home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / Source / GPCHAP10 / Prog10_1_16b.cpp < prev    next >
C/C++ Source or Header  |  2002-04-27  |  10KB  |  354 lines

  1. // PROG10_1_16b.CPP - Double buffer demo
  2. // 16bit version
  3.  
  4. // INCLUDES ///////////////////////////////////////////////
  5. #define WIN32_LEAN_AND_MEAN  
  6. #define INITGUID
  7.  
  8. #include <windows.h>   // include important windows stuff
  9. #include <windowsx.h> 
  10. #include <mmsystem.h>
  11. #include <iostream.h> // include important C/C++ stuff
  12. #include <conio.h>
  13. #include <stdlib.h>
  14. #include <malloc.h>
  15. #include <memory.h>
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <stdio.h>
  19. #include <math.h>
  20. #include <io.h>
  21. #include <fcntl.h>
  22.  
  23. #include <ddraw.h>  // directX includes
  24.  
  25. // DEFINES ////////////////////////////////////////////////
  26.  
  27. // defines for windows 
  28. #define WINDOW_CLASS_NAME "WINXCLASS"  // class name
  29.  
  30. #define WINDOW_WIDTH  640              // size of window
  31. #define WINDOW_HEIGHT 480
  32. #define SCREEN_WIDTH  640              // size of screen
  33. #define SCREEN_HEIGHT 480
  34. #define SCREEN_BPP    16               // bits per pixel
  35.  
  36. // MACROS /////////////////////////////////////////////////
  37.  
  38. // these read the keyboard asynchronously
  39. #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
  40. #define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
  41.  
  42. // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
  43. #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
  44.  
  45. // this builds a 16 bit color value in 5.6.5 format (green dominate mode)
  46. #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
  47.  
  48. // TYPES //////////////////////////////////////////////////
  49.  
  50. typedef unsigned short USHORT;
  51. typedef unsigned short WORD;
  52. typedef unsigned char  UCHAR;
  53. typedef unsigned char  BYTE;
  54.  
  55. // PROTOTYPES /////////////////////////////////////////////
  56.  
  57. int Game_Init(void *parms=NULL);
  58. int Game_Shutdown(void *parms=NULL);
  59. int Game_Main(void *parms=NULL);
  60.  
  61. // GLOBALS ////////////////////////////////////////////////
  62.  
  63. HWND main_window_handle = NULL; // save the window handle
  64. HINSTANCE main_instance = NULL; // save the instance
  65. char buffer[80];                // used to print text
  66.  
  67. LPDIRECTDRAW7        lpdd         = NULL;  // dd object
  68. LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;  // dd primary surface
  69. LPDIRECTDRAWSURFACE7 lpddsback    = NULL;  // dd back surface
  70. LPDIRECTDRAWPALETTE  lpddpal      = NULL;  // a pointer to the created dd palette
  71. DDSURFACEDESC2       ddsd;                 // a direct draw surface description struct
  72. DDSCAPS2             ddscaps;              // a direct draw surface capabilities struct
  73. HRESULT              ddrval;               // result back from dd calls
  74.  
  75. USHORT               *double_buffer = NULL; // the double buffer              
  76.  
  77. // FUNCTIONS //////////////////////////////////////////////
  78.  
  79. LRESULT CALLBACK WindowProc(HWND hwnd, 
  80.                             UINT msg, 
  81.                             WPARAM wparam, 
  82.                             LPARAM lparam)
  83. {
  84. // this is the main message handler of the system
  85. PAINTSTRUCT    ps;           // used in WM_PAINT
  86. HDC            hdc;       // handle to a device context
  87.  
  88. // what is the message 
  89. switch(msg)
  90.     {    
  91.     case WM_CREATE: 
  92.         {
  93.         // do initialization stuff here
  94.         return(0);
  95.         } break;
  96.  
  97.     case WM_PAINT:
  98.          {
  99.          // start painting
  100.          hdc = BeginPaint(hwnd,&ps);
  101.  
  102.          // end painting
  103.          EndPaint(hwnd,&ps);
  104.          return(0);
  105.         } break;
  106.  
  107.     case WM_DESTROY: 
  108.         {
  109.         // kill the application            
  110.         PostQuitMessage(0);
  111.         return(0);
  112.         } break;
  113.  
  114.     default:break;
  115.  
  116.     } // end switch
  117.  
  118. // process any messages that we didn't take care of 
  119. return (DefWindowProc(hwnd, msg, wparam, lparam));
  120.  
  121. } // end WinProc
  122.  
  123. // WINMAIN ////////////////////////////////////////////////
  124.  
  125. int WINAPI WinMain(    HINSTANCE hinstance,
  126.                     HINSTANCE hprevinstance,
  127.                     LPSTR lpcmdline,
  128.                     int ncmdshow)
  129. {
  130.  
  131. WNDCLASS winclass;    // this will hold the class we create
  132. HWND     hwnd;        // generic window handle
  133. MSG         msg;        // generic message
  134. HDC      hdc;       // generic dc
  135. PAINTSTRUCT ps;     // generic paintstruct
  136.  
  137. // first fill in the window class stucture
  138. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  139.                           CS_HREDRAW | CS_VREDRAW;
  140. winclass.lpfnWndProc    = WindowProc;
  141. winclass.cbClsExtra        = 0;
  142. winclass.cbWndExtra        = 0;
  143. winclass.hInstance        = hinstance;
  144. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  145. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  146. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  147. winclass.lpszMenuName    = NULL; 
  148. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  149.  
  150. // register the window class
  151. if (!RegisterClass(&winclass))
  152.     return(0);
  153.  
  154. // create the window, note the use of WS_POPUP
  155. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  156.                           "WinX Game Console",     // title
  157.                           WS_POPUP | WS_VISIBLE,
  158.                            0,0,       // x,y
  159.                           WINDOW_WIDTH,  // width
  160.                           WINDOW_HEIGHT, // height
  161.                           NULL,       // handle to parent 
  162.                           NULL,       // handle to menu
  163.                           hinstance,// instance
  164.                           NULL)))    // creation parms
  165. return(0);
  166.  
  167. // save the window handle and instance in a global
  168. main_window_handle = hwnd;
  169. main_instance      = hinstance;
  170.  
  171. // perform all game console specific initialization
  172. Game_Init();
  173.  
  174. // enter main event loop
  175. while(1)
  176.     {
  177.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  178.         { 
  179.         // test if this is a quit
  180.         if (msg.message == WM_QUIT)
  181.            break;
  182.     
  183.         // translate any accelerator keys
  184.         TranslateMessage(&msg);
  185.  
  186.         // send the message to the window proc
  187.         DispatchMessage(&msg);
  188.         } // end if
  189.     
  190.     // main game processing goes here
  191.     Game_Main();
  192.  
  193.     } // end while
  194.  
  195. // shutdown game and release all resources
  196. Game_Shutdown();
  197.  
  198. // return to Windows like this
  199. return(msg.wParam);
  200.  
  201. } // end WinMain
  202.  
  203. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  204.  
  205. int Game_Init(void *parms)
  206. {
  207. // this function is where you do all the initialization 
  208. // for your game
  209.  
  210. // create object and test for error
  211. if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
  212.    return(0);
  213.  
  214. // set cooperation level to windowed mode normal
  215. if (lpdd->SetCooperativeLevel(main_window_handle,
  216.            DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | 
  217.            DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
  218.     return(0);
  219.  
  220. // set the display mode
  221. if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)
  222.    return(0);
  223.  
  224. // Create the primary surface
  225. memset(&ddsd,0,sizeof(ddsd));
  226. ddsd.dwSize         = sizeof(ddsd);
  227. ddsd.dwFlags        = DDSD_CAPS;
  228. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  229.  
  230. if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
  231.    return(0);
  232.  
  233. // allocate memory for the double buffer, notice the SCREEN_BPP/8
  234. // term to take into consideration 16-bit pixels
  235. if ((double_buffer = (USHORT *)malloc(SCREEN_WIDTH*SCREEN_HEIGHT*(SCREEN_BPP/8)))==NULL)
  236.    return(0);
  237.  
  238. // return success
  239. return(1);
  240.  
  241. } // end Game_Init
  242.  
  243. ///////////////////////////////////////////////////////////
  244.  
  245. int Game_Shutdown(void *parms)
  246. {
  247. // this function is where you shutdown your game and
  248. // release all resources that you allocated
  249.  
  250. // first release the primary surface
  251. if (lpddsprimary!=NULL)
  252.    lpddsprimary->Release();
  253.        
  254. // release the directdraw object
  255. if (lpdd!=NULL)
  256.    lpdd->Release();
  257.  
  258. // free double buffer
  259. if (double_buffer!=NULL)
  260.    free(double_buffer);
  261.  
  262. // return success
  263. return(1);
  264. } // end Game_Shutdown
  265.  
  266. ///////////////////////////////////////////////////////////
  267.  
  268. int Game_Main(void *parms)
  269. {
  270. // this is the workhorse of your game it will be called
  271. // continuously in real-time this is like main() in C
  272. // all the calls for you game go here!
  273.  
  274. USHORT *primary_buffer = NULL, // used to draw
  275.        *dest_ptr       = NULL, // used in line by line copy
  276.        *src_ptr        = NULL; // " "
  277.  
  278. // check of user is trying to exit
  279. if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
  280.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  281.  
  282. // erase double buffer
  283. memset(double_buffer,0, SCREEN_WIDTH*SCREEN_HEIGHT*(SCREEN_BPP/8));
  284.  
  285. // perform game logic...
  286.        
  287. // draw the next frame into the double buffer
  288. // plot 5000 random pixels
  289. for (int index=0; index < 5000; index++)
  290.     {
  291.     int   x   = rand()%SCREEN_WIDTH;
  292.     int   y   = rand()%SCREEN_HEIGHT;
  293.     UCHAR red   = rand()%256;
  294.     UCHAR green = rand()%256;
  295.     UCHAR blue  = rand()%256;
  296.  
  297.     double_buffer[x+y*SCREEN_WIDTH] = _RGB16BIT565(red, green, blue);
  298.     } // end for index
  299.  
  300. // copy the double buffer into the primary buffer
  301. memset(&ddsd,0,sizeof(ddsd)); 
  302. ddsd.dwSize = sizeof(ddsd);
  303.  
  304. // lock the primary surface
  305. lpddsprimary->Lock(NULL,&ddsd, 
  306.               DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
  307.  
  308. // get video pointer to primary surfce
  309. primary_buffer = (USHORT *)ddsd.lpSurface;       
  310.  
  311. // test if memory is linear
  312. if (ddsd.lPitch == SCREEN_WIDTH*(SCREEN_BPP/8))
  313.    {
  314.    // copy memory from double buffer to primary buffer
  315.    memcpy(primary_buffer, double_buffer, SCREEN_WIDTH*SCREEN_HEIGHT*(SCREEN_BPP/8));
  316.    } // end if
  317. else
  318.    { // non-linear
  319.    // make copy of source and destination addresses
  320.    dest_ptr = primary_buffer;
  321.    src_ptr = double_buffer;
  322.  
  323.    // memory is non-linear, copy line by line
  324.    for (int y=0; y<SCREEN_HEIGHT; y++)
  325.        {
  326.        // copy line
  327.        memcpy(dest_ptr, src_ptr, SCREEN_WIDTH*(SCREEN_BPP/8));
  328.  
  329.        // advance pointers to next line
  330.        // notice division by 2 since lpitch is in bytes and
  331.        // these pointers are USHORT pointers
  332.        // but the screen_width is ok to use on src_ptr
  333.        // since the pointer arithematic will advance the pointer
  334.        // properly
  335.        dest_ptr+=(ddsd.lPitch/2);
  336.        src_ptr+=SCREEN_WIDTH;
  337.  
  338.        } // end for
  339.  
  340.    } // end else
  341.  
  342. // unlock primary buffer
  343. lpddsprimary->Unlock(NULL);
  344.  
  345. // wait a sec
  346. Sleep(5);
  347.  
  348. // return success
  349. return(1);
  350. } // end Game_Main
  351.  
  352. ///////////////////////////////////////////////////////////
  353.  
  354.