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

  1. // PROG11_6.CPP - a demo of mixing GDI and bobs
  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. #define BITMAP_ID     0x4D42      // universal id for a bitmap
  36.  
  37. // defines for BOBs
  38. #define BOB_STATE_DEAD     0      // this is a dead bob
  39. #define BOB_STATE_ALIVE    1      // this is a live bob
  40. #define BOB_STATE_LOADED   2      // the bob has been loaded
  41.  
  42. // MACROS /////////////////////////////////////////////////
  43.  
  44. // these read the keyboard asynchronously
  45. #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
  46. #define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
  47.  
  48. // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
  49. #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
  50.  
  51. // this builds a 16 bit color value in 5.6.5 format (green dominate mode)
  52. #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
  53.  
  54. // TYPES //////////////////////////////////////////////////
  55.  
  56. typedef unsigned short USHORT;
  57. typedef unsigned short WORD;
  58. typedef unsigned char  UCHAR;
  59. typedef unsigned char  BYTE;
  60.  
  61. // container structure for bitmaps .BMP file
  62. typedef struct BITMAP_FILE_TAG
  63.         {
  64.         BITMAPFILEHEADER bitmapfileheader;  // this contains the bitmapfile header
  65.         BITMAPINFOHEADER bitmapinfoheader;  // this is all the info including the palette
  66.         PALETTEENTRY     palette[256];      // we will store the palette here
  67.         UCHAR            *buffer;           // this is a pointer to the data
  68.  
  69.         } BITMAP_FILE, *BITMAP_FILE_PTR;
  70.  
  71. // the blitter object structure BOB
  72. typedef struct BITMAP_OBJ_TYP
  73.         {
  74.         int state; // the state of the object (general)
  75.         int attr;  // attributes pertaining to the object (general)
  76.         int x,y;   // position bitmap will be displayed at
  77.         int xv,yv; // velocity of object
  78.         int width, height; // the width and height of the bitmap
  79.         LPDIRECTDRAWSURFACE7 image; // the bitmap surface itself
  80.  
  81.         } BITMAP_OBJ, *BITMAP_OBJ_PTR;
  82.  
  83. // PROTOTYPES /////////////////////////////////////////////
  84.  
  85. // game console
  86. int Game_Init(void *parms=NULL);
  87. int Game_Shutdown(void *parms=NULL);
  88. int Game_Main(void *parms=NULL);
  89.  
  90. // bitmaps
  91. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);
  92. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
  93. int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);
  94.  
  95. // bobs
  96. int Draw_BOB(BITMAP_OBJ_PTR bob,LPDIRECTDRAWSURFACE7 dest);
  97. int Destroy_BOB(BITMAP_OBJ_PTR bob);
  98. int Create_BOB(BITMAP_OBJ_PTR bob,int width, int height,int attr, int flags);
  99. int Load_BOB(BITMAP_OBJ_PTR bob,BITMAP_FILE_PTR bitmap,int cx,int cy,int mode); 
  100.  
  101. // GLOBALS ////////////////////////////////////////////////
  102.  
  103. HWND main_window_handle = NULL; // save the window handle
  104. HINSTANCE main_instance = NULL; // save the instance
  105. char buffer[80];                // used to print text
  106.  
  107. LPDIRECTDRAW7        lpdd         = NULL;  // dd object
  108. LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;  // dd primary surface
  109. LPDIRECTDRAWSURFACE7 lpddsback    = NULL;  // dd back surface
  110. LPDIRECTDRAWPALETTE  lpddpal      = NULL;  // a pointer to the created dd palette
  111. PALETTEENTRY         palette[256];         // color palette
  112. DDSURFACEDESC2       ddsd;                 // a direct draw surface description struct
  113. DDBLTFX              ddbltfx;              // used to fill
  114. DDSCAPS2             ddscaps;              // a direct draw surface capabilities struct
  115. HRESULT              ddrval;               // result back from dd calls
  116. UCHAR                *primary_buffer = NULL; // primary video buffer
  117. UCHAR                *back_buffer    = NULL; // secondary back buffer
  118. BITMAP_FILE          bitmap16bit,            // a 16 bit bitmap file
  119.                      bitmap8bit;             // a 8 bit bitmap file
  120.  
  121. BITMAP_OBJ           creature;               // the creature
  122.  
  123. // FUNCTIONS //////////////////////////////////////////////
  124.  
  125. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
  126. {
  127. // this function opens a bitmap file and loads the data into bitmap
  128.  
  129. int file_handle,  // the file handle
  130.     index;        // looping index
  131.  
  132. UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
  133. OFSTRUCT file_data;        // the file data information
  134.  
  135. // open the file if it exists
  136. if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
  137.    return(0);
  138.  
  139. // now load the bitmap file header
  140. _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
  141.  
  142. // test if this is a bitmap file
  143. if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
  144.    {
  145.    // close the file
  146.    _lclose(file_handle);
  147.  
  148.    // return error
  149.    return(0);
  150.    } // end if
  151.  
  152. // now we know this is a bitmap, so read in all the sections
  153.  
  154. // first the bitmap infoheader
  155.  
  156. // now load the bitmap file header
  157. _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
  158.  
  159. // now load the color palette if there is one
  160. if (bitmap->bitmapinfoheader.biBitCount == 8)
  161.    {
  162.    _lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY));
  163.  
  164.    // now set all the flags in the palette correctly and fix the reversed 
  165.    // BGR RGBQUAD data format
  166.    for (index=0; index < 256; index++)
  167.        {
  168.        // reverse the red and green fields
  169.        int temp_color = bitmap->palette[index].peRed;
  170.        bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;
  171.        bitmap->palette[index].peBlue = temp_color;
  172.        
  173.        // always set the flags word to this
  174.        bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
  175.        } // end for index
  176.  
  177.     } // end if
  178.  
  179. // finally the image data itself
  180. _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
  181.  
  182. // now read in the image, if the image is 8 or 16 bit then simply read it
  183. // but if its 24 bit then read it into a temporary area and then convert
  184. // it to a 16 bit image
  185.  
  186. if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
  187.    {
  188.    // allocate the memory for the image
  189.    if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  190.       {
  191.       // close the file
  192.       _lclose(file_handle);
  193.  
  194.       // return error
  195.       return(0);
  196.       } // end if
  197.  
  198.    // now read it in
  199.    _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
  200.  
  201.    } // end if
  202. else
  203.    {
  204.    // this must be a 24 bit image, load it in and convert it to 16 bit
  205. //   printf("\nconverting 24 bit image...");
  206.  
  207.    // allocate temporary buffer
  208.    if (!(temp_buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  209.       {
  210.       // close the file
  211.       _lclose(file_handle);
  212.  
  213.       // return error
  214.       return(0);
  215.       } // end if
  216.    
  217.    // allocate final 16 bit storage buffer
  218.    if (!(bitmap->buffer=(UCHAR *)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight)))
  219.       {
  220.       // close the file
  221.       _lclose(file_handle);
  222.  
  223.       // release working buffer
  224.       free(temp_buffer);
  225.  
  226.       // return error
  227.       return(0);
  228.       } // end if
  229.  
  230.    // now read it in
  231.    _lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
  232.  
  233.    // now convert each 24 bit RGB value into a 16 bit value
  234.    for (index=0; index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
  235.        {
  236.        // extract RGB components (note they are in memory BGR)
  237.        // also, assume 5.6.5 format, so scale appropriately
  238.        UCHAR red    = (temp_buffer[index*3 + 2] >> 3), // 5 bits
  239.              green  = (temp_buffer[index*3 + 1] >> 2), // 6 bits, change to 3 for 5 bits
  240.              blue   = (temp_buffer[index*3 + 0] >> 3); // 5 bits
  241.  
  242.        // build up 16 bit color word assume 5.6.5 format
  243.        USHORT color = _RGB16BIT565(red,green,blue);
  244.  
  245.        // write color to buffer
  246.        ((USHORT *)bitmap->buffer)[index] = color;
  247.  
  248.        } // end for index
  249.  
  250.    // finally write out the correct number of bits
  251.    bitmap->bitmapinfoheader.biBitCount=16;
  252.  
  253.    } // end if
  254.  
  255. #if 0
  256. // write the file info out 
  257. printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
  258.         filename,
  259.         bitmap->bitmapinfoheader.biSizeImage,
  260.         bitmap->bitmapinfoheader.biWidth,
  261.         bitmap->bitmapinfoheader.biHeight,
  262.         bitmap->bitmapinfoheader.biBitCount,
  263.         bitmap->bitmapinfoheader.biClrUsed,
  264.         bitmap->bitmapinfoheader.biClrImportant);
  265. #endif
  266.  
  267. // close the file
  268. _lclose(file_handle);
  269.  
  270. // flip the bitmap
  271. Flip_Bitmap(bitmap->buffer, 
  272.             bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8), 
  273.             bitmap->bitmapinfoheader.biHeight);
  274.  
  275. // return success
  276. return(1);
  277.  
  278. } // end Load_Bitmap_File
  279.  
  280. ///////////////////////////////////////////////////////////
  281.  
  282. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
  283. {
  284. // this function releases all memory associated with "bitmap"
  285. if (bitmap->buffer)
  286.    {
  287.    // release memory
  288.    free(bitmap->buffer);
  289.  
  290.    // reset pointer
  291.    bitmap->buffer = NULL;
  292.  
  293.    } // end if
  294.  
  295. // return success
  296. return(1);
  297.  
  298. } // end Unload_Bitmap_File
  299.  
  300. ///////////////////////////////////////////////////////////
  301.  
  302. int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
  303. {
  304. // this function is used to flip upside down .BMP images
  305.  
  306. UCHAR *buffer; // used to perform the image processing
  307. int index;     // looping index
  308.  
  309. // allocate the temporary buffer
  310. if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
  311.    return(0);
  312.  
  313. // copy image to work area
  314. memcpy(buffer,image,bytes_per_line*height);
  315.  
  316. // flip vertically
  317. for (index=0; index < height; index++)
  318.     memcpy(&image[((height-1) - index)*bytes_per_line],
  319.            &buffer[index*bytes_per_line], bytes_per_line);
  320.  
  321. // release the memory
  322. free(buffer);
  323.  
  324. // return success
  325. return(1);
  326.  
  327. } // end Flip_Bitmap
  328.  
  329. ///////////////////////////////////////////////////////////
  330.  
  331. int Create_BOB(BITMAP_OBJ_PTR bob,    // the bob to create
  332.                int width, int height, // size of bob
  333.                int attr,              // attrs
  334.                int flags = 0)         // memory flag
  335. {
  336. // Create the BOB object, note that all BOBs 
  337. // are created as offscreen surfaces in VRAM as the
  338. // default, if you want to use system memory then
  339. // set flags equal to DDSCAPS_SYSTEMMEMORY
  340.  
  341. DDSURFACEDESC2 ddsd; // used to create surface
  342.  
  343. // set state and attributes of BOB
  344. bob->state = BOB_STATE_ALIVE;
  345. bob->attr  = attr;
  346. bob->image = NULL;
  347.  
  348. // set position and velocity to 0
  349. bob->x = bob->y = bob->xv = bob->yv = 0;
  350.  
  351. // set to access caps, width, and height
  352. memset(&ddsd,0,sizeof(ddsd));
  353. ddsd.dwSize  = sizeof(ddsd);
  354. ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  355.  
  356. // set dimensions of the new bitmap surface
  357. ddsd.dwWidth  = bob->width = width;
  358. ddsd.dwHeight = bob->height = height;
  359.  
  360. // set surface to offscreen plain
  361. ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | flags;
  362.  
  363. // create the surface
  364. if (lpdd->CreateSurface(&ddsd,&(bob->image),NULL)!=DD_OK)
  365.    return(0);
  366.  
  367. // set color key to color 0
  368. DDCOLORKEY color_key; // used to set color key
  369. color_key.dwColorSpaceLowValue  = 0;
  370. color_key.dwColorSpaceHighValue = 0;
  371.  
  372. // now set the color key for source blitting
  373. (bob->image)->SetColorKey(DDCKEY_SRCBLT, &color_key);
  374.  
  375. // return success
  376. return(1);
  377.  
  378. } // end Create_BOB
  379.  
  380. ///////////////////////////////////////////////////////////
  381.  
  382. int Destroy_BOB(BITMAP_OBJ_PTR bob)
  383. {
  384. // destroy the BOB, simply release the surface
  385.  
  386. if (bob->image)
  387.    (bob->image)->Release();
  388. else
  389.    return(0);
  390.  
  391. // return success
  392. return(1);
  393.  
  394. } // end Destroy_BOB
  395.  
  396. ///////////////////////////////////////////////////////////
  397.  
  398. int Draw_BOB(BITMAP_OBJ_PTR bob,       // bob to draw
  399.              LPDIRECTDRAWSURFACE7 dest) // surface to draw the bob on
  400. {
  401. // draw a bob at the x,y defined in the BOB
  402. // on the destination surface defined in dest
  403.  
  404. RECT dest_rect,   // the destination rectangle
  405.      source_rect; // the source rectangle                             
  406.  
  407. // fill in the destination rect
  408. dest_rect.left   = bob->x;
  409. dest_rect.top    = bob->y;
  410. dest_rect.right  = bob->x+bob->width;
  411. dest_rect.bottom = bob->y+bob->height;
  412.  
  413. // fill in the source rect
  414. source_rect.left    = 0;
  415. source_rect.top     = 0;
  416. source_rect.right   = bob->width;
  417. source_rect.bottom  = bob->height;
  418.  
  419. // blt to destination surface
  420. dest->Blt(&dest_rect, bob->image,
  421.           &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
  422.           NULL);
  423.  
  424. // return success
  425. return(1);
  426. } // end Draw_BOB
  427.  
  428. ///////////////////////////////////////////////////////////
  429.  
  430. int Load_BOB(BITMAP_OBJ_PTR bob, // bob to load with data
  431.              BITMAP_FILE_PTR bitmap, // bitmap to scan image data from
  432.              int cx,int cy,   // cell or absolute pos. to scan image from
  433.              int mode)    // if 0 then cx,cy is cell position, else 
  434.                           // cx,cy are absolute coords
  435. {
  436. // this function extracts a bitmap out of a bitmap file
  437.  
  438. UCHAR *source_ptr,   // working pointers
  439.       *dest_ptr;
  440.  
  441. DDSURFACEDESC2 ddsd;  //  direct draw surface description 
  442.  
  443. // test the mode of extraction, cell based or absolute
  444. if (mode==0)
  445.    {
  446.    // re-compute x,y
  447.    cx = cx*(bob->width+1) + 1;
  448.    cy = cy*(bob->height+1) + 1;
  449.    } // end if
  450.  
  451. // extract bitmap data
  452. source_ptr = bitmap->buffer +
  453.       cy*bitmap->bitmapinfoheader.biWidth+cx;
  454.  
  455. // get the addr to destination surface memory
  456.  
  457. // set size of the structure
  458. ddsd.dwSize = sizeof(ddsd);
  459.  
  460. // lock the display surface
  461. (bob->image)->Lock(NULL,
  462.                    &ddsd,
  463.                    DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
  464.                    NULL);
  465.  
  466. // assign a pointer to the memory surface for manipulation
  467. dest_ptr = (UCHAR *)ddsd.lpSurface;
  468.  
  469. // iterate thru each scanline and copy bitmap
  470. for (int index_y=0; index_y<bob->height; index_y++)
  471.     {
  472.     // copy next line of data to destination
  473.     memcpy(dest_ptr, source_ptr,bob->width);
  474.  
  475.     // advance pointers
  476.     dest_ptr   += (ddsd.lPitch);
  477.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  478.     } // end for index_y
  479.  
  480. // unlock the surface 
  481. (bob->image)->Unlock(NULL);
  482.  
  483. // set state to loaded
  484. bob->state |= BOB_STATE_LOADED;
  485.  
  486. // return success
  487. return(1);
  488.  
  489. } // end Load_BOB
  490.  
  491. ///////////////////////////////////////////////////////////
  492.  
  493. LRESULT CALLBACK WindowProc(HWND hwnd, 
  494.                             UINT msg, 
  495.                             WPARAM wparam, 
  496.                             LPARAM lparam)
  497. {
  498. // this is the main message handler of the system
  499. PAINTSTRUCT    ps;           // used in WM_PAINT
  500. HDC            hdc;       // handle to a device context
  501.  
  502. // what is the message 
  503. switch(msg)
  504.     {    
  505.     case WM_CREATE: 
  506.         {
  507.         // do initialization stuff here
  508.         return(0);
  509.         } break;
  510.  
  511.     case WM_PAINT:
  512.          {
  513.          // start painting
  514.          hdc = BeginPaint(hwnd,&ps);
  515.  
  516.          // end painting
  517.          EndPaint(hwnd,&ps);
  518.          return(0);
  519.         } break;
  520.  
  521.     case WM_DESTROY: 
  522.         {
  523.         // kill the application            
  524.         PostQuitMessage(0);
  525.         return(0);
  526.         } break;
  527.  
  528.     default:break;
  529.  
  530.     } // end switch
  531.  
  532. // process any messages that we didn't take care of 
  533. return (DefWindowProc(hwnd, msg, wparam, lparam));
  534.  
  535. } // end WinProc
  536.  
  537. // WINMAIN ////////////////////////////////////////////////
  538.  
  539. int WINAPI WinMain(    HINSTANCE hinstance,
  540.                     HINSTANCE hprevinstance,
  541.                     LPSTR lpcmdline,
  542.                     int ncmdshow)
  543. {
  544.  
  545. WNDCLASS winclass;    // this will hold the class we create
  546. HWND     hwnd;        // generic window handle
  547. MSG         msg;        // generic message
  548. HDC      hdc;       // generic dc
  549. PAINTSTRUCT ps;     // generic paintstruct
  550.  
  551. // first fill in the window class stucture
  552. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  553.                           CS_HREDRAW | CS_VREDRAW;
  554. winclass.lpfnWndProc    = WindowProc;
  555. winclass.cbClsExtra        = 0;
  556. winclass.cbWndExtra        = 0;
  557. winclass.hInstance        = hinstance;
  558. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  559. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  560. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  561. winclass.lpszMenuName    = NULL; 
  562. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  563.  
  564. // register the window class
  565. if (!RegisterClass(&winclass))
  566.     return(0);
  567.  
  568. // create the window, note the use of WS_POPUP
  569. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  570.                           "WinX Game Console",     // title
  571.                           WS_POPUP | WS_VISIBLE,
  572.                            0,0,       // x,y
  573.                           WINDOW_WIDTH,  // width
  574.                           WINDOW_HEIGHT, // height
  575.                           NULL,       // handle to parent 
  576.                           NULL,       // handle to menu
  577.                           hinstance,// instance
  578.                           NULL)))    // creation parms
  579. return(0);
  580.  
  581. // hide the mouse
  582. ShowCursor(FALSE);
  583.  
  584. // save the window handle and instance in a global
  585. main_window_handle = hwnd;
  586. main_instance      = hinstance;
  587.  
  588. // perform all game console specific initialization
  589. Game_Init();
  590.  
  591. // enter main event loop
  592. while(1)
  593.     {
  594.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  595.         { 
  596.         // test if this is a quit
  597.         if (msg.message == WM_QUIT)
  598.            break;
  599.     
  600.         // translate any accelerator keys
  601.         TranslateMessage(&msg);
  602.  
  603.         // send the message to the window proc
  604.         DispatchMessage(&msg);
  605.         } // end if
  606.     
  607.     // main game processing goes here
  608.     Game_Main();
  609.  
  610.     } // end while
  611.  
  612. // shutdown game and release all resources
  613. Game_Shutdown();
  614.  
  615. // return to Windows like this
  616. return(msg.wParam);
  617.  
  618. } // end WinMain
  619.  
  620. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  621.  
  622. int Game_Init(void *parms)
  623. {
  624. // this function is where you do all the initialization 
  625. // for your game
  626.  
  627. int index; // looping var
  628.  
  629. // create object and test for error
  630. if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
  631.    return(0);
  632.  
  633. // set cooperation level to windowed mode normal
  634. if (lpdd->SetCooperativeLevel(main_window_handle,
  635.            DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | 
  636.            DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
  637.     return(0);
  638.  
  639. // set the display mode
  640. if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)
  641.    return(0);
  642.  
  643. // Create the primary surface
  644. memset(&ddsd,0,sizeof(ddsd));
  645. ddsd.dwSize = sizeof(ddsd);
  646. ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  647.  
  648. // we need to let dd know that we want a complex 
  649. // flippable surface structure, set flags for that
  650. ddsd.ddsCaps.dwCaps = 
  651.   DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  652.  
  653. // set the backbuffer count to 1
  654. ddsd.dwBackBufferCount = 1;
  655.  
  656. // create the primary surface
  657. lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
  658.  
  659. // query for the backbuffer i.e the secondary surface
  660. ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  661. lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);
  662.  
  663. // create and attach palette
  664.  
  665. // create palette data
  666. // first clear out all the entries, defensive programming
  667. memset(palette,0,256*sizeof(PALETTEENTRY));
  668.  
  669. // create a R,G,B,GR gradient palette
  670. for (index=0; index<256; index++)
  671.     {
  672.     palette[index].peRed = rand()%256;
  673.     palette[index].peGreen = rand()%256;
  674.     palette[index].peBlue = rand()%256;
  675.     // set flags
  676.     palette[index].peFlags = PC_NOCOLLAPSE;
  677.     } // end for index
  678.  
  679.     palette[0].peRed = 0;
  680.     palette[0].peGreen = 0;
  681.     palette[0].peBlue =0;
  682.  
  683. // now create the palette object
  684. if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
  685.                          palette,&lpddpal,NULL)!=DD_OK)
  686.    return(0);
  687.  
  688. // attach the palette to the primary
  689. if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
  690.    return(0);
  691.  
  692. // now load the 8 bit color bitmap
  693. Load_Bitmap_File(&bitmap8bit, "MONSTR8.BMP");
  694.  
  695. // now load the palette into the directdraw
  696. lpddpal->SetEntries(0,0,256,bitmap8bit.palette);
  697.  
  698. // create creature BOB
  699. Create_BOB(&creature,96,64,0,DDSCAPS_SYSTEMMEMORY);
  700.     
  701. // extract bitmap image for BOB, note that this time
  702. // the entire bitmap is the bob
  703. Load_BOB(&creature,&bitmap8bit,0,0,1);  
  704.  
  705. // set position and velocity
  706. creature.x = 0;
  707. creature.y = SCREEN_HEIGHT/2;
  708. creature.xv = 4;
  709. creature.yv = 0;
  710.  
  711. // clear the primary and secondary surfaces
  712. memset(&ddbltfx,0,sizeof(ddbltfx));
  713. ddbltfx.dwSize = sizeof(ddbltfx);
  714. ddbltfx.dwFillColor = 0;
  715.  
  716. lpddsprimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx); 
  717. lpddsback->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx); 
  718.  
  719. // delete the bitmap 
  720. Unload_Bitmap_File(&bitmap8bit);
  721.  
  722. // return success
  723. return(1);
  724.  
  725. } // end Game_Init
  726.  
  727. ///////////////////////////////////////////////////////////
  728.  
  729. int Game_Shutdown(void *parms)
  730. {
  731. // this function is where you shutdown your game and
  732. // release all resources that you allocated
  733.  
  734. // delete bob
  735. Destroy_BOB(&creature);
  736.  
  737. // first release the secondary surface
  738. if (lpddsback!=NULL)
  739.    lpddsback->Release();
  740.  
  741. // now release the primary surface
  742. if (lpddsprimary!=NULL)
  743.    lpddsprimary->Release();
  744.        
  745. // release the directdraw object
  746. if (lpdd!=NULL)
  747.    lpdd->Release();
  748.  
  749. // return success
  750. return(1);
  751. } // end Game_Shutdown
  752.  
  753. ///////////////////////////////////////////////////////////
  754.  
  755. int Game_Main(void *parms)
  756. {
  757. // this is the workhorse of your game it will be called
  758. // continuously in real-time this is like main() in C
  759. // all the calls for you game go here!
  760.  
  761. int index,   // looping variable
  762.     length;  // length of current message
  763.     
  764. static int mindex=0,  // current message being played
  765.            mcount=0;  // timing counter to update messages
  766.  
  767. static char *messages[] = {"Will", "Work", "For", "Energion Cubes" };
  768.  
  769. // check of user is trying to exit
  770. if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
  771.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  772.  
  773. // clear secondary buffer
  774. memset(&ddbltfx,0,sizeof(ddbltfx));
  775. ddbltfx.dwSize = sizeof(ddbltfx);
  776. ddbltfx.dwFillColor = 0;
  777. lpddsback->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx); 
  778.  
  779. // move creature
  780. creature.x+=creature.xv;
  781.  
  782. // test if creature is offscreen
  783. if (creature.x >= SCREEN_WIDTH)
  784.    creature.x = 0;
  785.  
  786. // draw creature
  787. Draw_BOB(&creature, lpddsback);
  788.  
  789. // now use GDI to draw text above monster
  790. HDC xdc; // the working dc
  791.  
  792. // get the dc from secondary back buffer
  793. lpddsback->GetDC(&xdc);
  794.  
  795. // set the colors for the text up
  796. SetTextColor(xdc, RGB(0,255,0));
  797.  
  798. // set background mode to transparent so black isn't copied
  799. SetBkMode(xdc, TRANSPARENT);
  800.  
  801. // draw the text above the creature
  802. length = strlen(messages[mindex]);
  803. TextOut(xdc,creature.x - (4*length) + 32,creature.y-32,messages[mindex],length);
  804.  
  805. // release the dc
  806. lpddsback->ReleaseDC(xdc);
  807.  
  808. // flip pages
  809. while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);
  810.  
  811. // slow things down
  812. Sleep(30);
  813.  
  814. // update the message string
  815. if (++mcount > 30)
  816.    {
  817.    // reset count
  818.    mcount = 0;
  819.  
  820.    // update message
  821.    if (++mindex >= 4)
  822.        mindex=0;
  823.  
  824.    } // end if
  825.  
  826. // return success
  827. return(1);
  828.  
  829. } // end Game_Main
  830.  
  831.