home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / Source / GPCHAP23 / PROG23_4.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-01  |  17.4 KB  |  671 lines

  1. // PROG23_4.CPP - pattern demo
  2. // to compile make sure to include DDRAW.LIB, DSOUND.LIB,
  3. // DINPUT.LIB, WINMM.LIB, and of course GPDUMB I and II files.
  4.  
  5. // INCLUDES ///////////////////////////////////////////////
  6.  
  7. #define WIN32_LEAN_AND_MEAN  
  8. #define INITGUID
  9.  
  10. #include <windows.h>   // include important windows stuff
  11. #include <windowsx.h> 
  12. #include <mmsystem.h>
  13. #include <iostream.h> // include important C/C++ stuff
  14. #include <conio.h>
  15. #include <stdlib.h>
  16. #include <malloc.h>
  17. #include <memory.h>
  18. #include <string.h>
  19. #include <stdarg.h>
  20. #include <stdio.h> 
  21. #include <math.h>
  22. #include <io.h>
  23. #include <fcntl.h>
  24.  
  25. #include <ddraw.h>  // directX includes
  26. #include <dsound.h>
  27. #include <dinput.h>
  28. #include "gpdumb1.h" // game library includes
  29. #include "gpdumb2.h"
  30.  
  31. // DEFINES ////////////////////////////////////////////////
  32.  
  33. // defines for windows 
  34. #define WINDOW_CLASS_NAME "WINXCLASS"  // class name
  35.  
  36. #define WINDOW_WIDTH    320   // size of window
  37. #define WINDOW_HEIGHT   240
  38.  
  39. #define NUM_PATTERNS    4     // number of patterns in system
  40.  
  41. // pattern instruction opcodes for bot
  42.  
  43. // directional instructions
  44. #define OPC_E    0  // move west
  45. #define OPC_NE   1  // move northeast
  46. #define OPC_N    2  // move north
  47. #define OPC_NW   3  // move northwest
  48. #define OPC_W    4  // move west
  49. #define OPC_SW   5  // move southwest
  50. #define OPC_S    6  // move south
  51. #define OPC_SE   7  // move southeast
  52.  
  53. // special instructions
  54. #define OPC_STOP 8  // stop for a moment
  55. #define OPC_RAND 9  // select a random direction
  56. #define OPC_END  -1 // end pattern
  57.  
  58. // PROTOTYPES /////////////////////////////////////////////
  59.  
  60. // game console
  61. int Game_Init(void *parms=NULL);
  62. int Game_Shutdown(void *parms=NULL);
  63. int Game_Main(void *parms=NULL);
  64.  
  65. // GLOBALS ////////////////////////////////////////////////
  66.  
  67. HWND main_window_handle           = NULL; // save the window handle
  68. HINSTANCE main_instance           = NULL; // save the instance
  69. char buffer[80];                          // used to print text
  70.  
  71. BITMAP_IMAGE background_bmp;   // holds the background
  72. BOB          bot;              // the demo robot ship
  73.  
  74. // patterns in opcode operand format
  75. int pattern_1[] = {OPC_W, 10, OPC_NW, 10, OPC_N, 10, OPC_NE, 10, 
  76.                    OPC_E, 10, OPC_SE, 10, OPC_S, 10, OPC_SW, 10, 
  77.                    OPC_W, 10, OPC_RAND, 10,
  78.                    
  79.                    OPC_W, 20, OPC_NW, 10, OPC_N, 20, OPC_NE, 10, 
  80.                    OPC_E, 20, OPC_SE, 10, OPC_S, 20, OPC_SW, 10, 
  81.                    OPC_W, 10, OPC_END,0};
  82.                    
  83.  
  84. int pattern_2[] = {OPC_E, 20, OPC_W, 20, OPC_STOP, 20, OPC_NE, 10, 
  85.                    OPC_W, 10, OPC_NW, 10, OPC_SW, 20, OPC_NW, 20, 
  86.                    OPC_SW, 20, OPC_NW, 30, OPC_SW, 10, OPC_S, 50,  
  87.                    OPC_W, 2, OPC_NW, 2, OPC_N, 2, OPC_NE, 50,
  88.                    OPC_E,2, OPC_SE,2, OPC_S,2, OPC_RAND, 10, OPC_END,0};
  89.  
  90.  
  91.  
  92. int pattern_3[] = { OPC_N, 10, OPC_S, 10, OPC_N, 10, OPC_S, 10, 
  93.                     OPC_E, 10, OPC_W, 10, OPC_E, 10, OPC_W, 10, 
  94.                     OPC_NW, 10, OPC_N, 10, OPC_NE, 10, OPC_N, 10, 
  95.                     OPC_STOP, 20, OPC_RAND, 5, OPC_E, 50, OPC_S, 50, OPC_W, 50, 
  96.                     OPC_E, 10, OPC_E, 10, OPC_E, 10, OPC_NW, 100, 
  97.                     OPC_STOP, 10, OPC_END,0};
  98.  
  99.  
  100. int pattern_4[] = {OPC_W, 100, 
  101.                    OPC_NW, 2,OPC_N, 2,OPC_NE, 2,
  102.                    OPC_E, 100, 
  103.                    OPC_NE, 2,OPC_N, 2,OPC_NW, 2,
  104.                     
  105.                    OPC_W, 100, 
  106.                    OPC_NW, 2,OPC_N, 2,OPC_NE, 2,
  107.                    OPC_E, 100, 
  108.                    OPC_NE, 2,OPC_N, 2,OPC_NW, 2,
  109.                     
  110.                    OPC_W, 100, 
  111.                    OPC_NW, 2,OPC_N, 2,OPC_NE, 2,
  112.                    OPC_E, 100, 
  113.                    OPC_NE, 2,OPC_N, 2,OPC_NW, 2,
  114.  
  115.                    OPC_RAND, 10, OPC_RAND, 5,
  116.  
  117.                    OPC_SW, 2,OPC_S, 2,OPC_SE, 2,
  118.                    OPC_E, 100, 
  119.                    OPC_SE, 2,OPC_S, 2,OPC_SW, 2,
  120.                    OPC_W, 100,
  121.  
  122.                    OPC_SW, 2,OPC_S, 2,OPC_SE, 2,
  123.                    OPC_E, 100, 
  124.                    OPC_SE, 2,OPC_S, 2,OPC_SW, 2,
  125.                    OPC_W, 100,
  126.  
  127.                    OPC_SW, 2,OPC_S, 2,OPC_SE, 2,
  128.                    OPC_E, 100, 
  129.                    OPC_SE, 2,OPC_S, 2,OPC_SW, 2,
  130.                    OPC_W, 100, OPC_END,0};
  131.  
  132. // master pattern array
  133. int *patterns[NUM_PATTERNS] = {pattern_1, pattern_2, pattern_3, pattern_4};
  134.  
  135. int *curr_pattern=NULL;  // current pattern being processed
  136.  
  137. int bot_ip     =0,       // pattern instruction pointer for bot
  138.     bot_counter=0,       // counter of pattern control
  139.     bot_pattern_index;   // the current pattern being executed
  140.  
  141. // used as a index to string lookup to help print out
  142. char *opcode_names[] = {"OPC_E",
  143.                         "OPC_NE", 
  144.                         "OPC_N",    
  145.                         "OPC_NW",   
  146.                         "OPC_W",    
  147.                         "OPC_SW",   
  148.                         "OPC_S",    
  149.                         "OPC_SE",   
  150.                         "OPC_STOP", 
  151.                         "OPC_RAND", 
  152.                         "OPC_END",};  
  153. // sound stuff
  154. int engines_id = -1; // engine sound id
  155.  
  156. // FUNCTIONS //////////////////////////////////////////////
  157.  
  158. LRESULT CALLBACK WindowProc(HWND hwnd, 
  159.                             UINT msg, 
  160.                             WPARAM wparam, 
  161.                             LPARAM lparam)
  162. {
  163. // this is the main message handler of the system
  164. PAINTSTRUCT    ps;           // used in WM_PAINT
  165. HDC            hdc;       // handle to a device context
  166.  
  167. // what is the message 
  168. switch(msg)
  169.     {    
  170.     case WM_CREATE: 
  171.         {
  172.         // do initialization stuff here
  173.         return(0);
  174.         } break;
  175.  
  176.     case WM_PAINT:
  177.          {
  178.          // start painting
  179.          hdc = BeginPaint(hwnd,&ps);
  180.  
  181.          // end painting
  182.          EndPaint(hwnd,&ps);
  183.          return(0);
  184.         } break;
  185.  
  186.     case WM_DESTROY: 
  187.         {
  188.         // kill the application            
  189.         PostQuitMessage(0);
  190.         return(0);
  191.         } break;
  192.  
  193.     default:break;
  194.  
  195.     } // end switch
  196.  
  197. // process any messages that we didn't take care of 
  198. return (DefWindowProc(hwnd, msg, wparam, lparam));
  199.  
  200. } // end WinProc
  201.  
  202. // WINMAIN ////////////////////////////////////////////////
  203.  
  204. int WINAPI WinMain(    HINSTANCE hinstance,
  205.                     HINSTANCE hprevinstance,
  206.                     LPSTR lpcmdline,
  207.                     int ncmdshow)
  208. {
  209. // this is the winmain function
  210.  
  211. WNDCLASS winclass;    // this will hold the class we create
  212. HWND     hwnd;        // generic window handle
  213. MSG         msg;        // generic message
  214. HDC      hdc;       // generic dc
  215. PAINTSTRUCT ps;     // generic paintstruct
  216.  
  217. // first fill in the window class stucture
  218. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  219.                           CS_HREDRAW | CS_VREDRAW;
  220. winclass.lpfnWndProc    = WindowProc;
  221. winclass.cbClsExtra        = 0;
  222. winclass.cbWndExtra        = 0;
  223. winclass.hInstance        = hinstance;
  224. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  225. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  226. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  227. winclass.lpszMenuName    = NULL; 
  228. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  229.  
  230. // register the window class
  231. if (!RegisterClass(&winclass))
  232.     return(0);
  233.  
  234. // create the window, note the use of WS_POPUP
  235. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  236.                           "WinX Game Console",     // title
  237.                           WS_POPUP | WS_VISIBLE,
  238.                            0,0,       // x,y
  239.                           WINDOW_WIDTH,  // width
  240.                           WINDOW_HEIGHT, // height
  241.                           NULL,       // handle to parent 
  242.                           NULL,       // handle to menu
  243.                           hinstance,// instance
  244.                           NULL)))    // creation parms
  245. return(0);
  246.  
  247. // save the window handle and instance in a global
  248. main_window_handle = hwnd;
  249. main_instance      = hinstance;
  250.  
  251. // perform all game console specific initialization
  252. Game_Init();
  253.  
  254. // enter main event loop
  255. while(1)
  256.     {
  257.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  258.         { 
  259.         // test if this is a quit
  260.         if (msg.message == WM_QUIT)
  261.            break;
  262.     
  263.         // translate any accelerator keys
  264.         TranslateMessage(&msg);
  265.  
  266.         // send the message to the window proc
  267.         DispatchMessage(&msg);
  268.         } // end if
  269.     
  270.     // main game processing goes here
  271.     Game_Main();
  272.  
  273.     } // end while
  274.  
  275. // shutdown game and release all resources
  276. Game_Shutdown();
  277.  
  278. // return to Windows like this
  279. return(msg.wParam);
  280.  
  281. } // end WinMain
  282.  
  283. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  284.  
  285. int Game_Init(void *parms)
  286. {
  287. // this function is where you do all the initialization 
  288. // for your game
  289.  
  290. int index; // looping variable
  291.  
  292. int bot_anim[2];
  293.  
  294. // start up DirectDraw (replace the parms as you desire)
  295. DD_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP);
  296.  
  297. // load background image
  298. Load_Bitmap_File(&bitmap8bit, "STARSB8.BMP");
  299. Create_Bitmap(&background_bmp,0,0,640,480);
  300. Load_Image_Bitmap(&background_bmp, &bitmap8bit,0,0,BITMAP_EXTRACT_MODE_ABS);
  301. Set_Palette(bitmap8bit.palette);
  302. Unload_Bitmap_File(&bitmap8bit);
  303.  
  304. // load the bots bitmaps
  305. Load_Bitmap_File(&bitmap8bit, "BOTS8.BMP");
  306.  
  307. // create bat bob
  308. Create_BOB(&bot,320,200,116,60,16,BOB_ATTR_MULTI_ANIM | BOB_ATTR_VISIBLE, DDSCAPS_SYSTEMMEMORY);
  309. Set_Anim_Speed_BOB(&bot, 2);
  310.  
  311. // load the bot in 
  312. for (index=0; index < 16; index++)
  313.     Load_Frame_BOB(&bot, &bitmap8bit, index, index%2, index/2, BITMAP_EXTRACT_MODE_CELL);
  314.  
  315. // unload bot
  316. Unload_Bitmap_File(&bitmap8bit);
  317.  
  318. // create animations for bot
  319. for (index=0; index<8; index++)
  320.     {
  321.     // generate the animation on the fly
  322.     bot_anim[0] = index*2;
  323.     bot_anim[1] = bot_anim[0]+1;
  324.  
  325.     // load the generated animation
  326.     Load_Animation_BOB(&bot, index, 2, bot_anim);
  327.     } // end for index
  328.  
  329. // set the animation to right direction
  330. Set_Animation_BOB(&bot,0);
  331.  
  332. // initialize directinput
  333. DInput_Init();
  334.  
  335. // acquire the keyboard only
  336. DI_Init_Keyboard();
  337.  
  338. // initilize DirectSound
  339. DSound_Init();
  340.  
  341. // load background sounds
  342. engines_id = Load_WAV("ENGINES.WAV");
  343.  
  344. // start the sounds
  345. Play_Sound(engines_id, DSBPLAY_LOOPING);
  346.  
  347. // set clipping rectangle to screen extents so objects dont
  348. // mess up at edges
  349. RECT screen_rect = {0,0,screen_width,screen_height};
  350. lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);
  351.  
  352. // hide the mouse
  353. ShowCursor(FALSE);
  354.  
  355. // seed random number generate
  356. srand(Start_Clock());
  357.  
  358. // return success
  359. return(1);
  360.  
  361. } // end Game_Init
  362.  
  363. ///////////////////////////////////////////////////////////
  364.  
  365. int Game_Shutdown(void *parms)
  366. {
  367. // this function is where you shutdown your game and
  368. // release all resources that you allocated
  369.  
  370. // shut everything down
  371.  
  372. // kill all the bobs
  373. Destroy_BOBX(&bot);
  374.  
  375. // shutdown directdraw last
  376. DD_Shutdown();
  377.  
  378. // now directsound
  379. Stop_All_Sounds();
  380. DSound_Shutdown();
  381.  
  382. // shut down directinput
  383. DInput_Shutdown();
  384.  
  385. // return success
  386. return(1);
  387. } // end Game_Shutdown
  388.  
  389. //////////////////////////////////////////////////////////
  390.  
  391. void Bot_AI(void)
  392. {
  393. // this function controls the ai of the bot and the pattern
  394. // processing
  395.  
  396. static int opcode,  // current pattern opcode
  397.            operand; // current operand 
  398.  
  399. // test if it's time to process a new instruction
  400. if (curr_pattern==NULL)
  401.    {
  402.    // select a random pattern in pattern bank
  403.    bot_pattern_index = rand()%NUM_PATTERNS;
  404.    curr_pattern = patterns[bot_pattern_index];
  405.    
  406.    // now reset instuction pointer
  407.    bot_ip = 0;
  408.  
  409.    // reset counter
  410.    bot_counter = 0;
  411.  
  412.    } // end if
  413.  
  414. // process next instruction if it's time
  415. if (--bot_counter <= 0)
  416.     {
  417.     // get next instruction
  418.     opcode  = curr_pattern[bot_ip++];
  419.     operand = curr_pattern[bot_ip++];
  420.  
  421.     // test what the opcode is
  422.     switch(opcode)
  423.         {
  424.         case OPC_E:
  425.             {
  426.             // set direction to east
  427.             Set_Vel_BOB(&bot,6,0);
  428.   
  429.             // set animation to east
  430.             Set_Animation_BOB(&bot,opcode);
  431.             
  432.             // set counter to instuction operand
  433.             bot_counter = operand;
  434.  
  435.             } break;
  436.  
  437.         case OPC_NE:
  438.             {
  439.             // set direction to northeast
  440.             Set_Vel_BOB(&bot,6,-6);
  441.   
  442.             // set animation to northeast
  443.             Set_Animation_BOB(&bot,opcode);
  444.             
  445.             // set counter to instuction operand
  446.             bot_counter = operand;
  447.  
  448.             } break;
  449.  
  450.         case OPC_N: 
  451.             {
  452.             // set direction to north
  453.             Set_Vel_BOB(&bot,0,-6);
  454.   
  455.             // set animation to north
  456.             Set_Animation_BOB(&bot,opcode);
  457.             
  458.             // set counter to instuction operand
  459.             bot_counter = operand;
  460.  
  461.             } break;            
  462.  
  463.         case OPC_NW:
  464.             {
  465.             // set direction to northwest
  466.             Set_Vel_BOB(&bot,-6,-6);
  467.   
  468.             // set animation to northwest
  469.             Set_Animation_BOB(&bot,opcode);
  470.             
  471.             // set counter to instuction operand
  472.             bot_counter = operand;
  473.  
  474.             } break;            
  475.  
  476.         case OPC_W: 
  477.             {
  478.             // set direction to west
  479.             Set_Vel_BOB(&bot,-6,0);
  480.   
  481.             // set animation to west
  482.             Set_Animation_BOB(&bot,opcode);
  483.             
  484.             // set counter to instuction operand
  485.             bot_counter = operand;
  486.              
  487.             } break;            
  488.  
  489.         case OPC_SW:
  490.             {
  491.             // set direction to southwest
  492.             Set_Vel_BOB(&bot,-6,6);
  493.   
  494.             // set animation to southwest
  495.             Set_Animation_BOB(&bot,opcode);
  496.             
  497.             // set counter to instuction operand
  498.             bot_counter = operand;
  499.  
  500.             } break;            
  501.  
  502.         case OPC_S: 
  503.             {
  504.             // set direction to south
  505.             Set_Vel_BOB(&bot,0,6);
  506.   
  507.             // set animation to south
  508.             Set_Animation_BOB(&bot,opcode);
  509.             
  510.             // set counter to instuction operand
  511.             bot_counter = operand;
  512.  
  513.             } break;            
  514.  
  515.         case OPC_SE:
  516.             {
  517.             // set direction to southeast
  518.             Set_Vel_BOB(&bot,6,6);
  519.   
  520.             // set animation to southeast
  521.             Set_Animation_BOB(&bot,opcode);
  522.             
  523.             // set counter to instuction operand
  524.             bot_counter = operand;
  525.  
  526.             } break;            
  527.  
  528.         case OPC_STOP: 
  529.             {
  530.             // stop motion
  531.             Set_Vel_BOB(&bot,0,0);
  532.             
  533.             // set counter to instuction operand
  534.             bot_counter = operand;
  535.  
  536.             } break;
  537.  
  538.         case OPC_RAND:
  539.             {
  540.             // set direction randomly
  541.             Set_Vel_BOB(&bot,-4+rand()%9,-4+rand()%9);
  542.   
  543.             // set animation to south
  544.             Set_Animation_BOB(&bot,OPC_S);
  545.             
  546.             // set counter to instuction operand
  547.             bot_counter = operand;
  548.  
  549.             } break;
  550.  
  551.         case OPC_END: 
  552.             {
  553.             // stop motion
  554.             Set_Vel_BOB(&bot,0,0);
  555.             
  556.             // select a random pattern in pattern bank
  557.             bot_pattern_index = rand()%NUM_PATTERNS;
  558.             curr_pattern = patterns[bot_pattern_index];
  559.    
  560.             // now reset instuction pointer
  561.             bot_ip = 0;
  562.  
  563.             // reset counter
  564.             bot_counter = 0;
  565.  
  566.             } break;
  567.         
  568.         default: break;
  569.  
  570.         } // end switch
  571.  
  572.     } // end if
  573.  
  574.  
  575. // draw stats
  576. sprintf(buffer,"Pattern #%d",bot_pattern_index);
  577. Draw_Text_GDI(buffer,10, 400,RGB(0,255,0), lpddsback);
  578.  
  579. sprintf(buffer,"Opcode=%s Operand=%d",opcode_names[opcode],operand);
  580. Draw_Text_GDI(buffer,10, 416,RGB(0,255,0), lpddsback);
  581.  
  582. sprintf(buffer,"Instruction Ptr=%d ", bot_ip);
  583. Draw_Text_GDI(buffer,10, 432,RGB(0,255,0), lpddsback);
  584.  
  585. sprintf(buffer,"Counter=%d ", bot_counter);
  586. Draw_Text_GDI(buffer,10, 448,RGB(0,255,0), lpddsback);
  587.  
  588. } // end Bot_AI
  589.  
  590. //////////////////////////////////////////////////////////
  591.  
  592. int Game_Main(void *parms)
  593. {
  594. // this is the workhorse of your game it will be called
  595. // continuously in real-time this is like main() in C
  596. // all the calls for you game go here!
  597.  
  598. int index; // looping var
  599.  
  600. // start the timing clock
  601. Start_Clock();
  602.  
  603. // clear the drawing surface
  604. DD_Fill_Surface(lpddsback, 0);
  605.  
  606. // lock back buffer and copy background into it
  607. DD_Lock_Back_Surface();
  608.  
  609. // draw background
  610. Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0);
  611.  
  612. // unlock back surface
  613. DD_Unlock_Back_Surface();
  614.  
  615. // read keyboard
  616. DI_Read_Keyboard();
  617.  
  618. // do the ai on bot
  619. Bot_AI();
  620.  
  621. // the animate the bot
  622. Animate_BOB(&bot);
  623.  
  624. // move bot
  625. Move_BOB(&bot);
  626.  
  627. // test if bot is off screen, if so wrap around
  628. if (bot.x >= SCREEN_WIDTH)
  629.    bot.x = -bot.width;
  630. else
  631. if (bot.x < -bot.width)
  632.    bot.x = SCREEN_WIDTH;
  633.  
  634. if (bot.y >= SCREEN_HEIGHT)
  635.    bot.y = -bot.height;
  636. else
  637. if (bot.y < -bot.height)
  638.    bot.y = SCREEN_HEIGHT;
  639.  
  640. // draw the bot
  641. Draw_BOB(&bot, lpddsback);
  642.  
  643. // draw title
  644. Draw_Text_GDI("I-ROBOT - Pattern Demo",10, 10,RGB(0,255,255), lpddsback);
  645.  
  646. // flip the surfaces
  647. DD_Flip();
  648.  
  649. // sync to 30ish fps
  650. Wait_Clock(30);
  651.  
  652. // check of user is trying to exit
  653. if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
  654.     {
  655.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  656.  
  657.     // stop all sounds
  658.     Stop_All_Sounds();
  659.  
  660.     // do a screen transition
  661.     Screen_Transitions(SCREEN_BLUENESS,NULL,0);
  662.  
  663.     } // end if
  664.  
  665. // return success
  666. return(1);
  667.  
  668. } // end Game_Main
  669.  
  670. //////////////////////////////////////////////////////////
  671.