home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / Source / GPCHAP09 / PROG9_4.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-25  |  10.4 KB  |  357 lines

  1. // PROG9_4.CPP - creates a palette and draws color bars
  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. #define MAX_COLORS    256              // maximum colors
  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.  
  49. // TYPES //////////////////////////////////////////////////
  50.  
  51. typedef unsigned short USHORT;
  52. typedef unsigned short WORD;
  53. typedef unsigned char  UCHAR;
  54. typedef unsigned char  BYTE;
  55.  
  56. // PROTOTYPES /////////////////////////////////////////////
  57.  
  58. int Game_Init(void *parms=NULL);
  59. int Game_Shutdown(void *parms=NULL);
  60. int Game_Main(void *parms=NULL);
  61. void Draw_Hline(int xs, int xe, int y, int color, UCHAR *vbuffer, int bytes_per_line);
  62.  
  63. // GLOBALS ////////////////////////////////////////////////
  64.  
  65. HWND main_window_handle = NULL; // save the window handle
  66. HINSTANCE main_instance = NULL; // save the instance
  67. char buffer[80];                // used to print text
  68.  
  69. LPDIRECTDRAW7        lpdd         = NULL;  // dd object
  70. LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;  // dd primary surface
  71. LPDIRECTDRAWSURFACE7 lpddsback    = NULL;  // dd back surface
  72. LPDIRECTDRAWPALETTE  lpddpal      = NULL;  // a pointer to the created dd palette
  73. DDSURFACEDESC2       ddsd;                 // a direct draw surface description struct
  74. DDSCAPS2             ddscaps;              // a direct draw surface capabilities struct
  75. HRESULT              ddrval;               // result back from dd calls
  76. PALETTEENTRY         palette[MAX_COLORS];  // the color palette
  77.  
  78. // FUNCTIONS //////////////////////////////////////////////
  79.  
  80. LRESULT CALLBACK WindowProc(HWND hwnd, 
  81.                             UINT msg, 
  82.                             WPARAM wparam, 
  83.                             LPARAM lparam)
  84. {
  85. // this is the main message handler of the system
  86. PAINTSTRUCT    ps;           // used in WM_PAINT
  87. HDC            hdc;       // handle to a device context
  88.  
  89. // what is the message 
  90. switch(msg)
  91.     {    
  92.     case WM_CREATE: 
  93.         {
  94.         // do initialization stuff here
  95.         return(0);
  96.         } break;
  97.  
  98.     case WM_PAINT:
  99.          {
  100.          // start painting
  101.          hdc = BeginPaint(hwnd,&ps);
  102.  
  103.          // end painting
  104.          EndPaint(hwnd,&ps);
  105.          return(0);
  106.         } break;
  107.  
  108.     case WM_DESTROY: 
  109.         {
  110.         // kill the application            
  111.         PostQuitMessage(0);
  112.         return(0);
  113.         } break;
  114.  
  115.     default:break;
  116.  
  117.     } // end switch
  118.  
  119. // process any messages that we didn't take care of 
  120. return (DefWindowProc(hwnd, msg, wparam, lparam));
  121.  
  122. } // end WinProc
  123.  
  124. // WINMAIN ////////////////////////////////////////////////
  125.  
  126. int WINAPI WinMain(    HINSTANCE hinstance,
  127.                     HINSTANCE hprevinstance,
  128.                     LPSTR lpcmdline,
  129.                     int ncmdshow)
  130. {
  131.  
  132. WNDCLASS winclass;    // this will hold the class we create
  133. HWND     hwnd;        // generic window handle
  134. MSG         msg;        // generic message
  135. HDC      hdc;       // generic dc
  136. PAINTSTRUCT ps;     // generic paintstruct
  137.  
  138. // first fill in the window class stucture
  139. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  140.                           CS_HREDRAW | CS_VREDRAW;
  141. winclass.lpfnWndProc    = WindowProc;
  142. winclass.cbClsExtra        = 0;
  143. winclass.cbWndExtra        = 0;
  144. winclass.hInstance        = hinstance;
  145. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  146. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  147. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  148. winclass.lpszMenuName    = NULL; 
  149. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  150.  
  151. // register the window class
  152. if (!RegisterClass(&winclass))
  153.     return(0);
  154.  
  155. // create the window, note the use of WS_POPUP
  156. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  157.                           "WinX Game Console",     // title
  158.                           WS_POPUP | WS_VISIBLE,
  159.                            0,0,       // x,y
  160.                           WINDOW_WIDTH,  // width
  161.                           WINDOW_HEIGHT, // height
  162.                           NULL,       // handle to parent 
  163.                           NULL,       // handle to menu
  164.                           hinstance,// instance
  165.                           NULL)))    // creation parms
  166. return(0);
  167.  
  168. // save the window handle and instance in a global
  169. main_window_handle = hwnd;
  170. main_instance      = hinstance;
  171.  
  172. // perform all game console specific initialization
  173. Game_Init();
  174.  
  175. // enter main event loop
  176. while(1)
  177.     {
  178.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  179.         { 
  180.         // test if this is a quit
  181.         if (msg.message == WM_QUIT)
  182.            break;
  183.     
  184.         // translate any accelerator keys
  185.         TranslateMessage(&msg);
  186.  
  187.         // send the message to the window proc
  188.         DispatchMessage(&msg);
  189.         } // end if
  190.     
  191.     // main game processing goes here
  192.     Game_Main();
  193.  
  194.     } // end while
  195.  
  196. // shutdown game and release all resources
  197. Game_Shutdown();
  198.  
  199. // return to Windows like this
  200. return(msg.wParam);
  201.  
  202. } // end WinMain
  203.  
  204. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  205.  
  206. int Game_Init(void *parms)
  207. {
  208. // this function is where you do all the initialization 
  209. // for your game
  210.  
  211. // create object and test for error
  212. if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
  213.    return(0);
  214.  
  215. // set cooperation level to windowed mode normal
  216. if (lpdd->SetCooperativeLevel(main_window_handle,
  217.            DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | 
  218.            DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
  219.     return(0);
  220.  
  221. // set the display mode
  222. if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)
  223.    return(0);
  224.  
  225. // Create the primary surface
  226. memset(&ddsd,0,sizeof(ddsd));
  227. ddsd.dwSize         = sizeof(ddsd);
  228. ddsd.dwFlags        = DDSD_CAPS;
  229. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  230.  
  231. if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
  232.    return(0);
  233.  
  234. // create palette data
  235. // first clear out all the entries, defensive programming
  236. memset(palette,0,256*sizeof(PALETTEENTRY));
  237.  
  238. // create a R,G,B,GR gradient palette
  239. for (int index=0; index<256; index++)
  240.     {
  241.     if (index < 64) // shades of red 
  242.         palette[index].peRed = index*4; 
  243.     else           // shades of green
  244.     if (index >=64 && index <128) 
  245.         palette[index].peGreen = (index-64)*4;
  246.     else           // shades of blue
  247.     if (index >=128 && index <192) 
  248.        palette[index].peBlue = (index-128)*4;
  249.     else           // shades of grey
  250.     if (index >=192 && index <256) 
  251.         palette[index].peRed = palette[index].peGreen = 
  252.         palette[index].peBlue = (index-192)*4;
  253.  
  254.     // set flags 
  255.     palette[index].peFlags = PC_NOCOLLAPSE;
  256.     } // end for index
  257.  
  258. // now create the palette object
  259. if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
  260.                          palette,&lpddpal,NULL)!=DD_OK)
  261.    return(0);
  262.  
  263. // attach the palette to the primary
  264. if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
  265.    return(0);
  266.  
  267. // return success
  268. return(1);
  269. } // end Game_Init
  270.  
  271. ///////////////////////////////////////////////////////////
  272.  
  273. int Game_Shutdown(void *parms)
  274. {
  275. // this function is where you shutdown your game and
  276. // release all resources that you allocated
  277.  
  278. // first release the palette
  279. if (lpddpal!=NULL)
  280.    lpddpal->Release();
  281.  
  282. // now release the primary surface
  283. if (lpddsprimary!=NULL)
  284.    lpddsprimary->Release();
  285.        
  286. // release the directdraw object
  287. if (lpdd!=NULL)
  288.    lpdd->Release();
  289.  
  290. // return success
  291. return(1);
  292. } // end Game_Shutdown
  293.  
  294. ///////////////////////////////////////////////////////////
  295.  
  296. int Game_Main(void *parms)
  297. {
  298. // this is the workhorse of your game it will be called
  299. // continuously in real-time this is like main() in C
  300. // all the calls for you game go here!
  301.     
  302. // this will be aliased to the video memory
  303. UCHAR *video_buffer = NULL; 
  304.                              
  305. // check of user is trying to exit
  306. if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
  307.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  308.                
  309. // set up the surface description to lock the surface
  310. memset(&ddsd,0,sizeof(ddsd)); 
  311. ddsd.dwSize = sizeof(ddsd);
  312.  
  313. // lock the primary surface, note in a real game you would
  314. // do this once per frame
  315. lpddsprimary->Lock(NULL,&ddsd, 
  316.              DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
  317.  
  318. // get video pointer, we could have just as easily used
  319. // ddsd.lpSurface, but I like to alias the ptr
  320. video_buffer = (UCHAR *)ddsd.lpSurface;
  321.  
  322. // draw a collection of horizontal lines each with a different color
  323. // using a function defined below
  324. for (int y=0; y<SCREEN_HEIGHT; y++)
  325.     Draw_Hline(0,SCREEN_WIDTH-1, // starting and ending x
  326.                y,                // y position
  327.                y % MAX_COLORS,     // color of line
  328.                video_buffer,     // destination memory 
  329.                ddsd.lPitch);     // bytes per line
  330.  
  331. // unlock the surface, very important!
  332. lpddsprimary->Unlock(NULL);
  333.  
  334. // return success
  335. return(1);
  336. } // end Game_Main
  337.  
  338. ///////////////////////////////////////////////////////////
  339.  
  340. void Draw_Hline(int xs, int xe, int y, int color, UCHAR *vbuffer, int bytes_per_line)
  341. {
  342. // this function draws a horizontal line, in a 256 color mode, notice
  343. // that it takes into consideration the memory pitch of the mode
  344.  
  345. // compute starting video address of video line
  346. UCHAR *video_addr = vbuffer + y*bytes_per_line;
  347.  
  348. // now were on the correct video line, so draw the line
  349. // draw the line a byte at a time
  350. for (int x=xs; x<=xe; x++)
  351.     video_addr[x] = (UCHAR)color;
  352.  
  353. // or you could do this
  354. // memset((void *)(video_addr+xs),(UCHAR)col,xe-xs+1);
  355.  
  356. } // end Draw_Hline
  357.