216 lines
7.9 KiB
C++
216 lines
7.9 KiB
C++
#include <windows.h>
|
|
#include <math.h>
|
|
#include <string>
|
|
|
|
const int BMP_SIZE = 240, MY_TIMER = 987654;
|
|
|
|
class myBitmap {
|
|
public:
|
|
myBitmap() : pen( NULL ), brush( NULL ), clr( 0 ), wid( 1 ) {}
|
|
~myBitmap() {
|
|
DeleteObject( pen ); DeleteObject( brush );
|
|
DeleteDC( hdc ); DeleteObject( bmp );
|
|
}
|
|
bool create( int w, int h ) {
|
|
BITMAPINFO bi;
|
|
ZeroMemory( &bi, sizeof( bi ) );
|
|
bi.bmiHeader.biSize = sizeof( bi.bmiHeader );
|
|
bi.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
bi.bmiHeader.biPlanes = 1;
|
|
bi.bmiHeader.biWidth = w;
|
|
bi.bmiHeader.biHeight = -h;
|
|
|
|
HDC dc = GetDC( GetConsoleWindow() );
|
|
bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
|
|
if( !bmp ) return false;
|
|
|
|
hdc = CreateCompatibleDC( dc );
|
|
SelectObject( hdc, bmp );
|
|
ReleaseDC( GetConsoleWindow(), dc );
|
|
|
|
width = w; height = h;
|
|
return true;
|
|
}
|
|
void clear( BYTE clr = 0 ) {
|
|
memset( pBits, clr, width * height * sizeof( DWORD ) );
|
|
}
|
|
void setBrushColor( DWORD bClr ) {
|
|
if( brush ) DeleteObject( brush );
|
|
brush = CreateSolidBrush( bClr );
|
|
SelectObject( hdc, brush );
|
|
}
|
|
void setPenColor( DWORD c ) {
|
|
clr = c; createPen();
|
|
}
|
|
void setPenWidth( int w ) {
|
|
wid = w; createPen();
|
|
}
|
|
void saveBitmap( std::string path ) {
|
|
BITMAPFILEHEADER fileheader;
|
|
BITMAPINFO infoheader;
|
|
BITMAP bitmap;
|
|
DWORD wb;
|
|
|
|
GetObject( bmp, sizeof( bitmap ), &bitmap );
|
|
DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
|
|
|
|
ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
|
|
ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
|
|
ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );
|
|
|
|
infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
|
|
infoheader.bmiHeader.biCompression = BI_RGB;
|
|
infoheader.bmiHeader.biPlanes = 1;
|
|
infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
|
|
infoheader.bmiHeader.biHeight = bitmap.bmHeight;
|
|
infoheader.bmiHeader.biWidth = bitmap.bmWidth;
|
|
infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );
|
|
|
|
fileheader.bfType = 0x4D42;
|
|
fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
|
|
fileheader.bfSize = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;
|
|
|
|
GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );
|
|
|
|
HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
|
|
WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
|
|
WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
|
|
CloseHandle( file );
|
|
|
|
delete [] dwpBits;
|
|
}
|
|
HDC getDC() const { return hdc; }
|
|
DWORD* bits() { return ( DWORD* )pBits; }
|
|
private:
|
|
void createPen() {
|
|
if( pen ) DeleteObject( pen );
|
|
pen = CreatePen( PS_SOLID, wid, clr );
|
|
SelectObject( hdc, pen );
|
|
}
|
|
HBITMAP bmp; HDC hdc;
|
|
HPEN pen; HBRUSH brush;
|
|
void *pBits; int width, height, wid;
|
|
DWORD clr;
|
|
};
|
|
class plasma
|
|
{
|
|
public:
|
|
plasma() {
|
|
currentTime = 0; _WD = BMP_SIZE >> 1; _WV = BMP_SIZE << 1;
|
|
_bmp.create( BMP_SIZE, BMP_SIZE ); _bmp.clear();
|
|
plasma1 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
|
|
plasma2 = new BYTE[BMP_SIZE * BMP_SIZE * 4];
|
|
int i, j, dst = 0;
|
|
double temp;
|
|
for( j = 0; j < BMP_SIZE * 2; j++ ) {
|
|
for( i = 0; i < BMP_SIZE * 2; i++ ) {
|
|
plasma1[dst] = ( BYTE )( 128.0 + 127.0 * ( cos( ( double )hypot( BMP_SIZE - j, BMP_SIZE - i ) / 64.0 ) ) );
|
|
plasma2[dst] = ( BYTE )( ( sin( ( sqrt( 128.0 + ( BMP_SIZE - i ) * ( BMP_SIZE - i ) +
|
|
( BMP_SIZE - j ) * ( BMP_SIZE - j ) ) - 4.0 ) / 32.0 ) + 1 ) * 90.0 );
|
|
dst++;
|
|
}
|
|
}
|
|
}
|
|
void update() {
|
|
DWORD dst;
|
|
BYTE a, c1,c2, c3;
|
|
currentTime += ( double )( rand() % 2 + 1 );
|
|
|
|
int x1 = _WD + ( int )( ( _WD - 1 ) * sin( currentTime / 137 ) ),
|
|
x2 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime / 75 ) ),
|
|
x3 = _WD + ( int )( ( _WD - 1 ) * sin( -currentTime / 125 ) ),
|
|
y1 = _WD + ( int )( ( _WD - 1 ) * cos( currentTime / 123 ) ),
|
|
y2 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime / 85 ) ),
|
|
y3 = _WD + ( int )( ( _WD - 1 ) * cos( -currentTime / 108 ) );
|
|
|
|
int src1 = y1 * _WV + x1, src2 = y2 * _WV + x2, src3 = y3 * _WV + x3;
|
|
|
|
DWORD* bits = _bmp.bits();
|
|
for( int j = 0; j < BMP_SIZE; j++ ) {
|
|
dst = j * BMP_SIZE;
|
|
for( int i= 0; i < BMP_SIZE; i++ ) {
|
|
a = plasma2[src1] + plasma1[src2] + plasma2[src3];
|
|
c1 = a << 1; c2 = a << 2; c3 = a << 3;
|
|
bits[dst + i] = RGB( c1, c2, c3 );
|
|
src1++; src2++; src3++;
|
|
}
|
|
src1 += BMP_SIZE; src2 += BMP_SIZE; src3 += BMP_SIZE;
|
|
}
|
|
draw();
|
|
}
|
|
void setHWND( HWND hwnd ) { _hwnd = hwnd; }
|
|
private:
|
|
void draw() {
|
|
HDC dc = _bmp.getDC(), wdc = GetDC( _hwnd );
|
|
BitBlt( wdc, 0, 0, BMP_SIZE, BMP_SIZE, dc, 0, 0, SRCCOPY );
|
|
ReleaseDC( _hwnd, wdc );
|
|
}
|
|
myBitmap _bmp; HWND _hwnd; float _ang;
|
|
BYTE *plasma1, *plasma2;
|
|
double currentTime; int _WD, _WV;
|
|
};
|
|
class wnd
|
|
{
|
|
public:
|
|
wnd() { _inst = this; }
|
|
int wnd::Run( HINSTANCE hInst ) {
|
|
_hInst = hInst; _hwnd = InitAll();
|
|
SetTimer( _hwnd, MY_TIMER, 15, NULL );
|
|
_plasma.setHWND( _hwnd );
|
|
ShowWindow( _hwnd, SW_SHOW );
|
|
UpdateWindow( _hwnd );
|
|
MSG msg;
|
|
ZeroMemory( &msg, sizeof( msg ) );
|
|
while( msg.message != WM_QUIT ) {
|
|
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) != 0 ) {
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
}
|
|
return UnregisterClass( "_MY_PLASMA_", _hInst );
|
|
}
|
|
private:
|
|
void wnd::doPaint( HDC dc ) { _plasma.update(); }
|
|
void wnd::doTimer() { _plasma.update(); }
|
|
static int WINAPI wnd::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
|
|
switch( msg ) {
|
|
case WM_PAINT: {
|
|
PAINTSTRUCT ps;
|
|
_inst->doPaint( BeginPaint( hWnd, &ps ) );
|
|
EndPaint( hWnd, &ps );
|
|
return 0;
|
|
}
|
|
case WM_DESTROY: PostQuitMessage( 0 ); break;
|
|
case WM_TIMER: _inst->doTimer(); break;
|
|
default: return DefWindowProc( hWnd, msg, wParam, lParam );
|
|
}
|
|
return 0;
|
|
}
|
|
HWND InitAll() {
|
|
WNDCLASSEX wcex;
|
|
ZeroMemory( &wcex, sizeof( wcex ) );
|
|
wcex.cbSize = sizeof( WNDCLASSEX );
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
wcex.lpfnWndProc = ( WNDPROC )WndProc;
|
|
wcex.hInstance = _hInst;
|
|
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
|
|
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
|
|
wcex.lpszClassName = "_MY_PLASMA_";
|
|
|
|
RegisterClassEx( &wcex );
|
|
|
|
RECT rc = { 0, 0, BMP_SIZE, BMP_SIZE };
|
|
AdjustWindowRect( &rc, WS_SYSMENU | WS_CAPTION, FALSE );
|
|
int w = rc.right - rc.left, h = rc.bottom - rc.top;
|
|
return CreateWindow( "_MY_PLASMA_", ".: Plasma -- PJorente :.", WS_SYSMENU, CW_USEDEFAULT, 0, w, h, NULL, NULL, _hInst, NULL );
|
|
}
|
|
static wnd* _inst; HINSTANCE _hInst; HWND _hwnd; plasma _plasma;
|
|
};
|
|
wnd* wnd::_inst = 0;
|
|
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
|
|
wnd myWnd;
|
|
return myWnd.Run( hInstance );
|
|
}
|