/* a mandelbrot program adapted from prog5.4 in LaMothe's Windows game programming for dummies */ // the basic includes #define WIN32_LEAN_AND_MEAN #include #include #include // for sprintf() // #include // #include // these are the size of the plotted region #define IMAGE_WIDTH 640 #define IMAGE_HEIGHT 400 int displayed=0; // flag when picture done /* displayed = 0 until picture drawn */ int iy=0; // current line; update one line at a time // initial x and y ranges double xmin=-2.1; double xmax=.8; double ymin=-1.2; double ymax=1.2; double dx, dy; // size of pixels const int MAXITER=64; // maximum mandelbrot iterations // give a little border around the image #define BORDER 10 // the 8 allows for the windows border too #define WINDOW_WIDTH (IMAGE_WIDTH+2*BORDER+8) #define WINDOW_HEIGHT (IMAGE_HEIGHT+2*BORDER+96) char stringbuffer[256]; // the next stuff is mosty copied from the dummies book #define WINDOW_CLASS_NAME "WINCLASS1" // global variables HWND main_window_handle = NULL; // the window handle // FUNCTIONS ////////////////////////////////////////////// // this is called when windows has an event, such as a mouse press LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main system message handler PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to a device context // what is the message switch(msg) { case WM_CREATE: { // do initialization stuff here dy=(ymax-ymin)/IMAGE_HEIGHT; dx=(xmax-xmin)/IMAGE_WIDTH; return(0); } break; case WM_PAINT: { // the window is ready to be drawn or was exposed displayed=0; // to start the drawing again iy=0; hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); return(0); } break; case WM_DESTROY: { // kill the application PostQuitMessage(0); return(0); } break; case WM_LBUTTONDOWN: { // double scale on left button press int mx= (int) LOWORD(lparam); int my= (int) HIWORD(lparam); double mid = xmin+dx*mx; xmin = mid -(xmax-xmin)/4; xmax = 2*mid - xmin; mid = ymin+dy*my; ymin= mid-(ymax-ymin)/4; ymax = 2*mid - ymin; dy=(ymax-ymin)/IMAGE_HEIGHT; dx=(xmax-xmin)/IMAGE_WIDTH; iy=0; displayed=0; } break; case WM_RBUTTONDOWN: { // zoom out on right button int mx= (int) LOWORD(lparam); int my= (int) HIWORD(lparam); double mid = xmin+dx*mx; xmin = mid -(xmax-xmin); xmax = 2*mid - xmin; mid = ymin+dy*my; ymin= mid-(ymax-ymin); ymax = 2*mid - ymin; dy=(ymax-ymin)/IMAGE_HEIGHT; dx=(xmax-xmin)/IMAGE_WIDTH; iy=0; displayed=0; } break; case WM_KEYDOWN: {// quit if escape or Q key pressed int code = (int) wparam; switch (code) {case VK_ESCAPE: case VK_Q: PostQuitMessage(0); return(0); default: break; } } default: break; } // end switch // process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // WINMAIN //////////////////////////////////////////////// int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASS winclass; // this will hold the class we create HWND hwnd; // generic window handle MSG msg; // generic message HDC hdc; // generic dc // PAINTSTRUCT ps; // generic paintstruct // first fill in the window class stucture winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; // register the window class if (!RegisterClass(&winclass)) return(0); // create the window if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class "Mikey's mandel", // title WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0,0, // x,y WINDOW_WIDTH, // width WINDOW_HEIGHT, // height NULL, // handle to parent NULL, // handle to menu hinstance,// instance NULL))) // creation parms return(0); // save the window handle in a global main_window_handle = hwnd; // make a table of colors // RGB(red,green,blue), each intensity runs from 0 to 255 #define NCOLORS 8 COLORREF mycolors[NCOLORS]; HPEN mypen[NCOLORS],mybrush[NCOLORS]; mycolors[0]=RGB(0,0,0); mycolors[1]=RGB(0,0,255); mycolors[2]=RGB(0,255,0); mycolors[3]=RGB(0,255,255); mycolors[4]=RGB(255,0,0); mycolors[5]=RGB(255,0,255); mycolors[6]=RGB(255,255,0); mycolors[7]=RGB(255,255,255); int i; for (i=0; i=8.) break; } if (k==MAXITER) k=0; // black center colors[ix]=k%NCOLORS; // SetPixel(hdc, ix, iy, mycolors[k%NCOLORS]); } /* now display the row */ /* I draw line segments instead of individual pixels with the hope that it is somewhat faster */ MoveToEx(hdc,BORDER,BORDER+iy,NULL); // move pen to start of row int currentcolor=colors[0]; SelectObject(hdc,mypen[currentcolor]); for (ix=0; ix=IMAGE_HEIGHT){ // we are done drawing displayed=1; iy=0; } } } // end while // release the device context and the pens ReleaseDC(hwnd,hdc); for (i=0; i