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

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