home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / Source / GPCHAP12 / STARFERR.CPP < prev    next >
C/C++ Source or Header  |  2002-04-29  |  38KB  |  1,452 lines

  1. // STARFERR.CPP -  Game Engine Demo - STAR FERRET!
  2. // try and add stuff!
  3. // remember to compile you need GPDUMB1.CPP and
  4. // DirectDraw library DDRAW.LIB
  5.  
  6. // INCLUDES ///////////////////////////////////////////////
  7.  
  8. #define WIN32_LEAN_AND_MEAN  
  9. #define INITGUID
  10.  
  11. #include <windows.h>   // include important windows stuff
  12. #include <windowsx.h> 
  13. #include <mmsystem.h>
  14. #include <objbase.h>
  15. #include <iostream.h> // include important C/C++ stuff
  16. #include <conio.h>
  17. #include <stdlib.h>
  18. #include <malloc.h>
  19. #include <memory.h>
  20. #include <string.h>
  21. #include <stdarg.h>
  22. #include <stdio.h> 
  23. #include <math.h>
  24. #include <io.h>
  25. #include <fcntl.h>
  26.  
  27. #include <ddraw.h>     // directX includes
  28. #include "gpdumb1.h"
  29.  
  30. // DEFINES ////////////////////////////////////////////////
  31.  
  32. // defines for windows 
  33. #define WINDOW_CLASS_NAME "WINXCLASS"  // class name
  34.  
  35. #define WINDOW_WIDTH    64   // size of window
  36. #define WINDOW_HEIGHT   48
  37.  
  38. // star ferret constants
  39.  
  40. // vertical extents of players motion
  41. #define MIN_STARFERRET_Y   300
  42. #define MAX_STARFERRET_Y   (480-32)
  43.  
  44. // weapons defines
  45. #define MAX_PLASMA         8   // max number of plasma pulses
  46.  
  47. #define PLASMA_STATE_OFF   0   // this plasma is dead or off
  48. #define PLASMA_STATE_ON    1   // this one is alive and in flight
  49.  
  50. // starfield defines
  51. #define MAX_STARS          128
  52.  
  53. // asteroid field defines
  54. #define MAX_ROCKS          48
  55. #define ROCK_STATE_OFF     0   // this rock is dead or off
  56. #define ROCK_STATE_ON      1   // this one is alive and in flight
  57.  
  58. #define ROCK_LARGE         0   // sizes of rock
  59. #define ROCK_MEDIUM        1
  60. #define ROCK_SMALL         2
  61.  
  62. // explosion defines 
  63. #define MAX_BURSTS          8
  64. #define BURST_STATE_OFF     0   // this burst is dead or off
  65. #define BURST_STATE_ON      1   // this one is alive
  66.  
  67. // defines for player states
  68. #define PLAYER_STATE_DEAD     0
  69. #define PLAYER_STATE_DYING    1
  70. #define PLAYER_STATE_ALIVE    2 
  71.  
  72. // PROTOTYPES /////////////////////////////////////////////
  73.  
  74. // game console
  75. int Game_Init(void *parms=NULL);
  76. int Game_Shutdown(void *parms=NULL);
  77. int Game_Main(void *parms=NULL);
  78.  
  79. // helper functions for game logic
  80. void Draw_Info(void);
  81. void Start_Burst(int x, int y, int width, int height, int xv,int yv);
  82. void Draw_Bursts(void);
  83. void Move_Bursts(void);
  84. void Delete_Bursts(void);
  85. void Init_Bursts(void);
  86. void Draw_Rocks(void);
  87. void Start_Rock(int x, int y, int size,int xv, int yv);
  88. void Move_Rocks(void);
  89. void Delete_Rocks(void);
  90. void Init_Rocks(void);
  91. void Fire_Plasma(int x,int y, int vel);
  92. void Draw_Plasma(void);
  93. void Move_Plasma(void);
  94. int Collision_Test(int x1, int y1, int w1, int h1, 
  95.                    int x2, int y2, int w2, int h2);
  96.  
  97. void Delete_Plasma(void);
  98. void Init_Plasma(void);
  99. void Move_Stars(void);
  100. void Draw_Stars(void);
  101. void Init_Stars(void);
  102.  
  103. // TYPES //////////////////////////////////////////////////
  104.  
  105. // used to contain a single star
  106. typedef struct STAR_TYP
  107.     {
  108.     UCHAR color;  
  109.     int x,y;
  110.     int velocity;
  111.     } STAR, *STAR_PTR;
  112.  
  113. // GLOBALS ////////////////////////////////////////////////
  114.  
  115. HWND main_window_handle = NULL; // save the window handle
  116. HINSTANCE main_instance = NULL; // save the instance
  117. char buffer[80];                // used to print text
  118.  
  119. BOB starferret;            // the player 
  120. int moving_up = 0;         // used to track if player is moving up for
  121.                            // various parallax effects
  122. BOB plasma[MAX_PLASMA];    // plasma pulses
  123. BOB rocks[MAX_ROCKS];      // the asteroids
  124. BOB bursts[MAX_BURSTS];    // the explosion bursts
  125.  
  126. int rock_sizes[3] = {96,32,12}; // width X height sizes for scaler
  127.  
  128. STAR stars[MAX_STARS]; // the star field
  129.  
  130. // player state variables
  131. int player_state = PLAYER_STATE_ALIVE;
  132. int player_score = 0;  // the score
  133. int player_ships = 5;  // ships left
  134. int player_damage = 0; // damage of player
  135.  
  136. // PROTOTYPES //////////////////////////////////////////////
  137.  
  138.  
  139. // FUNCTIONS //////////////////////////////////////////////
  140.  
  141. LRESULT CALLBACK WindowProc(HWND hwnd, 
  142.                             UINT msg, 
  143.                             WPARAM wparam, 
  144.                             LPARAM lparam)
  145. {
  146. // this is the main message handler of the system
  147. PAINTSTRUCT    ps;           // used in WM_PAINT
  148. HDC            hdc;       // handle to a device context
  149.  
  150. // what is the message 
  151. switch(msg)
  152.     {    
  153.     case WM_CREATE: 
  154.         {
  155.         // do initialization stuff here
  156.         return(0);
  157.         } break;
  158.  
  159.     case WM_PAINT:
  160.          {
  161.          // start painting
  162.          hdc = BeginPaint(hwnd,&ps);
  163.  
  164.          // end painting
  165.          EndPaint(hwnd,&ps);
  166.          return(0);
  167.         } break;
  168.  
  169.     case WM_DESTROY: 
  170.         {
  171.         // kill the application            
  172.         PostQuitMessage(0);
  173.         return(0);
  174.         } break;
  175.  
  176.     default:break;
  177.  
  178.     } // end switch
  179.  
  180. // process any messages that we didn't take care of 
  181. return (DefWindowProc(hwnd, msg, wparam, lparam));
  182.  
  183. } // end WinProc
  184.  
  185. // WINMAIN ////////////////////////////////////////////////
  186.  
  187. int WINAPI WinMain(    HINSTANCE hinstance,
  188.                     HINSTANCE hprevinstance,
  189.                     LPSTR lpcmdline,
  190.                     int ncmdshow)
  191. {
  192. // this is the winmain function
  193.  
  194. WNDCLASS winclass;    // this will hold the class we create
  195. HWND     hwnd;        // generic window handle
  196. MSG         msg;        // generic message
  197. HDC      hdc;       // generic dc
  198. PAINTSTRUCT ps;     // generic paintstruct
  199.  
  200. // first fill in the window class stucture
  201. winclass.style            = CS_DBLCLKS | CS_OWNDC | 
  202.                           CS_HREDRAW | CS_VREDRAW;
  203. winclass.lpfnWndProc    = WindowProc;
  204. winclass.cbClsExtra        = 0;
  205. winclass.cbWndExtra        = 0;
  206. winclass.hInstance        = hinstance;
  207. winclass.hIcon            = LoadIcon(NULL, IDI_APPLICATION);
  208. winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  209. winclass.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
  210. winclass.lpszMenuName    = NULL; 
  211. winclass.lpszClassName    = WINDOW_CLASS_NAME;
  212.  
  213. // register the window class
  214. if (!RegisterClass(&winclass))
  215.     return(0);
  216.  
  217. // create the window, note the use of WS_POPUP
  218. if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
  219.                           "WinX Game Console",     // title
  220.                           WS_POPUP | WS_VISIBLE,
  221.                            0,0,       // x,y
  222.                           WINDOW_WIDTH,  // width
  223.                           WINDOW_HEIGHT, // height
  224.                           NULL,       // handle to parent 
  225.                           NULL,       // handle to menu
  226.                           hinstance,// instance
  227.                           NULL)))    // creation parms
  228. return(0);
  229.  
  230. // save the window handle and instance in a global
  231. main_window_handle = hwnd;
  232. main_instance      = hinstance;
  233.  
  234. // perform all game console specific initialization
  235. Game_Init();
  236.  
  237. // enter main event loop
  238. while(1)
  239.     {
  240.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  241.         { 
  242.         // test if this is a quit
  243.         if (msg.message == WM_QUIT)
  244.            break;
  245.     
  246.         // translate any accelerator keys
  247.         TranslateMessage(&msg);
  248.  
  249.         // send the message to the window proc
  250.         DispatchMessage(&msg);
  251.         } // end if
  252.     
  253.     // main game processing goes here
  254.     Game_Main();
  255.  
  256.     } // end while
  257.  
  258. // shutdown game and release all resources
  259. Game_Shutdown();
  260.  
  261. // return to Windows like this
  262. return(msg.wParam);
  263.  
  264. } // end WinMain
  265.  
  266. ///////////////////////////////////////////////////////////
  267.  
  268. void Init_Stars(void)
  269. {
  270. // this function initializes all the stars in such a way
  271. // that their intensity is proportional to their 
  272. // velocity
  273.  
  274. for (int index=0; index<MAX_STARS; index++)
  275.     {
  276.     // random postion
  277.     stars[index].x = rand()%screen_width;
  278.     stars[index].y = rand()%screen_height;
  279.  
  280.     // select star plane
  281.     int plane = rand()%4; // (1..4)
  282.  
  283.     // based on plane select velocity and color
  284.     stars[index].velocity = -(1 + plane*2);
  285.     stars[index].color = 25 - (plane*3);
  286.  
  287.     } // end for index
  288.  
  289. } // end Init_Stars
  290.  
  291. ///////////////////////////////////////////////////////////
  292.  
  293. void Move_Stars(void)
  294. {
  295. // this function moves all the stars
  296.  
  297. for (int index=0; index<MAX_STARS; index++)
  298.     {
  299.     // translate upward
  300.     if (!moving_up)
  301.        stars[index].y-=stars[index].velocity;
  302.     else
  303.        stars[index].y-=(stars[index].velocity+((moving_up*stars[index].velocity)));
  304.      
  305.     // test for collision with top of screen
  306.     if (stars[index].y >= screen_height)
  307.         stars[index].y-=screen_height;
  308.  
  309.     } // end for index
  310.  
  311. } // end Move_Stars
  312.  
  313. ///////////////////////////////////////////////////////////
  314.  
  315. void Draw_Stars(void)
  316. {
  317. // this function draws all the stars
  318.  
  319. // lock back surface
  320. DD_Lock_Back_Surface();
  321.  
  322. // draw all the stars
  323. for (int index=0; index<MAX_STARS; index++)
  324.     {
  325.     // draw stars 
  326.     Draw_Pixel(stars[index].x,stars[index].y, stars[index].color,back_buffer, back_lpitch);
  327.  
  328.     } // end for index
  329.  
  330. // unlock the secondary surface
  331. DD_Unlock_Back_Surface();
  332.  
  333. } // end Draw_Stars
  334.  
  335. ///////////////////////////////////////////////////////////
  336.  
  337. void Init_Plasma(void)
  338. {
  339. // this function initializes and loads all the plasma 
  340. // weapon pulses
  341.  
  342. // load the plasma imagery 
  343. Load_Bitmap_File(&bitmap8bit, "PLASMA8.BMP");
  344.  
  345.  
  346. #if 1
  347. // now create and load each plasma pulse
  348. for (int pulse=0; pulse<MAX_PLASMA; pulse++)
  349.     {
  350.     // create the bob to hold pulse
  351.     Create_BOB(&plasma[pulse],0,0,16,24,6,
  352.                BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
  353.                DDSCAPS_SYSTEMMEMORY);
  354.  
  355.     // load animation frames
  356.     for (int frame=0; frame<6; frame++)
  357.          Load_Frame_BOB(&plasma[pulse],&bitmap8bit,frame,frame,0,BITMAP_EXTRACT_MODE_CELL);  
  358.  
  359.     // set animation rate
  360.     Set_Anim_Speed_BOB(&plasma[pulse],1);
  361.  
  362.     // set state to off
  363.     plasma[pulse].state = PLASMA_STATE_OFF;
  364.  
  365.     } // end for pulse
  366. #endif
  367.  
  368. #if 0
  369. // create the first bob
  370. Create_BOB(&plasma[0],0,0,16,24,6,
  371.             BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
  372.             DDSCAPS_SYSTEMMEMORY);
  373.  
  374. // load animation frames
  375. for (int frame=0; frame<6; frame++)
  376.      Load_Frame_BOB(&plasma[0],&bitmap8bit,frame,frame,0,BITMAP_EXTRACT_MODE_CELL);  
  377.  
  378. // set animation rate
  379. Set_Anim_Speed_BOB(&plasma[0],1);
  380.  
  381. // set state to off
  382. plasma[0].state = PLASMA_STATE_OFF;
  383.  
  384. for (int pulse=1; pulse<MAX_PLASMA; pulse++)
  385.     {
  386.     memcpy(&plasma[pulse], &plasma[0], sizeof(BOB));
  387.     } // end for pulse
  388.  
  389. #endif
  390.  
  391.  
  392. // unload data infile
  393. Unload_Bitmap_File(&bitmap8bit);
  394.  
  395. } // end Init_Plasma
  396.  
  397. ///////////////////////////////////////////////////////////
  398.  
  399. void Delete_Plasma(void)
  400. {
  401. // this function simply deletes all memory and surfaces
  402. // related to the plasma pulses
  403.  
  404. for (int index=0; index<MAX_PLASMA; index++)
  405.     Destroy_BOB(&plasma[index]);
  406.  
  407. } // end Delete_Plasma
  408.  
  409. ///////////////////////////////////////////////////////////
  410.  
  411. int Collision_Test(int x1, int y1, int w1, int h1, 
  412.                    int x2, int y2, int w2, int h2) 
  413. {
  414. // this function tests if the two rects overlap
  415.  
  416. // get the radi of each rect
  417. int width1  = (w1>>1) - (w1>>3);
  418. int height1 = (h1>>1) - (h1>>3);
  419.  
  420. int width2  = (w2>>1) - (w2>>3);
  421. int height2 = (h2>>1) - (h2>>3);
  422.  
  423. // compute center of each rect
  424. int cx1 = x1 + width1;
  425. int cy1 = y1 + height1;
  426.  
  427. int cx2 = x2 + width2;
  428. int cy2 = y2 + height2;
  429.  
  430. // compute deltas
  431. int dx = abs(cx2 - cx1);
  432. int dy = abs(cy2 - cy1);
  433.  
  434. // test if rects overlap
  435. if (dx < (width1+width2) && dy < (height1+height2))
  436.    return(1);
  437. else
  438. // else no collision
  439. return(0);
  440.  
  441. } // end Collision_Test
  442.  
  443. ///////////////////////////////////////////////////////////
  444.  
  445. void Move_Plasma(void)
  446. {
  447. // this function moves all the plasma pulses and checks for
  448. // collision with the rocks
  449.  
  450. for (int index=0; index<MAX_PLASMA; index++)
  451.     {
  452.     // test if plasma pulse is in flight
  453.     if (plasma[index].state == PLASMA_STATE_ON)
  454.         {
  455.         // move the pulse upward
  456.         Move_BOB(&plasma[index]);
  457.   
  458.         // test for boundaries
  459.         if (plasma[index].y < 0 )
  460.             {
  461.             // kill the pulse
  462.             plasma[index].state = PLASMA_STATE_OFF;
  463.  
  464.             // move to next pulse
  465.             continue;
  466.             } // end if
  467.  
  468.         // test for collision with rocks
  469.  
  470.         for (int rock=0; rock<MAX_ROCKS; rock++)
  471.             {
  472.             if (rocks[rock].state==ROCK_STATE_ON)
  473.                 {
  474.                 // test for collision 
  475.                 if (Collision_Test(plasma[index].x, plasma[index].y, 
  476.                                    plasma[index].width, plasma[index].height,
  477.                                    rocks[rock].x, rocks[rock].y,
  478.                                    rocks[rock].varsI[1], rocks[rock].varsI[1]))
  479.                     {
  480.                     // kill pulse
  481.                     plasma[index].state = PLASMA_STATE_OFF;
  482.   
  483.                     // start explosion
  484.                     Start_Burst(plasma[index].x, plasma[index].y, 
  485.                                42,36,
  486.                                rocks[rock].xv*.5, rocks[rock].yv*.5);
  487.  
  488.                     // update score
  489.                     player_score+=rocks[rock].varsI[2];
  490.  
  491.                     // test strength of rock, cause damage
  492.                     rocks[rock].varsI[2]-=50;
  493.  
  494.                     // split test
  495.                     if (rocks[rock].varsI[2] > 0 && rocks[rock].varsI[2] < 50)
  496.                         {
  497.                         // test the size of rock
  498.                         switch(rocks[rock].varsI[0])
  499.                         {
  500.                         case ROCK_LARGE:
  501.                             {
  502.                             // split into two medium
  503.                             Start_Rock(rocks[rock].x+rand()%16,rocks[rock].y+rand()%16,
  504.                                        ROCK_MEDIUM,
  505.                                        rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
  506.                     
  507.                            Start_Rock(rocks[rock].x+rand()%16,rocks[rock].y+rand()%16,
  508.                                        ROCK_MEDIUM,
  509.                                        rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
  510.                             
  511.                            // throw in a small?
  512.                            if ((rand()%3)==1)
  513.                             Start_Rock(rocks[rock].x+rand()%16,rocks[rock].y+rand()%16,
  514.                                        ROCK_SMALL,
  515.                                        rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
  516.  
  517.                             // kill the original
  518.                             rocks[rock].state = ROCK_STATE_OFF;     
  519.             
  520.                             } break;
  521.  
  522.                         case ROCK_MEDIUM:
  523.                             {
  524.                             // split into 1 - 3 small
  525.                             int num_rocks = 1+rand()%3;
  526.  
  527.                             for (; num_rocks >=1; num_rocks--)
  528.                                 {
  529.                                 Start_Rock(rocks[rock].x+rand()%8,rocks[rock].y+rand()%8,
  530.                                            ROCK_SMALL,
  531.                                            rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
  532.  
  533.                                 } // end for num_rocks
  534.                  
  535.                             // kill the original
  536.                             rocks[rock].state = ROCK_STATE_OFF;
  537.  
  538.                             } break;
  539.  
  540.                         case ROCK_SMALL:
  541.                             {
  542.                             // just kill it
  543.                             rocks[rock].state = ROCK_STATE_OFF;
  544.  
  545.                             } break;
  546.  
  547.                         default:break;
  548.  
  549.         
  550.                         } // end switch
  551.  
  552.                         } // end if split
  553.                     else
  554.                     if (rocks[rock].varsI[2] <= 0)
  555.                         {
  556.                         // kill rock
  557.                         rocks[rock].state = ROCK_STATE_OFF;
  558.                         } // end else
  559.  
  560.                     // break out of loop
  561.                     break;
  562.  
  563.                    } // end if collision
  564.                 } // end if rock alive
  565.             } // end for rock
  566.  
  567.       } // end if
  568.  
  569.     } // end for index
  570.  
  571. } // end Move_Plasma
  572.  
  573. ///////////////////////////////////////////////////////////
  574.  
  575. void Draw_Plasma(void)
  576. {
  577. // this function draws all the plasma pulses
  578.  
  579. for (int index=0; index<MAX_PLASMA; index++)
  580.     {
  581.     // test if plasma pulse is in flight
  582.     if (plasma[index].state == PLASMA_STATE_ON)
  583.         {
  584.         // draw the pulse
  585.         Draw_BOB(&plasma[index],lpddsback);
  586.          
  587.         // animate the pulse
  588.         Animate_BOB(&plasma[index]);
  589.  
  590.         } // end if
  591.  
  592.     } // end for index
  593.  
  594. } // end Draw_Plasma
  595.  
  596. ///////////////////////////////////////////////////////////
  597.  
  598. void Fire_Plasma(int x,int y, int vel)
  599. {
  600. // this function fires a plasma pulse at the given starting
  601. // position and velocity, of course, one must be free for 
  602. // this to work
  603.  
  604. // scan for a pulse that is available
  605. for (int index=0; index<MAX_PLASMA; index++)
  606.     {
  607.     // is this one available
  608.       // test if plasma pulse is in flight
  609.     if (plasma[index].state == PLASMA_STATE_OFF)
  610.        {
  611.        // start this one up
  612.        plasma[index].x  = x;
  613.        plasma[index].y  = y;
  614.        plasma[index].yv = -vel;
  615.        plasma[index].curr_frame = 0;
  616.        plasma[index].state =  PLASMA_STATE_ON;
  617.        
  618.        // later
  619.        return;
  620.  
  621.        } // end if
  622.  
  623.     } // end for
  624.  
  625. } // end Fire_Plasma
  626.  
  627. ///////////////////////////////////////////////////////////
  628.  
  629. void Init_Rocks(void)
  630. {
  631. // this function initializes and loads all the rocks 
  632.  
  633. // load the rocks imagery 
  634. Load_Bitmap_File(&bitmap8bit, "ROCKS8.BMP");
  635.  
  636. // create the first bob
  637. Create_BOB(&rocks[0],0,0,96,96,20,
  638.             BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
  639.             DDSCAPS_SYSTEMMEMORY);
  640.  
  641. // load animation frames
  642. for (int frame=0; frame < 20; frame++)
  643.      Load_Frame_BOB(&rocks[0],&bitmap8bit,frame,frame%6,frame/6,BITMAP_EXTRACT_MODE_CELL);  
  644.  
  645. // set animation rate
  646. Set_Anim_Speed_BOB(&rocks[0],1+rand()%5);
  647. Set_Vel_BOB(&rocks[0], -4+rand()%8, 4+rand()%4);
  648. Set_Pos_BOB(&rocks[0], rand()%screen_width, rand()%screen_height);
  649.  
  650. // set size of rock
  651. rocks[0].varsI[0] = rand()%3;
  652. rocks[0].varsI[1] = rock_sizes[rocks[0].varsI[0]];
  653.  
  654. // set state to off
  655. rocks[0].state = ROCK_STATE_OFF;
  656.  
  657. for (int rock=1; rock<MAX_ROCKS; rock++)
  658.     {
  659.     memcpy(&rocks[rock], &rocks[0], sizeof(BOB));
  660.  
  661.     // set animation rate
  662.     Set_Anim_Speed_BOB(&rocks[rock],1+rand()%5);
  663.     
  664.     // set velocity
  665.     Set_Vel_BOB(&rocks[rock], -4+rand()%8, 4+rand()%4);
  666.     
  667.     // set position
  668.     Set_Pos_BOB(&rocks[rock], rand()%screen_width, rand()%screen_height);
  669.     
  670.     // set size of rock
  671.     rocks[rock].varsI[0] = rand()%3;
  672.     rocks[rock].varsI[1] = rock_sizes[rocks[rock].varsI[0]];
  673.     } // end for rock
  674.  
  675. // unload data infile
  676. Unload_Bitmap_File(&bitmap8bit);
  677.  
  678. } // end Init_Rocks
  679.  
  680. ///////////////////////////////////////////////////////////
  681.  
  682. void Delete_Rocks(void)
  683. {
  684. // this function simply deletes all memory and surfaces
  685. // related to the rocks pulses
  686.  
  687. for (int index=0; index<MAX_ROCKS; index++)
  688.     Destroy_BOB(&rocks[index]);
  689.  
  690. } // end Delete_Rocks
  691.  
  692. ///////////////////////////////////////////////////////////
  693.  
  694. void Move_Rocks(void)
  695. {
  696. // this function moves all the rocks pulses and checks for
  697. // collision with the rocks
  698.  
  699. for (int index=0; index<MAX_ROCKS; index++)
  700.     {
  701.     // test if rocks pulse is in flight
  702.     if (rocks[index].state == ROCK_STATE_ON)
  703.         {
  704.         // move the rock
  705.         Move_BOB(&rocks[index]);
  706.  
  707.         // add player motion in
  708.         if (moving_up)
  709.             rocks[index].y+=(rocks[index].yv*.5);
  710.  
  711.         // test if rock is off screen
  712.         if (rocks[index].y > screen_height)
  713.            {
  714.            // kill rock and put back on available list
  715.            rocks[index].state = ROCK_STATE_OFF;
  716.            } // end if
  717.         
  718.         } // end if
  719.  
  720.     } // end for index
  721.  
  722. // now test if it's time to add a new rock to the list
  723. if ((rand()%6)==3)
  724.    {
  725.    // scan for a rock to initialize
  726.    for (index=0; index<MAX_ROCKS; index++)
  727.        {
  728.        // is this rock available?
  729.        if (rocks[index].state == ROCK_STATE_OFF)
  730.           {
  731.           // set animation rate
  732.           Set_Anim_Speed_BOB(&rocks[index],1+rand()%5);
  733.     
  734.           // set velocity
  735.           Set_Vel_BOB(&rocks[index], -4+rand()%8, 4+rand()%12);
  736.     
  737.           // set position
  738.           Set_Pos_BOB(&rocks[index], rand()%screen_width, -128);
  739.     
  740.           // set size of rock
  741.           rocks[index].varsI[0] = rand()%3;
  742.           rocks[index].varsI[1] = rock_sizes[rocks[index].varsI[0]];
  743.           
  744.           // set strength of rock
  745.           switch(rocks[index].varsI[0])
  746.                 {
  747.                 case ROCK_LARGE:
  748.                      {
  749.                      // set hardness of rock
  750.                      rocks[index].varsI[2] = 100+rand()%100;
  751.                      } break;
  752.  
  753.                 case ROCK_MEDIUM:
  754.                      {
  755.                      // set hardness of rock
  756.                      rocks[index].varsI[2] = 40 + rand()%30;
  757.                      } break;     
  758.  
  759.                 case ROCK_SMALL:
  760.                      {
  761.                      // set hardness of rock
  762.                      rocks[index].varsI[2] = 10;
  763.                      } break;
  764.  
  765.                 default:break;
  766.  
  767.                 } // end switch
  768.  
  769.           // turn rock on
  770.           rocks[index].state = ROCK_STATE_ON;
  771.           
  772.           // later
  773.           return;
  774.  
  775.           } // end if
  776.  
  777.        } // end for index
  778.  
  779.    } // end if
  780.  
  781. } // end Move_Rocks
  782.  
  783. ///////////////////////////////////////////////////////////
  784.  
  785. void Start_Rock(int x, int y, int size,int xv, int yv)
  786. {
  787. // this functions starts a rock up with the sent parms, considering
  788. // there is one left
  789.  
  790. // scan for a rock to initialize
  791.    for (int index=0; index<MAX_ROCKS; index++)
  792.        {
  793.        // is this rock available?
  794.        if (rocks[index].state == ROCK_STATE_OFF)
  795.           {
  796.           // set animation rate
  797.           Set_Anim_Speed_BOB(&rocks[index],1+rand()%5);
  798.     
  799.           // set velocity
  800.           Set_Vel_BOB(&rocks[index], xv,yv);
  801.     
  802.           // set position
  803.           Set_Pos_BOB(&rocks[index], x,y);
  804.     
  805.           // set size of rock
  806.           rocks[index].varsI[0] = size;
  807.           rocks[index].varsI[1] = rock_sizes[rocks[index].varsI[0]];
  808.           
  809.           // set strength of rock
  810.           switch(rocks[index].varsI[0])
  811.                 {
  812.                 case ROCK_LARGE:
  813.                      {
  814.                      // set hardness of rock
  815.                      rocks[index].varsI[2] = 100+rand()%100;
  816.                      } break;
  817.  
  818.                 case ROCK_MEDIUM:
  819.                      {
  820.                      // set hardness of rock
  821.                      rocks[index].varsI[2] = 40 + rand()%30;
  822.                      } break;     
  823.  
  824.                 case ROCK_SMALL:
  825.                      {
  826.                      // set hardness of rock
  827.                      rocks[index].varsI[2] = 10;
  828.                      } break;
  829.  
  830.                 default:break;
  831.  
  832.                 } // end switch
  833.  
  834.           // turn rock on
  835.           rocks[index].state = ROCK_STATE_ON;
  836.           
  837.           // later
  838.           return;
  839.  
  840.           } // end if
  841.  
  842.        } // end for index
  843.  
  844. } // end Start_Rock
  845.  
  846. ///////////////////////////////////////////////////////////
  847.  
  848. void Draw_Rocks(void)
  849. {
  850. // this function draws all the rocks 
  851.  
  852. for (int index=0; index<MAX_ROCKS; index++)
  853.     {
  854.     // test if rocks pulse is in flight
  855.     if (rocks[index].state == ROCK_STATE_ON)
  856.         {
  857.  
  858.         if (rocks[index].varsI[0]!=ROCK_LARGE)
  859.             {
  860.             // draw the rock scaled
  861.             Draw_Scaled_BOB(&rocks[index],
  862.                             rocks[index].varsI[1],rocks[index].varsI[1],
  863.                             lpddsback);
  864.             }
  865.         else // draw normal
  866.            Draw_BOB(&rocks[index],lpddsback);
  867.          
  868.         // animate the pulse
  869.         Animate_BOB(&rocks[index]);
  870.  
  871.         } // end if
  872.  
  873.     } // end for index
  874.  
  875. } // end Draw_Rocks
  876.  
  877. ///////////////////////////////////////////////////////////
  878.  
  879. void Init_Bursts(void)
  880. {
  881. // this function initializes and loads all the bursts 
  882.  
  883. // load the bursts imagery 
  884. Load_Bitmap_File(&bitmap8bit, "EXPL8.BMP");
  885.  
  886. // create the first bob
  887. Create_BOB(&bursts[0],0,0,42,36,14,
  888.             BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
  889.             DDSCAPS_SYSTEMMEMORY);
  890.  
  891. // load animation frames
  892. for (int frame=0; frame < 14; frame++)
  893.      Load_Frame_BOB(&bursts[0],&bitmap8bit,frame,frame%6,frame/6,BITMAP_EXTRACT_MODE_CELL);  
  894.  
  895. // set animation rate
  896. Set_Anim_Speed_BOB(&bursts[0],1);
  897.  
  898. // set size of burst
  899. bursts[0].varsI[0] = bursts[0].width;
  900. bursts[0].varsI[1] = bursts[0].height;
  901.  
  902. // set state to off
  903. bursts[0].state = BURST_STATE_OFF;
  904.  
  905. for (int burst=1; burst<MAX_BURSTS; burst++)
  906.     {
  907.     memcpy(&bursts[burst], &bursts[0], sizeof(BOB));
  908.     } // end for burst
  909.  
  910. // unload data infile
  911. Unload_Bitmap_File(&bitmap8bit);
  912.  
  913. } // end Init_Bursts
  914.  
  915. ///////////////////////////////////////////////////////////
  916.  
  917. void Delete_Bursts(void)
  918. {
  919. // this function simply deletes all memory and surfaces
  920. // related to the bursts pulses
  921.  
  922. for (int index=0; index<MAX_BURSTS; index++)
  923.     Destroy_BOB(&bursts[index]);
  924.  
  925. } // end Delete_Bursts
  926.  
  927. ///////////////////////////////////////////////////////////
  928.  
  929. void Move_Bursts(void)
  930. {
  931. // this function moves all the bursts 
  932.  
  933. for (int index=0; index<MAX_BURSTS; index++)
  934.     {
  935.     // test if bursts pulse is in moving
  936.     if (bursts[index].state == BURST_STATE_ON)
  937.        {
  938.        // move the burst
  939.        Move_BOB(&bursts[index]);
  940.  
  941.         // add player motion in
  942.         if (moving_up)
  943.             bursts[index].y+=(bursts[index].yv*.5);
  944.  
  945.         // test if burst is off screen or done with animation
  946.         if ((bursts[index].y > screen_height) || bursts[index].curr_frame >= bursts[index].num_frames-1) 
  947.            {
  948.            // kill burst and put back on available list
  949.            bursts[index].state = BURST_STATE_OFF;
  950.            } // end if
  951.         
  952.         } // end if
  953.  
  954.     } // end for index
  955.  
  956. } // end Move_Bursts
  957.  
  958. ///////////////////////////////////////////////////////////
  959.  
  960. void Draw_Bursts(void)
  961. {
  962. // this function draws all the bursts 
  963. for (int index=0; index<MAX_BURSTS; index++)
  964.     {
  965.     // test if bursts pulse is in flight
  966.     if (bursts[index].state == BURST_STATE_ON)
  967.         {
  968.         if (bursts[index].varsI[0]!=bursts[index].width || 
  969.             bursts[index].varsI[1]!=bursts[index].height)
  970.             {
  971.             // draw the burst scaled
  972.             Draw_Scaled_BOB(&bursts[index],
  973.                             bursts[index].varsI[0],bursts[index].varsI[1],
  974.                             lpddsback);
  975.             }
  976.         else // draw normal
  977.            Draw_BOB(&bursts[index],lpddsback);
  978.          
  979.         // animate the explosion
  980.         Animate_BOB(&bursts[index]);
  981.  
  982.         } // end if
  983.  
  984.     } // end for index
  985.  
  986. } // end Draw_Bursts
  987.  
  988. ///////////////////////////////////////////////////////////
  989.  
  990. void Start_Burst(int x, int y, int width, int height, int xv,int yv)
  991. {
  992. // this function starts a burst up
  993.  
  994. // now test if it's time to add a new burst to the list
  995.  
  996. // scan for a burst to initialize
  997. for (int index=0; index<MAX_BURSTS; index++)
  998.     {
  999.     // is this burst available?
  1000.     if (bursts[index].state == BURST_STATE_OFF)
  1001.        {
  1002.        // set animation rate
  1003.        Set_Anim_Speed_BOB(&bursts[index],1);
  1004.        bursts[index].curr_frame = 0;
  1005.     
  1006.        // set velocity
  1007.        Set_Vel_BOB(&bursts[index], xv,yv);
  1008.     
  1009.        // set position
  1010.        Set_Pos_BOB(&bursts[index], x,y);
  1011.     
  1012.        // set size of burst
  1013.        bursts[index].varsI[0] = width;
  1014.        bursts[index].varsI[1] = height;
  1015.  
  1016.        // turn burst on
  1017.        bursts[index].state = BURST_STATE_ON;
  1018.           
  1019.        // later
  1020.        return;
  1021.  
  1022.        } // end if
  1023.  
  1024.     } // end for index
  1025.  
  1026. } // end Start_Burst
  1027.  
  1028. ///////////////////////////////////////////////////////////
  1029.  
  1030. void Draw_Info(void)
  1031. {
  1032. // this function draws all the information at the top of the screen
  1033.  
  1034. char score[16]; // hold score
  1035.  
  1036. // build up scrore string
  1037. sprintf(score,"0000000%d",player_score);
  1038.  
  1039. // build up final string
  1040. sprintf(buffer,"SCORE %s",&score[strlen(score)-8]);
  1041. Draw_Text_GDI(buffer,10,10,RGB(0,255,0),lpddsback);
  1042.  
  1043. // draw damage
  1044. sprintf(buffer,"DAMAGE %d%%",player_damage);
  1045. Draw_Text_GDI(buffer,320-8*strlen(buffer),10,RGB(0,255,0),lpddsback);
  1046.  
  1047. // draw ships
  1048. sprintf(buffer,"SHIPS %d",player_ships);
  1049. Draw_Text_GDI(buffer,500,10,RGB(0,255,0),lpddsback);
  1050.  
  1051. } // end Draw_Info
  1052.  
  1053. ///////////////////////////////////////////////////////////
  1054.  
  1055. void Do_Intro(void)
  1056. {
  1057. // the worlds simples intro
  1058.  
  1059. int shade; // used as looping var
  1060.  
  1061. for (shade=0; shade < 256; shade++)
  1062.     {
  1063.     // draw text in shades
  1064.     Draw_Text_GDI("DUMB GAMES INC.",320-4*strlen("DUMB GAMES INC."),200,
  1065.                    RGB(shade,shade,shade),lpddsprimary);
  1066.     Sleep(2);
  1067.  
  1068.     // is user trying to bail
  1069.     if (KEY_DOWN(VK_ESCAPE))
  1070.         return;
  1071.  
  1072.     } // end for shade
  1073.  
  1074. Sleep(2000);
  1075.  
  1076. for (shade=255; shade >=0; shade--)
  1077.     {
  1078.     // draw text in shades
  1079.     Draw_Text_GDI("DUMB GAMES INC.",320-4*strlen("DUMB GAMES INC."),200,
  1080.                    RGB(0,shade,0),lpddsprimary);
  1081.     Sleep(2);
  1082.  
  1083.      // is user trying to bail
  1084.     if (KEY_DOWN(VK_ESCAPE))
  1085.         return;
  1086.     
  1087.     } // end for shade
  1088.  
  1089. Sleep(1000);
  1090.  
  1091. for (shade=0; shade < 256; shade++)
  1092.     {
  1093.     // draw text in shades
  1094.     Draw_Text_GDI("PRESENTS...",320-4*strlen("PRESENTS..."),200,
  1095.                    RGB(shade,shade,shade),lpddsprimary);
  1096.     Sleep(2);
  1097.     
  1098.     // is user trying to bail
  1099.     if (KEY_DOWN(VK_ESCAPE))
  1100.         return;
  1101.  
  1102.     } // end for shade
  1103.  
  1104. Sleep(2000);
  1105.  
  1106. for (shade=255; shade >=0; shade--)
  1107.     {
  1108.     // draw text in shades
  1109.     Draw_Text_GDI("PRESENTS...",320-4*strlen("PRESENTS..."),200,
  1110.                    RGB(0,shade,0),lpddsprimary);
  1111.     Sleep(2);
  1112.     
  1113.     // is user trying to bail
  1114.     if (KEY_DOWN(VK_ESCAPE))
  1115.         return;
  1116.  
  1117.     } // end for shade
  1118.  
  1119. Sleep(2000);
  1120.  
  1121. for (shade=0; shade < 256; shade++)
  1122.     {
  1123.     // draw text in shades
  1124.     Draw_Text_GDI("S T A R   F E R R E T !",320-4*strlen("S T A R   F E R R E T !"),200,
  1125.                    RGB(shade,shade,shade),lpddsprimary);
  1126.     Sleep(2);
  1127.  
  1128.     // is user trying to bail
  1129.     if (KEY_DOWN(VK_ESCAPE))
  1130.         return;    
  1131.  
  1132.     } // end for shade
  1133.  
  1134. Sleep(3000);
  1135.  
  1136. for (shade=255; shade >=0; shade--)
  1137.     {
  1138.     // draw text in shades
  1139.     Draw_Text_GDI("S T A R   F E R R E T !",320-4*strlen("S T A R   F E R R E T !"),200,
  1140.                    RGB(0,shade,0),lpddsprimary);
  1141.     Sleep(2);
  1142.   
  1143.     // is user trying to bail
  1144.     if (KEY_DOWN(VK_ESCAPE))
  1145.         return;  
  1146.  
  1147.     } // end for shade
  1148.  
  1149. } // end Do_Intro
  1150.  
  1151.  
  1152. // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
  1153.  
  1154. int Game_Init(void *parms)
  1155. {
  1156. // this function is where you do all the initialization 
  1157. // for your game
  1158.  
  1159. int index;         // looping var
  1160. char filename[80]; // used to build up files names
  1161.  
  1162. // set screen stuff
  1163. screen_width = 640;
  1164. screen_height = 480;
  1165. screen_bpp = 8;
  1166.  
  1167. // initialize directdraw
  1168. DD_Init(screen_width, screen_height, screen_bpp);
  1169.  
  1170. // load the starferret ship
  1171. Load_Bitmap_File(&bitmap8bit, "STAR8.BMP");
  1172.  
  1173. // set the palette to background image palette
  1174. Set_Palette(bitmap8bit.palette);
  1175.  
  1176. // now create the starferret
  1177. Create_BOB(&starferret,0,0,56,38,3,
  1178.            BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
  1179.            DDSCAPS_SYSTEMMEMORY);
  1180.  
  1181. // load star ferret frames
  1182. for (index=0; index<3; index++)
  1183.      Load_Frame_BOB(&starferret,&bitmap8bit,index,index,0,BITMAP_EXTRACT_MODE_CELL);  
  1184.  
  1185. // set position
  1186. Set_Pos_BOB(&starferret,320,350);
  1187.  
  1188. // set animation speed
  1189. Set_Anim_Speed_BOB(&starferret,1);
  1190.  
  1191. // unload data infile
  1192. Unload_Bitmap_File(&bitmap8bit);
  1193.  
  1194. // initialize the plasma pulses
  1195. Init_Plasma();
  1196.  
  1197. // initialize all the stars
  1198. Init_Stars();
  1199.  
  1200. // init rocks
  1201. Init_Rocks();
  1202.  
  1203. // init all the explosions
  1204. Init_Bursts();
  1205.  
  1206. #if 0
  1207. // load the background
  1208. Load_Bitmap_File(&bitmap8bit, "MUSH.BMP");
  1209.  
  1210. // set the palette to background image palette
  1211. Set_Palette(bitmap8bit.palette);
  1212.  
  1213. // load in the four frames of the mushroom
  1214. for (index=0; index<4; index++)
  1215.     {
  1216.     // create mushroom bitmaps
  1217.     Create_Bitmap(&mushrooms[index],0,0,32,32);
  1218.     Load_Image_Bitmap(&mushrooms[index],&bitmap8bit,index,0,BITMAP_EXTRACT_MODE_CELL);  
  1219.     } // end for index
  1220.  
  1221. // now create the bug blaster bob
  1222. Create_BOB(&blaster,0,0,32,32,3,
  1223.            BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM | BOB_ATTR_ANIM_ONE_SHOT,
  1224.            DDSCAPS_SYSTEMMEMORY);
  1225.  
  1226. // load in the four frames of the mushroom
  1227. for (index=0; index<3; index++)
  1228.      Load_Frame_BOB(&blaster,&bitmap8bit,index,index,1,BITMAP_EXTRACT_MODE_CELL);  
  1229.  
  1230. // unload the bitmap file
  1231. Unload_Bitmap_File(&bitmap8bit);
  1232.  
  1233. // set the animation sequences for bug blaster
  1234. Load_Animation_BOB(&blaster,0,5,blaster_anim);
  1235.  
  1236. // set up stating state of bug blaster
  1237. Set_Pos_BOB(&blaster,320, 200);
  1238. Set_Anim_Speed_BOB(&blaster,1);
  1239.  
  1240. #endif
  1241.  
  1242. // set clipping rectangle to screen extents so objects dont
  1243. // mess up at edges
  1244. RECT screen_rect = {0,0,screen_width,screen_height};
  1245. lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);
  1246.  
  1247. // seed random number generate
  1248. srand(Start_Clock());
  1249.  
  1250. // hide the mouse
  1251. ShowCursor(FALSE);
  1252.  
  1253. // do the introdcution
  1254. Do_Intro();
  1255.  
  1256. // return success
  1257. return(1);
  1258.  
  1259. } // end Game_Init
  1260.  
  1261. ///////////////////////////////////////////////////////////
  1262.  
  1263. int Game_Shutdown(void *parms)
  1264. {
  1265. // this function is where you shutdown your game and
  1266. // release all resources that you allocated
  1267.  
  1268. // delete all the explosions
  1269. Delete_Bursts();
  1270.     
  1271. // delete the player
  1272. Destroy_BOB(&starferret);
  1273.  
  1274. // the delete all the rocks
  1275. Delete_Rocks();
  1276.  
  1277. // delete all the plasma pulses
  1278. Delete_Plasma();
  1279.  
  1280. // shutdonw directdraw
  1281. DD_Shutdown();
  1282.  
  1283. // return success
  1284. return(1);
  1285. } // end Game_Shutdown
  1286.  
  1287. ///////////////////////////////////////////////////////////
  1288.  
  1289. int Game_Main(void *parms)
  1290. {
  1291. // this is the workhorse of your game it will be called
  1292. // continuously in real-time this is like main() in C
  1293. // all the calls for you game go here!
  1294.  
  1295. static int ready_counter = 0, // used to draw a little "get ready"
  1296.            ready_state   = 0;
  1297.  
  1298. int  index;             // looping var
  1299. int  dx,dy;             // general deltas used in collision detection
  1300.  
  1301. // check of user is trying to exit
  1302. if (KEY_DOWN(VK_ESCAPE) && ready_state)
  1303.     PostMessage(main_window_handle, WM_DESTROY,0,0);
  1304.  
  1305. // start the timing clock
  1306. Start_Clock();
  1307.  
  1308. // reset upward motion flag
  1309. moving_up = 0;
  1310.  
  1311. // clear the drawing surface
  1312. DD_Fill_Surface(lpddsback, 0);
  1313.  
  1314.  
  1315. // only process player if alive
  1316. if (player_state == PLAYER_STATE_ALIVE)
  1317. {
  1318.  
  1319. // test if player is moving
  1320. if (KEY_DOWN(VK_RIGHT))
  1321.     {
  1322.     // move player to right
  1323.     starferret.x+=8;
  1324.  
  1325.     } // end if
  1326. else
  1327. if (KEY_DOWN(VK_LEFT))
  1328.     {
  1329.     // move player to left
  1330.     starferret.x-=8;
  1331.  
  1332.     } // end if
  1333.  
  1334. // vertical/speed motion
  1335. if (KEY_DOWN(VK_UP))
  1336.     {
  1337.     // move player up
  1338.     starferret.y-=4;
  1339.  
  1340.     // set upward motion flag
  1341.     moving_up = 1;
  1342.  
  1343.     } // end if
  1344. else
  1345. if (KEY_DOWN(VK_DOWN))
  1346.     {
  1347.     // move player to left
  1348.     starferret.y+=2;
  1349.  
  1350.     } // end if
  1351.  
  1352. // test if player is firing
  1353. if (KEY_DOWN(VK_CONTROL) || KEY_DOWN(VK_SPACE))
  1354.    Fire_Plasma(starferret.x+28-8,starferret.y-8,16);
  1355.  
  1356. // apply friction, or downward motion
  1357. starferret.y++;
  1358.  
  1359. // do bounds check
  1360.  
  1361. // first vertical axis
  1362. if (starferret.y < MIN_STARFERRET_Y)
  1363.    starferret.y = MIN_STARFERRET_Y;
  1364. else
  1365. if (starferret.y > MAX_STARFERRET_Y)
  1366.    starferret.y = MAX_STARFERRET_Y;
  1367.  
  1368. // now horizontal axis
  1369. if (starferret.x < 0)
  1370.    starferret.x = 0;
  1371. else
  1372. if (starferret.x > (screen_width - starferret.width))
  1373.    starferret.x = (screen_width - starferret.width);
  1374.  
  1375. // animate player
  1376. Animate_BOB(&starferret);
  1377.  
  1378. } // end if player alive
  1379. else
  1380. if (player_state = PLAYER_STATE_DYING)
  1381.    { 
  1382.    // player is dying
  1383.  
  1384.    } // end if
  1385. else
  1386. if (player_state = PLAYER_STATE_DEAD)
  1387.    {
  1388.    // player is dead
  1389.  
  1390.    } // end if
  1391.  
  1392. // move the plasma
  1393. Move_Plasma();
  1394.  
  1395. // move the asteroids
  1396. Move_Rocks();
  1397.  
  1398. // move the stars
  1399. Move_Stars();
  1400.  
  1401. // move the explosions
  1402. Move_Bursts();
  1403.  
  1404. // draw the tocks
  1405. Draw_Rocks();
  1406.  
  1407. // draw the plasma
  1408. Draw_Plasma();
  1409.  
  1410. // draw the player if alive
  1411. if (player_state == PLAYER_STATE_ALIVE)
  1412.     {
  1413.     Draw_BOB(&starferret,lpddsback);
  1414.     } // end if
  1415.  
  1416. // draw the stars
  1417. Draw_Stars();
  1418.  
  1419. // draw explosions last
  1420. Draw_Bursts();
  1421.  
  1422. // draw the score and ships left
  1423. Draw_Info();
  1424.  
  1425. // draw get ready?
  1426. if (!ready_state)
  1427.    {
  1428.    // draw text
  1429.    Draw_Text_GDI("GET READY!",320-8*strlen("GET READY!")/2, 200,RGB(0,0,255),lpddsback);
  1430.  
  1431.    // increment counter
  1432.    if (++ready_counter > 60)
  1433.       {
  1434.       // set state to ready
  1435.       ready_state = 1;
  1436.       ready_counter = 0;
  1437.       } // end if
  1438.  
  1439.    } // end if
  1440.  
  1441. // flip the surfaces
  1442. DD_Flip();
  1443.  
  1444. // sync to 30ish fps
  1445. Wait_Clock(30);
  1446.  
  1447. // return success
  1448. return(1);
  1449.  
  1450. } // end Game_Main
  1451.  
  1452. //////////////////////////////////////////////////////////