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

  1. // PROG10_2_16b.CPP - page flipping 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. // FUNCTIONS //////////////////////////////////////////////
  76.  
  77. LRESULT CALLBACK WindowProc(HWND hwnd, 
  78.                             UINT msg, 
  79.                             WPARAM wparam, 
  80.                             LPARAM lparam)
  81. {
  82. // this is the main message handler of the system
  83. PAINTSTRUCT    ps;           // used in WM_PAINT
  84. HDC            hdc;       // handle to a device context
  85.  
  86. // what is the message 
  87. switch(msg)
  88.     {    
  89.     case WM_CREATE: 
  90.         {
  91.         // do initialization stuff here
  92.         return(0);
  93.         } break;
  94.  
  95.     case WM_PAINT:
  96.          {
  97.          // start painting
  98.          hdc = BeginPaint(hwnd,&ps);
  99.  
  100.          // end painting
  101.          EndPaint(hwnd,&ps);
  102.          return(0);
  103.         } break;
  104.  
  105.     case WM_DESTROY: 
  106.         {
  107.         // kill the application            
  108.         PostQuitMessage(0);
  109.         return(0);
  110.         } break;
  111.  
  112.     default:break;
  113.  
  114.     } // end switch
  115.  
  116. // process any messages that we didn't take care of 
  117. return (DefWindowProc(hwnd, msg, wparam, lparam));
  118.  
  119. } // end WinProc
  120.  
  121. // WINMAIN ////////////////////////////////////////////////
  122.  
  123. int WINAPI WinMain(    HINSTANCE hinstance,
  124.                     HINSTANCE hprevinstance,
  125.                     LPSTR lpcmdline,
  126.                     int ncmdshow)
  127. {
  128.  
  129. WNDCLASS winclass;    // this will hold the class we create
  130. HWND     hwnd;        // generic window handle
  131. MSG         msg;        // generic message
  132. HDC      hdc;       // generic dc
  133. PAINTSTRUCT ps;     // generic paintstruct
  134.  
  135. // first fill in the window class stucture
  136. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  137.                           CS_HREDRAW | CS_VREDRAW;
  138. winclass.lpfnWndProc    = WindowProc;
  139. winclass.cbClsExtra        = 0;
  140. winclass.cbWndExtra        = 0;
  141. winclass.hInstance        = hinstance;
  142. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  143. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  144. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  145. winclass.lpszMenuName    = NULL; 
  146. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  147.  
  148. // register the window class
  149. if (!RegisterClass(&winclass))
  150.     return(0);
  151.  
  152. // create the window, note the use of WS_POPUP
  153. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  154.                           "WinX Game Console",     // title
  155.                           WS_POPUP | WS_VISIBLE,
  156.                            0,0,       // x,y
  157.                           WINDOW_WIDTH,  // width
  158.                           WINDOW_HEIGHT, // height
  159.                           NULL,       // handle to parent 
  160.                           NULL,       // handle to menu
  161.                           hinstance,// instance
  162.                           NULL)))    // creation parms
  163. return(0);
  164.  
  165. // save the window handle and instance in a global
  166. main_window_handle = hwnd;
  167. main_instance      = hinstance;
  168.  
  169. // perform all game console specific initialization
  170. Game_Init();
  171.  
  172. // enter main event loop
  173. while(1)
  174.     {
  175.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  176.         { 
  177.         // test if this is a quit
  178.         if (msg.message == WM_QUIT)
  179.            break;
  180.     
  181.         // translate any accelerator keys
  182.         TranslateMessage(&msg);
  183.  
  184.         // send the message to the window proc
  185.         DispatchMessage(&msg);
  186.         } // end if
  187.     
  188.     // main game processing goes here
  189.     Game_Main();
  190.  
  191.     } // end while
  192.  
  193. // shutdown game and release all resources
  194. Game_Shutdown();
  195.  
  196. // return to Windows like this
  197. return(msg.wParam);
  198.  
  199. } // end WinMain
  200.  
  201. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  202.  
  203. int Game_Init(void *parms)
  204. {
  205. // this function is where you do all the initialization 
  206. // for your game
  207.  
  208. // create object and test for error
  209. if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
  210.    return(0);
  211.  
  212. // set cooperation level to windowed mode normal
  213. if (lpdd->SetCooperativeLevel(main_window_handle,
  214.            DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | 
  215.            DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
  216.     return(0);
  217.  
  218. // set the display mode
  219. if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)
  220.    return(0);
  221.  
  222. // Create the primary surface
  223. memset(&ddsd,0,sizeof(ddsd));
  224. ddsd.dwSize = sizeof(ddsd);
  225.  
  226. // set the flags to validate both the capabilities 
  227. // field and the backbuffer count field
  228. ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  229.  
  230. // we need to let dd know that we want a complex 
  231. // flippable surface structure, set flags for that
  232. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
  233.                       DDSCAPS_COMPLEX;
  234.  
  235. // set the backbuffer count to 1
  236. ddsd.dwBackBufferCount = 1;
  237.  
  238. // create the primary surface
  239. lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
  240.  
  241. // query for the backbuffer or secondary surface
  242. // notice the use of ddscaps to indicate what 
  243. // we are requesting
  244. ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  245.  
  246. // get the surface
  247. lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);
  248.  
  249. // return success
  250. return(1);
  251.  
  252. } // end Game_Init
  253.  
  254. ///////////////////////////////////////////////////////////
  255.  
  256. int Game_Shutdown(void *parms)
  257. {
  258. // this function is where you shutdown your game and
  259. // release all resources that you allocated
  260.  
  261. // first release the secondary surface
  262. if (lpddsback!=NULL)
  263.    lpddsback->Release();
  264.        
  265. // now release the primary surface
  266. if (lpddsprimary!=NULL)
  267.    lpddsprimary->Release();
  268.        
  269. // release the directdraw object
  270. if (lpdd!=NULL)
  271.    lpdd->Release();
  272.  
  273. // return success
  274. return(1);
  275. } // end Game_Shutdown
  276.  
  277. ///////////////////////////////////////////////////////////
  278.  
  279. int Game_Main(void *parms)
  280. {
  281. // this is the workhorse of your game it will be called
  282. // continuously in real-time this is like main() in C
  283. // all the calls for you game go here!
  284.  
  285. USHORT *back_buffer = NULL, // used to draw
  286.        *dest_ptr    = NULL, // used in line by line copy
  287.        *src_ptr     = NULL; // " "
  288.  
  289. // check of user is trying to exit
  290. if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
  291.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  292.  
  293. // erase secondary back buffer
  294. memset(&ddsd,0,sizeof(ddsd)); 
  295. ddsd.dwSize = sizeof(ddsd);
  296.  
  297. // lock the secondary surface
  298. lpddsback->Lock(NULL,&ddsd, 
  299.               DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
  300.  
  301. // get video pointer to secondary surface
  302. back_buffer = (USHORT *)ddsd.lpSurface;     
  303.  
  304. // clear back buffer out, remember in 16bit mode there are
  305. // 2 bytes per pixel, so watch out for addressing and multiplying
  306. // issues in this code
  307.  
  308. // linear memory
  309. if (ddsd.lPitch == SCREEN_WIDTH*2)
  310.     memset(back_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT*(SCREEN_BPP/8));
  311. else
  312.    {
  313.    // non-linear memory
  314.    
  315.    // make copy of video pointer
  316.    dest_ptr = back_buffer;
  317.  
  318.    // clear out memory one line at a time
  319.    for (int y=0; y < SCREEN_HEIGHT; y++)
  320.        {
  321.        // clear next line
  322.        memset(dest_ptr,0,SCREEN_WIDTH*(SCREEN_BPP/8));
  323.        
  324.        // advance pointer to next line
  325.        dest_ptr+=(ddsd.lPitch/2);
  326.  
  327.        } // end for y
  328.  
  329.    } // end else
  330.  
  331. // perform game logic...
  332.        
  333. // draw the next frame into the secondary back buffer
  334. // plot 5000 random pixels
  335. for (int index = 0; index < 5000; index++)
  336.     {
  337.     int   x     = rand()%SCREEN_WIDTH;
  338.     int   y     = rand()%SCREEN_HEIGHT;
  339.  
  340.     UCHAR red   = rand()%256;
  341.     UCHAR green = rand()%256;
  342.     UCHAR blue  = rand()%256;
  343.     
  344.     // back_buffer is a short pointer, BUT lpitch is in bytes
  345.     // so divide by 2, to get number of "pixels" or words
  346.     back_buffer[x+y*(ddsd.lPitch/2)] = _RGB16BIT565(red, green, blue);
  347.     } // end for index
  348.  
  349. // unlock secondary buffer
  350. lpddsback->Unlock(NULL);
  351.  
  352. // flip pages
  353. while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);
  354.  
  355. // wait a sec
  356. Sleep(5);
  357.  
  358. // return success
  359. return(1);
  360.  
  361. } // end Game_Main
  362.  
  363. ///////////////////////////////////////////////////////////
  364.  
  365.