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

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