home *** CD-ROM | disk | FTP | other *** search
/ Black Art of 3D Game Programming / Black_Art_of_3D_Game_Programming.iso / source / borland / chap_9 / blazem2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-26  |  56.5 KB  |  2,258 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <io.h>
  5. #include <conio.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <fcntl.h>
  11. #include <memory.h>
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include <string.h>
  15.  
  16. // include all of our stuff
  17.  
  18. #include "black3.h"
  19. #include "black4.h"
  20. #include "black5.h"
  21. #include "black6.h"
  22. #include "black8.h"
  23. #include "black9.h"
  24.  
  25. #include "blazem0.h"
  26.  
  27.  
  28. ////////////////////////////////////////////////////////////////////////////////
  29.  
  30. void Shield_Control(int ship,int on)
  31. {
  32. // this function is used to activate or de-activate the shields of the player
  33. // or remote ship
  34.  
  35. if (ship==THE_PLAYER)
  36.    {
  37.  
  38.    // which ship does player have?
  39.  
  40.    if (players_ship_type==GRYFON_SHIP)
  41.       {
  42.       // activating or de-activating shields?
  43.  
  44.       if (on)
  45.          players_shield_color = primary_blue;
  46.       else
  47.          players_shield_color = primary_black;
  48.  
  49.       } // end if gryfon
  50.    else
  51.       {
  52.       // activating or de-activating shields?
  53.  
  54.       if (on)
  55.          players_shield_color = primary_red;
  56.       else
  57.          players_shield_color = primary_black;
  58.  
  59.        } // else raptor
  60.  
  61.    // set the color
  62.  
  63.    Write_Color_Reg(PLAYERS_SHIELD_REG,(RGB_color_ptr)&players_shield_color);
  64.  
  65.    // record shield change
  66.  
  67.    players_shields = on;
  68.  
  69.    } // end if players ship
  70. else
  71.    {
  72.    // must be remote ship
  73.  
  74.    // which ship does remote have?
  75.  
  76.    if (remotes_ship_type==GRYFON_SHIP)
  77.       {
  78.       // activating or de-activating shields?
  79.  
  80.       if (on)
  81.          remotes_shield_color = primary_blue;
  82.       else
  83.          remotes_shield_color = primary_black;
  84.       } // end if gryfon
  85.    else
  86.       {
  87.       // activating or de-activating shields?
  88.  
  89.       if (on)
  90.          remotes_shield_color = primary_red;
  91.       else
  92.          remotes_shield_color = primary_black;
  93.        } // else raptor
  94.  
  95.    // set the color
  96.  
  97.    Write_Color_Reg(REMOTES_SHIELD_REG,(RGB_color_ptr)&remotes_shield_color);
  98.  
  99.    // record shield change
  100.  
  101.    remotes_shields = on;
  102.  
  103.    } // end must be remote
  104.  
  105. } // end Shield_Control
  106.  
  107. ///////////////////////////////////////////////////////////////////////////////
  108.  
  109. void Erase_Missiles(void)
  110. {
  111. // this function erases all the missiles
  112.  
  113. int index; // lopping variable
  114.  
  115. for (index=0; index<NUM_MISSILES; index++)
  116.     {
  117.     // is this missile active and visible
  118.  
  119.     if (missiles[index].state == MISS_ACTIVE && missiles[index].visible)
  120.        {
  121.        Write_Pixel_DB(missiles[index].sx,missiles[index].sy,missiles[index].back_color);
  122.        } // end if alive
  123.  
  124.     } // end for index
  125.  
  126. } // end Erase_Missiles
  127.  
  128. /////////////////////////////////////////////////////////////////////////////
  129.  
  130. void Under_Missiles(void)
  131. {
  132. // this function scans the background under the missiles
  133.  
  134. int index,       // looping varible
  135.     px_window,   // the starting postion of the players window
  136.     py_window,
  137.     mx,my;       // local aliases for speed
  138.  
  139. // compute starting position of players window so screen mapping can be done
  140.  
  141. px_window = players_x - 160 + 11;
  142. py_window = players_y - 100 + 9;
  143.  
  144. for (index=0; index<NUM_MISSILES; index++)
  145.     {
  146.     // is this missile active
  147.  
  148.     if (missiles[index].state == MISS_ACTIVE)
  149.        {
  150.        // remap to screen coordinates
  151.  
  152.        mx=missiles[index].sx = (missiles[index].x - px_window);
  153.        my=missiles[index].sy = (missiles[index].y - py_window);
  154.  
  155.        // test if missile is visible on screen?
  156.  
  157.        if (mx>=320 || mx <0 || my>=200  || my<0)
  158.           {
  159.  
  160.           // this missile is invisible and has been clipped
  161.  
  162.           missiles[index].visible = 0;
  163.  
  164.           // process next missile
  165.  
  166.           continue;
  167.  
  168.           } // end visibility test
  169.  
  170.        // scan under missile
  171.  
  172.        missiles[index].back_color =
  173.                       Read_Pixel_DB(mx,my);
  174.  
  175.        // set visibility flag
  176.  
  177.        missiles[index].visible = 1;
  178.  
  179.        } // end if alive
  180.  
  181.     } // end for index
  182.  
  183. } // end Under_Missiles
  184.  
  185. /////////////////////////////////////////////////////////////////////////////
  186.  
  187. void Draw_Missiles(void)
  188. {
  189. // this function draws all the missiles
  190. int index; // looping variable
  191.  
  192. for (index=0; index<NUM_MISSILES; index++)
  193.     {
  194.     // is this missile active and visible
  195.  
  196.     if (missiles[index].state == MISS_ACTIVE && missiles[index].visible)
  197.        {
  198.  
  199.        Write_Pixel_DB(missiles[index].sx,missiles[index].sy,missiles[index].color);
  200.  
  201.        } // end if alive
  202.  
  203.     } // end for index
  204.  
  205. } // end Draw_Missiles
  206.  
  207. /////////////////////////////////////////////////////////////////////////////
  208.  
  209. void Init_Missiles(void)
  210. {
  211. // this function resets and intializes all missiles
  212. int index; // looping variable
  213.  
  214. for (index=0; index<NUM_MISSILES; index++)
  215.     missiles[index].state = MISS_INACTIVE;
  216.  
  217. } // Init_Missiles
  218.  
  219. ////////////////////////////////////////////////////////////////////////////
  220.  
  221. void Move_Missiles(void)
  222. {
  223. // this function move all the missiles and performs collision detection
  224.  
  225. int index,              // looping variables
  226.     a_index,
  227.     miss_x,miss_y;      // speed aliases
  228.  
  229. // process each missile
  230.  
  231. for (index=0; index<NUM_MISSILES; index++)
  232.     {
  233.  
  234.     // is missile active
  235.  
  236.     if (missiles[index].state == MISS_ACTIVE)
  237.        {
  238.        // move the missile
  239.  
  240.        miss_x = (missiles[index].x += missiles[index].xv);
  241.        miss_y = (missiles[index].y += missiles[index].yv);
  242.  
  243.        // test if a missile has hit an asteroid
  244.  
  245.        for (a_index=0; a_index<NUM_ASTEROIDS; a_index++)
  246.            {
  247.            // test if asteroid is active
  248.  
  249.            if (asteroids[a_index].rock.state==ASTEROID_ACTIVE)
  250.               {
  251.               // test for collision
  252.  
  253.               if (miss_x >= asteroids[a_index].x &&
  254.                   miss_y >= asteroids[a_index].y &&
  255.                   miss_x <= asteroids[a_index].x + asteroids[a_index].rock.width &&
  256.                   miss_y <= asteroids[a_index].y + asteroids[a_index].rock.height)
  257.                   {
  258.                   // kill the asteroid and the missile
  259.  
  260.                   asteroids[a_index].rock.state = ASTEROID_INACTIVE;
  261.  
  262.                   missiles[index].state = MISS_INACTIVE;
  263.  
  264.                   // what kind of asteroid did we have?
  265.  
  266.                   switch(asteroids[a_index].type)
  267.                         {
  268.  
  269.                         case ASTEROID_LARGE:
  270.                              {
  271.                              // start an explosion at proper place
  272.  
  273.                              Start_Explosion(asteroids[a_index].x,
  274.                                              asteroids[a_index].y,2);
  275.  
  276.                              // start one medium and one small asteroid
  277.                              //  (if possible)
  278.  
  279.                              Start_Asteroid(asteroids[a_index].x,
  280.                                             asteroids[a_index].y,
  281.                                             ASTEROID_MEDIUM);
  282.  
  283.                              Start_Asteroid(asteroids[a_index].x+ASTEROID_LARGE_WIDTH/2,
  284.                                             asteroids[a_index].y+ASTEROID_LARGE_HEIGHT/2,
  285.                                             ASTEROID_SMALL);
  286.  
  287.                              if (missiles[index].type==PLAYER_MISSILE)
  288.                                 players_score+=100;
  289.                              else
  290.                                 remotes_score+=100;
  291.  
  292.  
  293.                              } break;
  294.  
  295.                         case ASTEROID_MEDIUM:
  296.                              {
  297.                              // start an explosion at proper place
  298.  
  299.                              Start_Explosion(asteroids[a_index].x-2,
  300.                                              asteroids[a_index].y-2,2);
  301.  
  302.  
  303.                              // start two small asteroids (if possible)
  304.  
  305.                              Start_Asteroid(asteroids[a_index].x,
  306.                                             asteroids[a_index].y,
  307.                                             ASTEROID_SMALL);
  308.  
  309.                              Start_Asteroid(asteroids[a_index].x+ASTEROID_MEDIUM_WIDTH/2,
  310.                                             asteroids[a_index].y+ASTEROID_MEDIUM_HEIGHT/2,
  311.                                             ASTEROID_SMALL);
  312.  
  313.                              if (missiles[index].type==PLAYER_MISSILE)
  314.                                 players_score+=50;
  315.                              else
  316.                                 remotes_score+=50;
  317.  
  318.                              } break;
  319.  
  320.                         case ASTEROID_SMALL:
  321.                              {
  322.                              // start an explosion at proper place
  323.  
  324.                              Start_Explosion(asteroids[a_index].x-8,
  325.                                              asteroids[a_index].y-8,2);
  326.  
  327.                              // start a randomly positioned asteroid of any size
  328.                              // at the worm hole
  329.  
  330.                              Start_Asteroid(WORMHOLE_X,WORMHOLE_Y,rand()%3);
  331.  
  332.                              if (missiles[index].type==PLAYER_MISSILE)
  333.                                 players_score+=25;
  334.                              else
  335.                                 remotes_score+=25;
  336.  
  337.                              } break;
  338.  
  339.                         default:break;
  340.  
  341.                         } // end switch
  342.  
  343.                   // break inner loop
  344.  
  345.                   break;
  346.  
  347.                   } // end if collision
  348.  
  349.               } // end if active
  350.  
  351.            } // end for a_index
  352.  
  353.        // test if missiles hit local player
  354.  
  355.        if (linked && players_state==ALIVE && missiles[index].type==REMOTE_MISSILE)
  356.        {
  357.        if (miss_x>players_x && miss_x < players_x+SHIP_WIDTH &&
  358.            miss_y>players_y && miss_y < players_y+SHIP_HEIGHT)
  359.            {
  360.  
  361.            // de-activate missile
  362.  
  363.            missiles[index].state = MISS_INACTIVE;
  364.  
  365.            // were shields up?
  366.  
  367.            if (players_shields)
  368.               {
  369.               // start explosion
  370.               Start_Explosion(players_x,players_y,2);
  371.               } // end if shields up
  372.            else
  373.               { // say bye bye!
  374.  
  375.               Start_Explosion(players_x,players_y,2);
  376.               Start_Nova(players_x+SHIP_WIDTH/2,players_y+SHIP_HEIGHT/2);
  377.  
  378.               // start local player death sequence
  379.  
  380.               Start_Players_Death();
  381.  
  382.               } // end if else
  383.  
  384.            } // end if local player hit
  385.  
  386.        } // end if remote fired this missile
  387.  
  388.        // test if missile has hit remote player
  389.  
  390.        if (linked && remotes_state==ALIVE && missiles[index].type==PLAYER_MISSILE)
  391.           {
  392.           if (miss_x>remotes_x && miss_x < remotes_x+SHIP_WIDTH &&
  393.               miss_y>remotes_y && miss_y < remotes_y+SHIP_HEIGHT)
  394.               {
  395.  
  396.               // de-activate missile
  397.  
  398.               missiles[index].state = MISS_INACTIVE;
  399.  
  400.               // were shields up?
  401.  
  402.               if (remotes_shields)
  403.                  {
  404.                  // start explosion
  405.                  Start_Explosion(remotes_x,remotes_y,2);
  406.                  } // end if shields up
  407.               else
  408.                  { // say bye bye!
  409.  
  410.                  Start_Explosion(remotes_x,remotes_y,2);
  411.                  Start_Nova(remotes_x+SHIP_WIDTH/2,remotes_y+SHIP_HEIGHT/2);
  412.  
  413.                  // start remote death sequence
  414.  
  415.                  Start_Remotes_Death();
  416.  
  417.                  } // end if else
  418.  
  419.               } // end if remote player hit
  420.  
  421.           } // end if remote is linked
  422.  
  423.        // test if it's hit the edge of the screen or a wall
  424.  
  425.        if ( (miss_x >= UNIVERSE_WIDTH+UNIVERSE_BORDER)  ||
  426.             (miss_x < -UNIVERSE_BORDER)                 ||
  427.             (miss_y >  UNIVERSE_HEIGHT+UNIVERSE_BORDER) ||
  428.             (miss_y < -UNIVERSE_BORDER)                 ||
  429.             (--missiles[index].lifetime < 0))
  430.           {
  431.           // de-activate the missile
  432.  
  433.           missiles[index].state = MISS_INACTIVE;
  434.  
  435.           } // end if off edge of screen
  436.  
  437.        // test if this missiles has been terminated in some way, if so update
  438.        // the active missile variable for the player or remote
  439.  
  440.        if (missiles[index].state == MISS_INACTIVE)
  441.           {
  442.           // update number of active missiles
  443.  
  444.           if (missiles[index].type == PLAYER_MISSILE)
  445.              players_active_missiles--;
  446.           else
  447.           if (missiles[index].type == REMOTE_MISSILE)
  448.              remotes_active_missiles--;
  449.  
  450.           } // end if this missiles was terminated on this cycle
  451.  
  452.        } // end if alive
  453.  
  454.     } // end for index
  455.  
  456. } // end Move_Missiles
  457.  
  458. /////////////////////////////////////////////////////////////////////////////
  459.  
  460. int Start_Missile(int x,int y,int xv,int yv, int color,int type)
  461. {
  462. // this function start a photon missile with the given position and speed
  463.  
  464. int index; // looping variable
  465.  
  466. // scan for an inactive
  467.  
  468. for (index=0; index<NUM_MISSILES; index++)
  469.     {
  470.     // is this missile free?
  471.  
  472.     if (missiles[index].state == MISS_INACTIVE)
  473.        {
  474.        // set up fields
  475.  
  476.        missiles[index].state       = MISS_ACTIVE;
  477.        missiles[index].x           = x;
  478.        missiles[index].y           = y;
  479.        missiles[index].sx          = 0;
  480.        missiles[index].sy          = 0;
  481.        missiles[index].counter     = 0;
  482.        missiles[index].threshold   = 0;
  483.        missiles[index].xv          = xv;
  484.        missiles[index].yv          = yv;
  485.        missiles[index].color       = color;
  486.        missiles[index].back_color  = 0;
  487.        missiles[index].type        = type;
  488.        missiles[index].visible     = 0;
  489.        missiles[index].lifetime    = 30 + rand()%10;
  490.  
  491.        // make some sound
  492.  
  493.        Digital_FX_Play(BLZLAS_VOC,2);
  494.  
  495.        // return success
  496.  
  497.        return(1);
  498.  
  499.        } // end if found a good one
  500.  
  501.     } // end for index
  502.  
  503. // must not have found one
  504.  
  505. return(0);
  506.  
  507. } // end Start_Missile
  508.  
  509. /////////////////////////////////////////////////////////////////////////////
  510.  
  511. void Start_Players_Death(void)
  512. {
  513. // this function starts the players death sequence
  514.  
  515. players_xv                  = 0;
  516. players_yv                  = 0;
  517. players_engine              = 0;
  518. players_flame_count         = 0;
  519. players_gravity             = 0;
  520. players_shields             = 0;
  521. players_shield_time         = 0;
  522. players_cloak               = -1;
  523. players_state               = DYING;
  524. players_death_count         = 48;
  525.  
  526.  
  527. debounce_hud                = 0;
  528. debounce_scan               = 0;
  529. debounce_cloak              = 0;
  530. debounce_thrust             = 0;
  531. debounce_fire               = 0;
  532. debounce_shields            = 0;
  533.  
  534. } // end Start_Players_Death
  535.  
  536. //////////////////////////////////////////////////////////////////////////////
  537.  
  538. void Reset_Player(void)
  539. {
  540. // this function resets the player to his starting position
  541.  
  542. players_last_x              = game_start_x[master];
  543. players_last_y              = game_start_y[master];
  544. players_x                   = game_start_x[master];
  545. players_y                   = game_start_y[master];
  546. players_state               = ALIVE;
  547.  
  548. } // end Reset_Player
  549.  
  550. //////////////////////////////////////////////////////////////////////////////
  551.  
  552. void Reset_Remote(void)
  553. {
  554. // this function resets the remote to his starting position
  555.  
  556. remotes_last_x              = game_start_x[slave];
  557. remotes_last_y              = game_start_y[slave];
  558. remotes_x                   = game_start_x[slave];
  559. remotes_y                   = game_start_y[slave];
  560. remotes_state               = ALIVE;
  561.  
  562. } // end Reset_Remote
  563.  
  564. //////////////////////////////////////////////////////////////////////////////
  565.  
  566. void Start_Remotes_Death(void)
  567. {
  568. // this function starts the remotes death sequence
  569.  
  570. remotes_xv                  = 0;
  571. remotes_yv                  = 0;
  572. remotes_engine              = 0;
  573. remotes_flame_count         = 0;
  574. remotes_gravity             = 0;
  575. remotes_shields             = 0;
  576. remotes_shield_time         = 0;
  577. remotes_cloak               = -1;
  578. remotes_state               = DYING;
  579. remotes_death_count         = 48;
  580.  
  581. } // end Start_Remotes_Death
  582.  
  583. //////////////////////////////////////////////////////////////////////////////
  584.  
  585. void Reset_System(void)
  586. {
  587. // this function resets everything so the game can be ran again
  588. // I hope I didn't leave anything out?
  589.  
  590. // player variables
  591.  
  592. winner = WINNER_NONE;      // the winner of the game
  593.  
  594. players_last_x              = game_start_x[master];
  595. players_last_y              = game_start_y[master];
  596. players_x                   = game_start_x[master];
  597. players_y                   = game_start_y[master];
  598. players_dx                  = 0;
  599. players_dy                  = 0;
  600. players_xv                  = 0;
  601. players_yv                  = 0;
  602. players_engine              = 0;
  603. players_stability           = 8;
  604. players_flame_count         = 0;
  605. players_flame_time          = 1;
  606. players_ship.curr_frame     = 0;
  607. players_gravity             = 0;
  608. players_shields             = 0;
  609. players_shield_time         = 0;
  610. players_cloak               = -1;
  611. players_heads               = -1;
  612. players_comm                = -1;
  613. players_scanner             = -1;
  614. players_num_ships           = 3;
  615. players_shield_strength     = 22000;
  616. players_energy              = 22000;
  617. players_score               = 0;
  618. players_active_missiles     = 0;
  619. players_state               = ALIVE;
  620. players_death_count         = 0;
  621.  
  622. debounce_hud                = 0;
  623. debounce_scan               = 0;
  624. debounce_cloak              = 0;
  625. debounce_thrust             = 0;
  626. debounce_fire               = 0;
  627. debounce_shields            = 0;
  628.  
  629. refresh_heads = 0;
  630.  
  631. // remote variables
  632.  
  633. remotes_last_x          = game_start_x[slave];
  634. remotes_last_y          = game_start_y[slave];
  635. remotes_x               = game_start_x[slave];
  636. remotes_y               = game_start_y[slave];
  637. remotes_dx              = 0;
  638. remotes_dy              = 0;
  639. remotes_xv              = 0;
  640. remotes_yv              = 0;
  641. remotes_engine          = 0;
  642. remotes_stability       = 8;
  643. remotes_flame_count     = 0;
  644. remotes_flame_time      = 1;
  645. remotes_gravity         = 0;
  646. remotes_shields         = 0;
  647. remotes_shield_time     = 0;
  648. remotes_cloak           = -1;
  649. remotes_heads           = -1;
  650. remotes_comm            = -1;
  651. remotes_scanner         = -1;
  652. remotes_num_ships       = 3;
  653. remotes_shield_strength = 22000;
  654. remotes_energy          = 22000;
  655. remotes_score           = 0;
  656. remotes_active_missiles = 0;
  657. remotes_state           = ALIVE;
  658. remotes_death_count    = 0;
  659.  
  660. } // end Reset_System
  661.  
  662. ///////////////////////////////////////////////////////////////////////////////
  663.  
  664. void Panel_FX(void)
  665. {
  666. // this function performs all of the special effects for the control panel
  667.  
  668. int index; // lopping variable
  669.  
  670. static int panel_counter = 0;  // used to time the color rotation of the panel
  671.  
  672. // is it time to update colors?
  673.  
  674. if (++panel_counter>2)
  675.    {
  676.    // reset counter
  677.  
  678.    panel_counter=0;
  679.  
  680.    // do animation to colors
  681.  
  682.    Read_Color_Reg(END_PANEL_REG, (RGB_color_ptr)&color_1);
  683.  
  684.    for (index=END_PANEL_REG; index>START_PANEL_REG; index--)
  685.        {
  686.        // read the (i-1)th register
  687.  
  688.        Read_Color_Reg(index-1, (RGB_color_ptr)&color_2);
  689.  
  690.        // assign it to the ith
  691.  
  692.        Write_Color_Reg(index, (RGB_color_ptr)&color_2);
  693.  
  694.        } // end rotate loop
  695.  
  696.     // place the value of the first color register into the last to
  697.     // complete the rotation
  698.  
  699.     Write_Color_Reg(START_PANEL_REG, (RGB_color_ptr)&color_1);
  700.  
  701.    } // end if time
  702.  
  703. } // end Panel_FX
  704.  
  705. ////////////////////////////////////////////////////////////////////////////////
  706.  
  707. void Start_Explosion(int x,int y,int speed)
  708. {
  709. // this function stars a generic explosion
  710.  
  711. int index;  // looping variable
  712.  
  713. // scan for a useable explosion
  714.  
  715. for (index=0; index<NUM_EXPLOSIONS; index++)
  716.     {
  717.  
  718.     if (explosions[index].state == EXPLOSION_INACTIVE)
  719.        {
  720.  
  721.        // set up fields
  722.  
  723.        explosions[index].state       = EXPLOSION_ACTIVE;
  724.        explosions[index].x           = 0; // screen coordinates
  725.        explosions[index].y           = 0;
  726.        explosions[index].counter_2   = x; // the counters will be used as universe
  727.        explosions[index].counter_3   = y; // coordinates
  728.  
  729.  
  730.        explosions[index].curr_frame  = 0;
  731.        explosions[index].threshold_1 = speed;
  732.        explosions[index].counter_1   = 0;
  733.  
  734.        // make some sound
  735.  
  736.        Digital_FX_Play(BLZEXP1_VOC,1);
  737.  
  738.        break; // exit loop
  739.  
  740.        } // end if found a good one
  741.  
  742.     } // end for index
  743.  
  744. } // end Start_Explosion
  745.  
  746. /////////////////////////////////////////////////////////////////////////////
  747.  
  748. void Under_Explosions(void)
  749. {
  750.  
  751. // this function scans under the explosions
  752.  
  753.  
  754. int index,     // looping index
  755.     px_window, // the starting postion of the players window
  756.     py_window;
  757.  
  758. // compute starting position of players window so screen mapping can be done
  759.  
  760. px_window = players_x - 160+11;
  761. py_window = players_y - 100+9;
  762.  
  763. // scan for a running explosions
  764.  
  765. for (index=0; index<NUM_EXPLOSIONS; index++)
  766.     {
  767.  
  768.     if (explosions[index].state == EXPLOSION_ACTIVE)
  769.        {
  770.  
  771.        // postion explosion correctly on view screen, note this is very similar
  772.        // to what we will do in 3-D when we translate all the objects in the
  773.        // universe to the viewer position, note counter_2 and counter_3
  774.        // in the sprite structure are used as universe or world x,y
  775.  
  776.        explosions[index].x = (explosions[index].counter_2-px_window);
  777.        explosions[index].y = (explosions[index].counter_3-py_window);
  778.  
  779.        Sprite_Under_Clip((sprite_ptr)&explosions[index],double_buffer);
  780.  
  781.        } // end if found a good one
  782.  
  783.     } // end for index
  784.  
  785. } // end Under_Explosions
  786.  
  787. /////////////////////////////////////////////////////////////////////////////
  788.  
  789. void Erase_Explosions(void)
  790. {
  791. // this function erases all the current explosions
  792.  
  793. int index;
  794.  
  795. // scan for a useable explosion
  796.  
  797. for (index=0; index<NUM_EXPLOSIONS; index++)
  798.     {
  799.  
  800.     if (explosions[index].state == EXPLOSION_ACTIVE)
  801.        {
  802.        Sprite_Erase_Clip((sprite_ptr)&explosions[index],double_buffer);
  803.  
  804.        } // end if found a good one
  805.  
  806.     } // end for index
  807.  
  808. } // end Erase_Explosions
  809.  
  810. /////////////////////////////////////////////////////////////////////////////
  811.  
  812. void Draw_Explosions(void)
  813. {
  814. // this function draws the explosion
  815.  
  816. int index; // looping variable
  817.  
  818. // scan for a useable explosion
  819.  
  820. for (index=0; index<NUM_EXPLOSIONS; index++)
  821.     {
  822.  
  823.     // make sure this explosion is alive
  824.  
  825.     if (explosions[index].state == EXPLOSION_ACTIVE)
  826.        {
  827.  
  828.        Sprite_Draw_Clip((sprite_ptr)&explosions[index],double_buffer,1);
  829.  
  830.        } // end if found a good one
  831.  
  832.     } // end for index
  833.  
  834. } // end Draw_Explosions
  835.  
  836. /////////////////////////////////////////////////////////////////////////////
  837.  
  838. void Animate_Explosions(void)
  839. {
  840. // this function aniamtes the explosions
  841.  
  842. int index;  // looping index
  843.  
  844. // scan for a useable explosion
  845.  
  846. for (index=0; index<NUM_EXPLOSIONS; index++)
  847.     {
  848.     // test if explosion is active
  849.  
  850.     if (explosions[index].state == EXPLOSION_ACTIVE)
  851.        {
  852.        // test if it's time to change frames
  853.  
  854.        if (++explosions[index].counter_1 >= explosions[index].threshold_1)
  855.           {
  856.           // is the explosion over?
  857.  
  858.           if (++explosions[index].curr_frame == NUM_EXPLOSION_FRAMES)
  859.              explosions[index].state = EXPLOSION_INACTIVE;
  860.  
  861.           // reset animation clock for future
  862.  
  863.           explosions[index].counter_1 = 0;
  864.  
  865.           } // end if time to change frames
  866.  
  867.        } // end if found a good one
  868.  
  869.     } // end for index
  870.  
  871. } // end Animate_Explosions
  872.  
  873. //////////////////////////////////////////////////////////////////////////////
  874.  
  875. void Init_Explosions(void)
  876. {
  877. // clear out the states of all explosions
  878.  
  879. int index; // looping variable
  880.  
  881. for (index=0; index<NUM_EXPLOSIONS; index++)
  882.     explosions[index].state = EXPLOSION_INACTIVE;
  883.  
  884. } // Init_Explosions
  885.  
  886. /////////////////////////////////////////////////////////////////////////////
  887.  
  888. void Load_Wormhole(void)
  889. {
  890. // this function loads in the imagery for the worm hole
  891.  
  892. int index; // looping variable
  893.  
  894. // load the imagery for the worm hole
  895.  
  896. PCX_Init((pcx_picture_ptr)&image_pcx);
  897. PCX_Load("blazewrm.pcx", (pcx_picture_ptr)&image_pcx,1);
  898.  
  899. // initialize the wormhole sprite
  900.  
  901. Sprite_Init((sprite_ptr)&wormhole,0,0,26,22,0,0,0,0,0,0);
  902.  
  903. // extract the animation frames
  904.  
  905. for (index=0; index<NUM_WORMHOLE_FRAMES; index++)
  906.     PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,(sprite_ptr)&wormhole,index,index,0);
  907.  
  908. PCX_Delete((pcx_picture_ptr)&image_pcx);
  909.  
  910. } // end Load_Wormhole
  911.  
  912. /////////////////////////////////////////////////////////////////////////////
  913.  
  914. void Init_Wormhole(void)
  915. {
  916. // this resets all the worm hole parameters
  917.  
  918.  
  919. // set screen coordinates to 0
  920.  
  921. wormhole.x = 0;
  922. wormhole.y = 0;
  923.  
  924. // set universe coordinates to proper position
  925.  
  926. wormhole.counter_2 = WORMHOLE_X; // note the counters are being used for
  927. wormhole.counter_3 = WORMHOLE_Y; // universe positions
  928.  
  929. // reset the frame counter
  930.  
  931. wormhole.curr_frame = 0;
  932.  
  933. // these will be used to time animation
  934.  
  935. wormhole.counter_1 = 0;
  936. wormhole.threshold_1 = 2;
  937.  
  938. } // end Init_Wormhole
  939.  
  940. /////////////////////////////////////////////////////////////////////////////
  941.  
  942. void Under_Wormhole(void)
  943. {
  944.  
  945. // this function scans under the wormhole
  946.  
  947.  
  948. int px_window, // the starting postion of the players window
  949.     py_window;
  950.  
  951. // compute starting position of players window so screen mapping can be done
  952.  
  953. px_window = players_x - 160+11;
  954. py_window = players_y - 100+9;
  955.  
  956. // translate wormhole to screen coordinates
  957.  
  958. wormhole.x = (wormhole.counter_2-px_window);
  959. wormhole.y = (wormhole.counter_3-py_window);
  960.  
  961. Sprite_Under_Clip((sprite_ptr)&wormhole,double_buffer);
  962.  
  963. } // end Under_Wormhole
  964.  
  965. /////////////////////////////////////////////////////////////////////////////
  966.  
  967. void Erase_Wormhole(void)
  968. {
  969. // this function erase the wormhole
  970.  
  971. Sprite_Erase_Clip((sprite_ptr)&wormhole,double_buffer);
  972.  
  973. } // end Erase_Wormhole
  974.  
  975. /////////////////////////////////////////////////////////////////////////////
  976.  
  977. void Draw_Wormhole(void)
  978. {
  979. // this function draws the wormhole
  980.  
  981. Sprite_Draw_Clip((sprite_ptr)&wormhole,double_buffer,1);
  982.  
  983. } // end Draw_Wormhole
  984.  
  985. /////////////////////////////////////////////////////////////////////////////
  986.  
  987. void Animate_Wormhole(void)
  988. {
  989. // this function animates the wormhole
  990.  
  991. if (++wormhole.counter_1 >= wormhole.threshold_1)
  992.    {
  993.    // time to reset frame counter?
  994.  
  995.    if (++wormhole.curr_frame == NUM_WORMHOLE_FRAMES)
  996.        wormhole.curr_frame = 0;
  997.  
  998.     // reset animation clock for future
  999.  
  1000.     wormhole.counter_1 = 0;
  1001.  
  1002.     } // end if time to change frames
  1003.  
  1004. } // end Animate_Wormhole
  1005.  
  1006. /////////////////////////////////////////////////////////////////////////////
  1007.  
  1008. void Load_Fuel_Cells(void)
  1009. {
  1010. // this function loads in the imagery for the fuel cells
  1011.  
  1012. int index,  // looping variable
  1013.     frames; // looping variable
  1014.  
  1015. // load the imagery for the fuel cells
  1016.  
  1017. PCX_Init((pcx_picture_ptr)&image_pcx);
  1018. PCX_Load("blazeful.pcx", (pcx_picture_ptr)&image_pcx,1);
  1019.  
  1020. // initialize the fuel cells sprite and load bitmaps
  1021.  
  1022. for (index=0; index<NUM_FUEL_CELLS; index++)
  1023.     {
  1024.  
  1025.     Sprite_Init((sprite_ptr)&fuel_cells[index],0,0,20,18,0,0,0,0,0,0);
  1026.  
  1027.     // extract the animation frames
  1028.  
  1029.     for (frames=0; frames<NUM_FUEL_FRAMES; frames++)
  1030.         PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,
  1031.                        (sprite_ptr)&fuel_cells[index],frames,frames,0);
  1032.  
  1033.     } // end for index
  1034.  
  1035. PCX_Delete((pcx_picture_ptr)&image_pcx);
  1036.  
  1037. } // end Load_Fuel_Cells
  1038.  
  1039. /////////////////////////////////////////////////////////////////////////////
  1040.  
  1041. void Init_Fuel_Cells(void)
  1042. {
  1043. // this resets all the fuel cell parameters
  1044.  
  1045. int index; // looping variable
  1046.  
  1047. for (index=0; index<NUM_FUEL_CELLS; index++)
  1048.     {
  1049.  
  1050.     // set state
  1051.  
  1052.     fuel_cells[index].state = FUEL_CELL_ACTIVE;
  1053.  
  1054.     // set screen coordinates to 0
  1055.  
  1056.     fuel_cells[index].x = 0;
  1057.     fuel_cells[index].y = 0;
  1058.  
  1059.     // set universe coordinates to random position
  1060.  
  1061.     fuel_cells[index].counter_2 = 200+rand()%(UNIVERSE_WIDTH-400);
  1062.     fuel_cells[index].counter_3 = 200+rand()%(UNIVERSE_HEIGHT-400);
  1063.  
  1064.     // reset the frame counter
  1065.  
  1066.     fuel_cells[index].curr_frame = 0;
  1067.  
  1068.     // these will be used to time animation
  1069.  
  1070.     fuel_cells[index].counter_1 = 0;
  1071.     fuel_cells[index].threshold_1 = 2;
  1072.  
  1073.     } // end index
  1074.  
  1075. } // end Init_Fuel_Cells
  1076.  
  1077. /////////////////////////////////////////////////////////////////////////////
  1078.  
  1079. void Under_Fuel_Cells(void)
  1080. {
  1081. // this function scans under the Fuel cells
  1082.  
  1083.  
  1084. int px_window, // the starting postion of the players window
  1085.     py_window,
  1086.     index;     // looping variable
  1087.  
  1088. // compute starting position of players window so screen mapping can be done
  1089.  
  1090. px_window = players_x - 160+11;
  1091. py_window = players_y - 100+9;
  1092.  
  1093. // process each fuel cell
  1094.  
  1095. for (index=0; index<NUM_FUEL_CELLS; index++)
  1096.     {
  1097.     // test if fuel cell is active
  1098.  
  1099.     if (fuel_cells[index].state == FUEL_CELL_ACTIVE)
  1100.        {
  1101.        // translate Fuelcells to screen coordinates
  1102.  
  1103.        fuel_cells[index].x = (fuel_cells[index].counter_2-px_window);
  1104.        fuel_cells[index].y = (fuel_cells[index].counter_3-py_window);
  1105.  
  1106.        Sprite_Under_Clip((sprite_ptr)&fuel_cells[index],double_buffer);
  1107.  
  1108.        } // end fi active
  1109.  
  1110.     } // end for index
  1111.  
  1112. } // end Under_Fuel_Cells
  1113.  
  1114. /////////////////////////////////////////////////////////////////////////////
  1115.  
  1116. void Erase_Fuel_Cells(void)
  1117. {
  1118. // this function erase the Fuelcells
  1119.  
  1120. int index; // looping variable
  1121.  
  1122. for (index=0; index<NUM_FUEL_CELLS; index++)
  1123.     {
  1124.     // test if fuel cell is active
  1125.  
  1126.     if (fuel_cells[index].state == FUEL_CELL_ACTIVE)
  1127.        {
  1128.  
  1129.        Sprite_Erase_Clip((sprite_ptr)&fuel_cells[index],double_buffer);
  1130.  
  1131.        } // end if active
  1132.  
  1133.     } // end for index
  1134.  
  1135. } // end Erase_Fuel_Cells
  1136.  
  1137. /////////////////////////////////////////////////////////////////////////////
  1138.  
  1139. void Draw_Fuel_Cells(void)
  1140. {
  1141. // this function draws the Fuel cells
  1142.  
  1143. int index; // looping variable
  1144.  
  1145. for (index=0; index<NUM_FUEL_CELLS; index++)
  1146.     {
  1147.     // test if fuel cell is active
  1148.  
  1149.     if (fuel_cells[index].state == FUEL_CELL_ACTIVE)
  1150.        {
  1151.  
  1152.        Sprite_Draw_Clip((sprite_ptr)&fuel_cells[index],double_buffer,1);
  1153.  
  1154.        } // end if active
  1155.  
  1156.     } // end for index
  1157.  
  1158. } // end Draw_Fuel_Cells
  1159.  
  1160. /////////////////////////////////////////////////////////////////////////////
  1161.  
  1162. void Animate_Fuel_Cells(void)
  1163. {
  1164. // this function animates the fuel cells and test for collision
  1165.  
  1166. int index; // looping variable
  1167.  
  1168. for (index=0; index<NUM_FUEL_CELLS; index++)
  1169.     {
  1170.     // test if fuel cell is active
  1171.  
  1172.     if (fuel_cells[index].state == FUEL_CELL_ACTIVE)
  1173.        {
  1174.        // move cell to right
  1175.  
  1176.        if (++fuel_cells[index].counter_2 > (UNIVERSE_WIDTH+UNIVERSE_BORDER))
  1177.           fuel_cells[index].counter_2 = -UNIVERSE_BORDER;
  1178.  
  1179.        // perform animation
  1180.  
  1181.        if (++fuel_cells[index].counter_1 >= fuel_cells[index].threshold_1)
  1182.           {
  1183.           // time to reset frame counter?
  1184.  
  1185.           if (++fuel_cells[index].curr_frame == NUM_FUEL_FRAMES)
  1186.               fuel_cells[index].curr_frame = 0;
  1187.  
  1188.            // reset animation clock for future
  1189.  
  1190.            fuel_cells[index].counter_1 = 0;
  1191.  
  1192.           } // end if time to change frames
  1193.  
  1194.        } // end if active
  1195.  
  1196.     } // end for index
  1197.  
  1198. } // end Animate_Fuel_Cells
  1199.  
  1200. //////////////////////////////////////////////////////////////////////////////
  1201.  
  1202. void Load_Alien(void)
  1203. {
  1204. // this function loads in the imagery for the alien
  1205.  
  1206. int index; // looping variable
  1207.  
  1208. // load the imagery for the alien
  1209.  
  1210. PCX_Init((pcx_picture_ptr)&image_pcx);
  1211. PCX_Load("blazealn.pcx", (pcx_picture_ptr)&image_pcx,1);
  1212.  
  1213. // initialize the alien sprite
  1214.  
  1215. Sprite_Init((sprite_ptr)&alien.body,0,0,14,8,0,0,0,0,0,0);
  1216.  
  1217. // extract the animation frames
  1218.  
  1219. for (index=0; index<NUM_ALIEN_FRAMES; index++)
  1220.     PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,(sprite_ptr)&alien.body,index,index,0);
  1221.  
  1222.  
  1223. PCX_Delete((pcx_picture_ptr)&image_pcx);
  1224.  
  1225. } // end Load_Alien
  1226.  
  1227. /////////////////////////////////////////////////////////////////////////////
  1228.  
  1229. void Init_Alien(void)
  1230. {
  1231. // this resets all the alien parameters
  1232.  
  1233. // set screen coordinates to 0
  1234.  
  1235. alien.body.x = 0;
  1236. alien.body.y = 0;
  1237.  
  1238. // set universe coordinates to proper position
  1239.  
  1240. alien.x = 0;
  1241. alien.y = 0;
  1242.  
  1243. // reset the frame counter
  1244.  
  1245. alien.body.curr_frame = 0;
  1246.  
  1247. // these will be used to time animation
  1248.  
  1249. alien.body.counter_1 = 0;
  1250. alien.body.threshold_1 = 2;
  1251.  
  1252. // set state to active
  1253.  
  1254. alien.state = ALIEN_INACTIVE;
  1255.  
  1256. } // end Init_Alien
  1257.  
  1258. //////////////////////////////////////////////////////////////////////////////
  1259.  
  1260. void Alien_Control(void)
  1261. {
  1262. // this function will be called every cycle and decide if an alien
  1263. // will start up
  1264.  
  1265. // make sure alien is dead
  1266.  
  1267. if (alien.state==ALIEN_INACTIVE)
  1268.    {
  1269.    // throw a coin
  1270.  
  1271.    if ((rand()%ALIEN_ODDS)==1)
  1272.       {
  1273.       // position alien and set appropriate fields
  1274.  
  1275.       alien.body.x = 0; // screen coords
  1276.       alien.body.y = 0;
  1277.  
  1278.       // start alien from wormhole (universe coords)
  1279.  
  1280.       alien.x = WORMHOLE_X; // note the counters are being used for
  1281.       alien.y = WORMHOLE_Y; // universe positions
  1282.  
  1283.       // reset the frame counter
  1284.  
  1285.       alien.body.curr_frame = 0;
  1286.  
  1287.       // this will be used to time animation
  1288.  
  1289.       alien.body.counter_1   = 0;
  1290.       alien.body.threshold_1 = 2;
  1291.  
  1292.       // set state to random to start with
  1293.  
  1294.       alien.state = ALIEN_RANDOM;
  1295.  
  1296.       // select a random direction
  1297.  
  1298.       alien.xv = -4 + rand()%8;
  1299.       alien.yv = -4 + rand()%8;
  1300.  
  1301.       // counter 2 will be used to track how long to stay in a state
  1302.  
  1303.       alien.body.counter_2 = 50;
  1304.  
  1305.       } // end if start one
  1306.  
  1307.    } // end if dead
  1308.  
  1309. } // end Alien_Control
  1310.  
  1311. /////////////////////////////////////////////////////////////////////////////
  1312.  
  1313. void Under_Alien(void)
  1314. {
  1315. // this function scans under the alien
  1316.  
  1317. int px_window, // the starting postion of the players window
  1318.     py_window;
  1319.  
  1320. if (alien.state!=ALIEN_INACTIVE)
  1321.    {
  1322.    // compute starting position of players window so screen
  1323.    // mapping can be done
  1324.  
  1325.    px_window = players_x - 160+11;
  1326.    py_window = players_y - 100+9;
  1327.  
  1328.    // translate alien to screen coordinates
  1329.  
  1330.    alien.body.x = (alien.x-px_window);
  1331.    alien.body.y = (alien.y-py_window);
  1332.  
  1333.    // perform scan in screen coords
  1334.  
  1335.    Sprite_Under_Clip((sprite_ptr)&alien.body,double_buffer);
  1336.  
  1337.    } // end if alien alive
  1338.  
  1339. } // end Under_Alien
  1340.  
  1341. /////////////////////////////////////////////////////////////////////////////
  1342.  
  1343. void Erase_Alien(void)
  1344. {
  1345. // this function erases the alien
  1346.  
  1347. if (alien.state!=ALIEN_INACTIVE)
  1348.     Sprite_Erase_Clip((sprite_ptr)&alien.body,double_buffer);
  1349.  
  1350. } // end Erase_Alien
  1351.  
  1352. /////////////////////////////////////////////////////////////////////////////
  1353.  
  1354. void Draw_Alien(void)
  1355. {
  1356. // this function draws the alien
  1357.  
  1358. if (alien.state!=ALIEN_INACTIVE)
  1359.    Sprite_Draw_Clip((sprite_ptr)&alien.body,double_buffer,1);
  1360.  
  1361. } // end Draw_Alien
  1362.  
  1363. /////////////////////////////////////////////////////////////////////////////
  1364.  
  1365. void Move_Alien(void)
  1366. {
  1367. // this function moves the alien (if there is one)
  1368.  
  1369. if (alien.state!=ALIEN_INACTIVE)
  1370.    {
  1371.  
  1372.    // what state is alien in?
  1373.  
  1374.    switch(alien.state)
  1375.          {
  1376.  
  1377.          case ALIEN_RANDOM:
  1378.               {
  1379.  
  1380.               // move alien in direction
  1381.  
  1382.               alien.x+=alien.xv;
  1383.               alien.y+=alien.yv;
  1384.  
  1385.               } break;
  1386.  
  1387.          case ALIEN_CHASE_PLAYER:
  1388.               {
  1389.  
  1390.  
  1391.               } break;
  1392.  
  1393.          case ALIEN_CHASE_REMOTE:
  1394.               {
  1395.  
  1396.  
  1397.               } break;
  1398.  
  1399.           default:break;
  1400.  
  1401.          } // end switch
  1402.  
  1403.    // decrement state counter
  1404.  
  1405.    if (--alien.body.counter_2<=0)
  1406.       {
  1407.       // select a new state
  1408.  
  1409.       alien.state = ALIEN_RANDOM;   // change this line later
  1410.  
  1411.       // set up new state
  1412.  
  1413.       switch(alien.state)
  1414.             {
  1415.             case ALIEN_RANDOM:
  1416.                  {
  1417.                  // select new random direction and state time
  1418.  
  1419.                  alien.xv = -4 + rand()%8;
  1420.                  alien.yv = -4 + rand()%8;
  1421.  
  1422.                  // counter 2 will be used to track how long to stay in a state
  1423.  
  1424.                  alien.body.counter_2 = 25+rand()%75;
  1425.  
  1426.                  } break;
  1427.  
  1428.             case ALIEN_CHASE_PLAYER:
  1429.                  {
  1430.                  // this bud's for you!
  1431.                  } break;
  1432.  
  1433.             case ALIEN_CHASE_REMOTE:
  1434.                  {
  1435.                  // this is an exercise
  1436.                  } break;
  1437.  
  1438.             default:break;
  1439.  
  1440.             } // end switch
  1441.  
  1442.       } // end if time to select a new state
  1443.  
  1444.    // animate alien
  1445.  
  1446.    if (++alien.body.counter_1 >=alien.body.threshold_1)
  1447.       {
  1448.       // change animation frames
  1449.  
  1450.       if (++alien.body.curr_frame==NUM_ALIEN_FRAMES)
  1451.          alien.body.curr_frame = 0;
  1452.  
  1453.       // reset animation counter
  1454.  
  1455.       alien.body.counter_1 = 0;
  1456.  
  1457.       } // end if time to animate
  1458.  
  1459.    // do collision detection
  1460.  
  1461.    if ((alien.x>UNIVERSE_WIDTH+UNIVERSE_BORDER)  ||
  1462.        (alien.x<-UNIVERSE_BORDER)                ||
  1463.        (alien.y>UNIVERSE_HEIGHT+UNIVERSE_BORDER) ||
  1464.        (alien.y<-UNIVERSE_BORDER))
  1465.       {
  1466.       // kill alien
  1467.  
  1468.       alien.state = ALIEN_INACTIVE;
  1469.  
  1470.       } // end if alien has warped off universe edge
  1471.  
  1472.    } // end if alien alive
  1473.  
  1474. } // end Move_Alien
  1475.  
  1476. ///////////////////////////////////////////////////////////////////////////////
  1477.  
  1478. void Load_Heads(void)
  1479. {
  1480. // this function loads various icons for the heads up display
  1481.  
  1482. int index; // looping variable
  1483.  
  1484. // load the imagery for the icons for display
  1485.  
  1486. PCX_Init((pcx_picture_ptr)&image_pcx);
  1487. PCX_Load("blazehu1.pcx", (pcx_picture_ptr)&image_pcx,1);
  1488.  
  1489. // intialize the button sprite
  1490.  
  1491. Sprite_Init((sprite_ptr)&heads_text,0,0,34,6,0,0,0,0,0,0);
  1492.  
  1493. // extract the bitmaps for heads up text
  1494.  
  1495. for (index=0; index<7; index++)
  1496.     PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,
  1497.                    (sprite_ptr)&heads_text,index,index,0);
  1498.  
  1499. // delete pcx file
  1500.  
  1501. PCX_Delete((pcx_picture_ptr)&image_pcx);
  1502.  
  1503. // load the imagery for the icons for display
  1504.  
  1505. PCX_Init((pcx_picture_ptr)&image_pcx);
  1506. PCX_Load("blazehu2.pcx", (pcx_picture_ptr)&image_pcx,1);
  1507.  
  1508. // intialize the button sprite
  1509.  
  1510. Sprite_Init((sprite_ptr)&heads_numbers,0,0,8,6,0,0,0,0,0,0);
  1511.  
  1512. // extract the bitmaps for heads up text
  1513.  
  1514. for (index=0; index<7; index++)
  1515.     PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,
  1516.                    (sprite_ptr)&heads_numbers,index,index,0);
  1517.  
  1518. // delete pcx file
  1519.  
  1520. PCX_Delete((pcx_picture_ptr)&image_pcx);
  1521.  
  1522. // load the imagery for the icons for display
  1523.  
  1524. PCX_Init((pcx_picture_ptr)&image_pcx);
  1525. PCX_Load("blazehu1.pcx", (pcx_picture_ptr)&image_pcx,1);
  1526.  
  1527. // intialize the button sprite
  1528.  
  1529. Sprite_Init((sprite_ptr)&heads_gauge,0,0,34,6,0,0,0,0,0,0);
  1530.  
  1531. // extract the bitmaps for heads up gauges
  1532.  
  1533. for (index=0; index<23; index++)
  1534.     PCX_Get_Sprite((pcx_picture_ptr)&image_pcx,
  1535.                    (sprite_ptr)&heads_gauge,index,index%9,2+index/9);
  1536.  
  1537. // delete pcx file
  1538.  
  1539. PCX_Delete((pcx_picture_ptr)&image_pcx);
  1540.  
  1541. } // end Load_Heads
  1542.  
  1543. ////////////////////////////////////////////////////////////////////////////
  1544.  
  1545. void Init_Heads(void)
  1546. {
  1547. // do nothing for now
  1548.  
  1549.  
  1550. } // end Init_Heads
  1551.  
  1552. ////////////////////////////////////////////////////////////////////////////
  1553.  
  1554. void Draw_Heads(void)
  1555. {
  1556. // this function draws the heads up display during the tmie when
  1557. // the game background can be modified
  1558.  
  1559. int index; // looping variable
  1560.  
  1561. heads_text.x = LEFT_HEADS_TEXT_X;
  1562. heads_text.y = LEFT_HEADS_TEXT_Y;
  1563.  
  1564. // draw the left most messages first
  1565.  
  1566. heads_text.curr_frame = HEADS_CLOAK;
  1567.  
  1568. for (index=0; index<4; index++)
  1569.     {
  1570.     Sprite_Draw((sprite_ptr)&heads_text,double_buffer,0);
  1571.  
  1572.     // move down a row
  1573.  
  1574.     heads_text.y+=8;
  1575.  
  1576.     // select next message
  1577.  
  1578.     heads_text.curr_frame++;
  1579.  
  1580.     } //  end for index
  1581.  
  1582. // now draw buttons and numbers
  1583.  
  1584. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1585. heads_numbers.y = LEFT_HEADS_TEXT_Y;
  1586.  
  1587. // draw cloaked button
  1588.  
  1589. if (players_cloak==1)
  1590.    {
  1591.    heads_numbers.curr_frame=2;
  1592.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1593.    }
  1594. else
  1595.    {
  1596.    heads_numbers.curr_frame=1;
  1597.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1598.    } // end else
  1599.  
  1600. // draw scanner enable
  1601.  
  1602. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1603. heads_numbers.y = LEFT_HEADS_TEXT_Y+8;
  1604.  
  1605. if (players_scanner==1)
  1606.    {
  1607.    heads_numbers.curr_frame=2;
  1608.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1609.    }
  1610. else
  1611.    {
  1612.    heads_numbers.curr_frame=1;
  1613.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1614.    } // end else
  1615.  
  1616. // draw communications
  1617.  
  1618. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1619. heads_numbers.y = LEFT_HEADS_TEXT_Y+16;
  1620.  
  1621. if (linked)
  1622.    {
  1623.    heads_numbers.curr_frame=2;
  1624.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1625.    }
  1626. else
  1627.    {
  1628.    heads_numbers.curr_frame=1;
  1629.    Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1630.    } // end else
  1631.  
  1632. // draw number of ships
  1633.  
  1634. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1635. heads_numbers.y = LEFT_HEADS_TEXT_Y+24;
  1636.  
  1637. heads_numbers.curr_frame=3+players_num_ships;
  1638. Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1639.  
  1640. // now draw right most messages
  1641.  
  1642. heads_text.x = RIGHT_HEADS_TEXT_X;
  1643. heads_text.y = RIGHT_HEADS_TEXT_Y;
  1644.  
  1645. heads_text.curr_frame = HEADS_ENERGY;
  1646.  
  1647. for (index=0; index<2; index++)
  1648.     {
  1649.     Sprite_Draw((sprite_ptr)&heads_text,double_buffer,0);
  1650.  
  1651.     // move down a row
  1652.  
  1653.     heads_text.y+=8;
  1654.  
  1655.     // select next message
  1656.  
  1657.     heads_text.curr_frame++;
  1658.  
  1659.     } //  end for index
  1660.  
  1661. // draw gauges
  1662.  
  1663. heads_gauge.x = RIGHT_HEADS_TEXT_X+40;
  1664. heads_gauge.y = RIGHT_HEADS_TEXT_Y;
  1665.  
  1666. // compute proper frame
  1667.  
  1668. heads_gauge.curr_frame = 22 - (players_energy/1000);
  1669.  
  1670. // draw the energy level
  1671.  
  1672. Sprite_Draw((sprite_ptr)&heads_gauge,double_buffer,0);
  1673.  
  1674. heads_gauge.x = RIGHT_HEADS_TEXT_X+40;
  1675. heads_gauge.y = RIGHT_HEADS_TEXT_Y+8;
  1676.  
  1677. // compute proper frame
  1678.  
  1679. heads_gauge.curr_frame = 22 - (players_shield_strength/1000);
  1680.  
  1681. // draw the shield strength
  1682.  
  1683. Sprite_Draw((sprite_ptr)&heads_gauge,double_buffer,0);
  1684.  
  1685. } // end Draw_Heads
  1686.  
  1687. ////////////////////////////////////////////////////////////////////////////
  1688.  
  1689. void Erase_Heads(void)
  1690. {
  1691.  
  1692. // this function erases the heads up display during the time when
  1693. // the game background can be modified
  1694.  
  1695. int index; // looping variable
  1696.  
  1697. heads_text.x = LEFT_HEADS_TEXT_X;
  1698. heads_text.y = LEFT_HEADS_TEXT_Y;
  1699.  
  1700. // draw the left most messages first
  1701.  
  1702. heads_text.curr_frame = 0;
  1703.  
  1704. for (index=0; index<4; index++)
  1705.     {
  1706.     Sprite_Draw((sprite_ptr)&heads_text,double_buffer,0);
  1707.  
  1708.     // move down a row
  1709.  
  1710.     heads_text.y+=8;
  1711.  
  1712.     } //  end for index
  1713.  
  1714.  
  1715. // now erase buttons and numbers
  1716.  
  1717. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1718. heads_numbers.y = LEFT_HEADS_TEXT_Y;
  1719.  
  1720. // erase cloaked button
  1721.  
  1722. heads_numbers.curr_frame=0;
  1723. Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1724.  
  1725. // erase scanner
  1726.  
  1727. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1728. heads_numbers.y = LEFT_HEADS_TEXT_Y+8;
  1729.  
  1730. Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1731.  
  1732. // erase communications
  1733.  
  1734. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1735. heads_numbers.y = LEFT_HEADS_TEXT_Y+16;
  1736.  
  1737. Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1738.  
  1739. // erase ships number
  1740.  
  1741. heads_numbers.x = LEFT_HEADS_TEXT_X+40;
  1742. heads_numbers.y = LEFT_HEADS_TEXT_Y+24;
  1743.  
  1744. Sprite_Draw((sprite_ptr)&heads_numbers,double_buffer,0);
  1745.  
  1746. // now draw right most messages
  1747.  
  1748. heads_text.x = RIGHT_HEADS_TEXT_X;
  1749. heads_text.y = RIGHT_HEADS_TEXT_Y;
  1750.  
  1751. // draw the left most messages first
  1752.  
  1753. for (index=0; index<2; index++)
  1754.     {
  1755.     Sprite_Draw((sprite_ptr)&heads_text,double_buffer,0);
  1756.  
  1757.     // move down a row
  1758.  
  1759.     heads_text.y+=8;
  1760.  
  1761.     } //  end for index
  1762.  
  1763. // erase gauges
  1764.  
  1765. heads_gauge.x = RIGHT_HEADS_TEXT_X+40;
  1766. heads_gauge.y = RIGHT_HEADS_TEXT_Y;
  1767.  
  1768. // compute proper frame
  1769.  
  1770. heads_gauge.curr_frame = 22;
  1771.  
  1772. // draw the energy level
  1773.  
  1774. Sprite_Draw((sprite_ptr)&heads_gauge,double_buffer,0);
  1775.  
  1776. // draw gauges
  1777.  
  1778. heads_gauge.x = RIGHT_HEADS_TEXT_X+40;
  1779. heads_gauge.y = RIGHT_HEADS_TEXT_Y+8;
  1780.  
  1781. // erase the shield strength
  1782.  
  1783. Sprite_Draw((sprite_ptr)&heads_gauge,double_buffer,0);
  1784.  
  1785. } // end Erase_Heads
  1786.  
  1787. /////////////////////////////////////////////////////////////////////////////
  1788.  
  1789. void Init_Scanner(void)
  1790. {
  1791. // this function initializes the scanner
  1792.  
  1793. // not much to do at this point!
  1794.  
  1795. } // end Init_Scanner
  1796.  
  1797. /////////////////////////////////////////////////////////////////////////////
  1798.  
  1799. void Erase_Scanner(void)
  1800. {
  1801. // this function erases the scanner and the blips
  1802.  
  1803. // first erase scanner grid
  1804.  
  1805. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y,   0,double_buffer);
  1806. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y+16,0,double_buffer);
  1807. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y+32,0,double_buffer);
  1808.  
  1809. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X,   0,double_buffer);
  1810. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+16,0,double_buffer);
  1811. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+32,0,double_buffer);
  1812. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+48,0,double_buffer);
  1813. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+64,0,double_buffer);
  1814.  
  1815. } // end Erase_Scanner
  1816.  
  1817. ////////////////////////////////////////////////////////////////////////////
  1818.  
  1819. void Draw_Scanner(void)
  1820. {
  1821. // this function draws the scanner and the blips
  1822.  
  1823. // first draw scanner grid
  1824.  
  1825. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y,   10,double_buffer);
  1826. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y+16,10,double_buffer);
  1827. Line_H_2(SCANNER_X,SCANNER_X+64,SCANNER_Y+32,10,double_buffer);
  1828.  
  1829. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X,   10,double_buffer);
  1830. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+16,10,double_buffer);
  1831. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+32,10,double_buffer);
  1832. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+48,10,double_buffer);
  1833. Line_V_2(SCANNER_Y,SCANNER_Y+32,SCANNER_X+64,10,double_buffer);
  1834.  
  1835. } // end Draw_Scanner
  1836.  
  1837. /////////////////////////////////////////////////////////////////////////////
  1838.  
  1839. void Under_Blips(void)
  1840. {
  1841. // this function is used to draw all the scanner blips
  1842.  
  1843. // draw blips, notice that the position of the remote and player is
  1844. // scaled to fit into the scanner window
  1845.  
  1846. under_players_blip = Read_Pixel_DB(SCANNER_X+players_x/40,SCANNER_Y+players_y/80);
  1847. under_remotes_blip = Read_Pixel_DB(SCANNER_X+remotes_x/40,SCANNER_Y+remotes_y/80);
  1848.  
  1849. } // end Under_Blips
  1850.  
  1851. /////////////////////////////////////////////////////////////////////////////
  1852.  
  1853. void Draw_Blips(void)
  1854. {
  1855. // this function is used to draw all the scanner blips
  1856.  
  1857. // draw blips, notice that the position of the remote and player is
  1858. // scaled to fit into the scanner window
  1859.  
  1860. if (players_cloak==-1)
  1861.    Write_Pixel_DB(SCANNER_X+players_x/40,SCANNER_Y+players_y/80,9);
  1862.  
  1863. if (remotes_cloak==-1)
  1864.    Write_Pixel_DB(SCANNER_X+remotes_x/40,SCANNER_Y+remotes_y/80,12);
  1865.  
  1866. } // end Draw_Blips
  1867.  
  1868. /////////////////////////////////////////////////////////////////////////////
  1869.  
  1870. void Erase_Blips(void)
  1871. {
  1872. // this function is used to erase all the scanner blips
  1873.  
  1874. // erase blips, notice that the position of the remote and player is
  1875. // scaled to fit into the scanner window
  1876.  
  1877. Write_Pixel_DB(SCANNER_X+players_x/40,SCANNER_Y+players_y/80,under_players_blip);
  1878. Write_Pixel_DB(SCANNER_X+remotes_x/40,SCANNER_Y+remotes_y/80,under_remotes_blip);
  1879.  
  1880. } // end Erase_Blips
  1881.  
  1882. ////////////////////////////////////////////////////////////////////////////
  1883.  
  1884. void Music_Init(void)
  1885. {
  1886. // this function loads the music and resets all the indexes
  1887.  
  1888. static int loaded=0;
  1889.  
  1890. // has the music already been loaded
  1891.  
  1892. if (!music_enabled)
  1893.    return;
  1894.  
  1895. if (!loaded)
  1896.    {
  1897.    Music_Load("blazemus.xmi",(music_ptr)&song);
  1898.    loaded=1;
  1899.    } // end if not loaded
  1900.  
  1901. // reset sequence counters
  1902.  
  1903. game_seq_index=0;
  1904. intro_seq_index=0;
  1905.  
  1906. } // end Music_Init
  1907.  
  1908. /////////////////////////////////////////////////////////////////////////////
  1909.  
  1910. void Music_Close(void)
  1911. {
  1912. // this function unloads the music files
  1913.  
  1914. if (!music_enabled)
  1915.    return;
  1916.  
  1917. // turn off music and unload song
  1918.  
  1919. Music_Stop();
  1920. Music_Unload((music_ptr)&song);
  1921.  
  1922. } // end Music_Close
  1923.  
  1924. //////////////////////////////////////////////////////////////////////////////
  1925.  
  1926. void Digital_FX_Init(void)
  1927. {
  1928. // this function initializes the digital sound fx system
  1929.  
  1930. static int loaded=0;
  1931.  
  1932. if (!digital_enabled)
  1933.    return;
  1934.  
  1935. // have the sound fx been loaded?
  1936.  
  1937. if (!loaded)
  1938.    {
  1939.    // load int sounds
  1940.  
  1941.    Sound_Load("BLZCLK.VOC"  ,(_sound_ptr)&digital_FX[BLZCLK_VOC  ],1);
  1942.    Sound_Load("BLZEXP1.VOC" ,(_sound_ptr)&digital_FX[BLZEXP1_VOC ],1);
  1943.    Sound_Load("BLZEXP2.VOC" ,(_sound_ptr)&digital_FX[BLZEXP2_VOC ],1);
  1944.    Sound_Load("BLZLAS.VOC"  ,(_sound_ptr)&digital_FX[BLZLAS_VOC  ],1);
  1945.    Sound_Load("BLZNRG.VOC"  ,(_sound_ptr)&digital_FX[BLZNRG_VOC  ],1);
  1946.    Sound_Load("BLZSHLD.VOC" ,(_sound_ptr)&digital_FX[BLZSHLD_VOC ],1);
  1947.    Sound_Load("BLZTAC.VOC"  ,(_sound_ptr)&digital_FX[BLZTAC_VOC  ],1);
  1948.    Sound_Load("BLZSCN.VOC"  ,(_sound_ptr)&digital_FX[BLZSCN_VOC  ],1);
  1949.    Sound_Load("BLZMISS.VOC" ,(_sound_ptr)&digital_FX[BLZMISS_VOC ],1);
  1950.  
  1951.    Sound_Load("BLZBIOS.VOC" ,(_sound_ptr)&digital_FX[BLZBIOS_VOC ],1);
  1952.    Sound_Load("BLZENTR.VOC" ,(_sound_ptr)&digital_FX[BLZENTR_VOC ],1);
  1953.    Sound_Load("BLZABRT.VOC" ,(_sound_ptr)&digital_FX[BLZABRT_VOC ],1);
  1954.    Sound_Load("BLZSEL.VOC"  ,(_sound_ptr)&digital_FX[BLZSEL_VOC  ],1);
  1955.    Sound_Load("BLZKEY.VOC"  ,(_sound_ptr)&digital_FX[BLZKEY_VOC  ],1);
  1956.    Sound_Load("BLZDIAL.VOC"  ,(_sound_ptr)&digital_FX[BLZDIAL_VOC  ],1);
  1957.  
  1958.    Sound_Load("BLZLOS.VOC"  ,(_sound_ptr)&digital_FX[BLZLOS_VOC  ],1);
  1959.    Sound_Load("BLZWIN.VOC"  ,(_sound_ptr)&digital_FX[BLZWIN_VOC  ],1);
  1960.  
  1961.    // set loaded flag
  1962.  
  1963.    loaded=1;
  1964.  
  1965.    } // end if sound effects aren't loaded
  1966.  
  1967. } // end Digital_FX_Init
  1968.  
  1969. ///////////////////////////////////////////////////////////////////////////////
  1970.  
  1971. void Digital_FX_Close(void)
  1972. {
  1973. // this function unloads all the digital FX
  1974.  
  1975. if (!digital_enabled)
  1976.    return;
  1977.  
  1978. // unload all the sound fx from memory
  1979.  
  1980. Sound_Unload((_sound_ptr)&digital_FX[BLZCLK_VOC  ]);
  1981. Sound_Unload((_sound_ptr)&digital_FX[BLZEXP1_VOC ]);
  1982. Sound_Unload((_sound_ptr)&digital_FX[BLZEXP2_VOC ]);
  1983. Sound_Unload((_sound_ptr)&digital_FX[BLZLAS_VOC  ]);
  1984. Sound_Unload((_sound_ptr)&digital_FX[BLZNRG_VOC  ]);
  1985. Sound_Unload((_sound_ptr)&digital_FX[BLZSHLD_VOC ]);
  1986. Sound_Unload((_sound_ptr)&digital_FX[BLZTAC_VOC  ]);
  1987. Sound_Unload((_sound_ptr)&digital_FX[BLZSCN_VOC  ]);
  1988. Sound_Unload((_sound_ptr)&digital_FX[BLZMISS_VOC ]);
  1989.  
  1990. Sound_Unload((_sound_ptr)&digital_FX[BLZENTR_VOC ]);
  1991. Sound_Unload((_sound_ptr)&digital_FX[BLZABRT_VOC ]);
  1992. Sound_Unload((_sound_ptr)&digital_FX[BLZSEL_VOC  ]);
  1993. Sound_Unload((_sound_ptr)&digital_FX[BLZKEY_VOC  ]);
  1994. Sound_Unload((_sound_ptr)&digital_FX[BLZDIAL_VOC ]);
  1995.  
  1996. Sound_Unload((_sound_ptr)&digital_FX[BLZLOS_VOC  ]);
  1997. Sound_Unload((_sound_ptr)&digital_FX[BLZWIN_VOC ]);
  1998.  
  1999.  
  2000. } // end Digital_FX_Close
  2001.  
  2002. /////////////////////////////////////////////////////////////////////////////
  2003.  
  2004. int Digital_FX_Play(int the_effect, int priority)
  2005. {
  2006. // this function is used to play a digital effect using a pre-emptive priority
  2007. // scheme. The algorithm works like this: if a sound is playing then its
  2008. // priority is compared to the sound that is being requested to be played
  2009. // if the new sound has higher priority (a smaller number) then the currenlty
  2010. // playing sound is pre-empted for the new sound and the global FX priority
  2011. // is set to the new sound. If there is no sound playing then the new sound
  2012. // is simple played and the global priority is set
  2013.  
  2014. // is the digital fx system on-line?
  2015.  
  2016. if (!digital_enabled)
  2017.    return(0);
  2018.  
  2019. // is there a sound playing?
  2020.  
  2021. if (!Sound_Status() || (priority <= digital_FX_priority))
  2022.    {
  2023.    // start new sound
  2024.  
  2025.    Sound_Stop();
  2026.  
  2027.    Sound_Play((_sound_ptr)&digital_FX[the_effect]);
  2028.  
  2029.    // set the priority
  2030.  
  2031.    digital_FX_priority = priority;
  2032.  
  2033.    return(1);
  2034.  
  2035.    } // end if
  2036. else // the current sound is of higher priority
  2037.    return(0);
  2038.  
  2039. } // end Digital_FX_Play
  2040.  
  2041. /////////////////////////////////////////////////////////////////////////////
  2042.  
  2043. int Parse_Commands(int argc, char **argv)
  2044. {
  2045. // this function is used to parse the commands line parameters that are to be
  2046. // used as switched to enable different modes of operation
  2047.  
  2048. int index;  // looping variable
  2049.  
  2050. for (index=1; index<argc; index++)
  2051.     {
  2052.     // get the first character from the string
  2053.  
  2054.     switch(argv[index][0])
  2055.           {
  2056.  
  2057.           case 's': // enable sound effects
  2058.           case 'S':
  2059.                {
  2060.                digital_enabled=1;
  2061.                } break;
  2062.  
  2063.           case 'm': // enable nusic
  2064.           case 'M':
  2065.                {
  2066.                music_enabled=1;
  2067.                } break;
  2068.  
  2069.           // more commands would go here...
  2070.  
  2071.           default:break;
  2072.  
  2073.           } // end switch
  2074.  
  2075.     } // end for index
  2076.  
  2077. } // end Parse_Commands
  2078.  
  2079. /////////////////////////////////////////////////////////////////////////////
  2080.  
  2081. int Get_Modem_String(char *buffer)
  2082. {
  2083. // this function open up the modem intialization file named
  2084. // blaze.mod, if the file exists then
  2085.  
  2086. FILE *fp;
  2087.  
  2088. // try and open the file
  2089.  
  2090. if ((fp=fopen("blaze.mod","r"))==NULL)
  2091.    {
  2092.    strcpy(buffer,"");
  2093.    return(0);
  2094.    }
  2095.  
  2096. // else load in modem initialization string
  2097.  
  2098. fscanf(fp,"%s",buffer);
  2099.  
  2100. // close the file
  2101.  
  2102. fclose(fp);
  2103.  
  2104. return(1);
  2105.  
  2106. } // end Get_Modem_String
  2107.  
  2108. ////////////////////////////////////////////////////////////////////////////////
  2109.  
  2110. void Start_Up(void)
  2111. {
  2112.  
  2113. int index; // looping variable
  2114.  
  2115. // set the graphics mode to mode 13h
  2116.  
  2117. Set_Graphics_Mode(GRAPHICS_MODE13);
  2118.  
  2119. // start up music system
  2120.  
  2121. if (music_enabled)
  2122.    {
  2123.    Music_Init();
  2124.    Music_Play((music_ptr)&song,0);
  2125.    } // end if music enabled
  2126.  
  2127. // start up digital FX system
  2128.  
  2129. if (digital_enabled)
  2130.    {
  2131.    Digital_FX_Init();
  2132.    } // end if digital sound enabled
  2133.  
  2134. // put up Waite header
  2135.  
  2136. Intro_Waite();
  2137.  
  2138. // seed the random number generator with time
  2139.  
  2140. srand((unsigned int)Timer_Query());
  2141.  
  2142. // initialize font engine
  2143.  
  2144. Font_Engine_1(0,0,0,0,NULL,NULL);
  2145. Tech_Print(START_MESS_X,START_MESS_Y,"STARBLAZER 1.0 STARTING UP...",video_buffer);
  2146.  
  2147. Time_Delay(5);
  2148.  
  2149. // create the double buffer
  2150.  
  2151. Create_Double_Buffer(200);
  2152. Tech_Print(START_MESS_X,START_MESS_Y+16,"DOUBLE BUFFER CREATED",video_buffer);
  2153. Tech_Print(START_MESS_X,START_MESS_Y+24,"LANGUAGE TRANSLATION ENGAGED",video_buffer);
  2154.  
  2155. // install the keyboard driver
  2156.  
  2157. Keyboard_Install_Driver();
  2158. Tech_Print(START_MESS_X,START_MESS_Y+32,"NEURAL INTERFACE ACTIVATED",video_buffer);
  2159.  
  2160. // load in all gadget icons
  2161.  
  2162. Load_Icons();
  2163. Tech_Print(START_MESS_X,START_MESS_Y+40,"VISUAL ICONS LOADED",video_buffer);
  2164.  
  2165. // load in the ships
  2166.  
  2167. Load_Ships();
  2168. Tech_Print(START_MESS_X,START_MESS_Y+48,"SHIPS LOADED",video_buffer);
  2169.  
  2170. // assign ships to player and remote
  2171.  
  2172. Copy_Frames((sprite_ptr)&players_ship,(sprite_ptr)&gryfon_l);
  2173. Copy_Frames((sprite_ptr)&remotes_ship,(sprite_ptr)&raptor_r);
  2174.  
  2175. // start the asteroids up
  2176.  
  2177. Init_Asteroids(16,6,4);
  2178. Tech_Print(START_MESS_X,START_MESS_Y+56,"ASTEROID TRAJECTORIES COMPUTED",video_buffer);
  2179.  
  2180. // start the stars
  2181.  
  2182. Init_Stars();
  2183. Tech_Print(START_MESS_X,START_MESS_Y+64,"STARFIELD GENERATED",video_buffer);
  2184.  
  2185. // start the missiles
  2186.  
  2187. Init_Missiles();
  2188. Tech_Print(START_MESS_X,START_MESS_Y+72,"WEAPONS DAEMONS ONLINE",video_buffer);
  2189.  
  2190. // start the explosions
  2191.  
  2192. Init_Explosions();
  2193. Load_Explosions();
  2194. Init_Novas();
  2195. Tech_Print(START_MESS_X,START_MESS_Y+80,"EXPLOSION ANIMATION SYSTEM LOADED",video_buffer);
  2196.  
  2197. // initialize font engine
  2198.  
  2199. Font_Engine_1(0,0,0,0,NULL,NULL);
  2200. Tech_Print(START_MESS_X,START_MESS_Y+88,"FONT ENGINE ENGAGED",video_buffer);
  2201.  
  2202. // load the wormhole imagery
  2203.  
  2204. Load_Wormhole();
  2205. Init_Wormhole();
  2206. Tech_Print(START_MESS_X,START_MESS_Y+96,"WORM HOLE CREATED",video_buffer);
  2207.  
  2208. // load the aliens
  2209.  
  2210. Load_Alien();
  2211. Init_Alien();
  2212. Tech_Print(START_MESS_X,START_MESS_Y+104,"ENEMY AI GENERATED",video_buffer);
  2213.  
  2214. // the the fuel cells
  2215.  
  2216. Load_Fuel_Cells();
  2217. Init_Fuel_Cells();
  2218. Tech_Print(START_MESS_X,START_MESS_Y+112,"FUEL CELLS PLACED",video_buffer);
  2219.  
  2220. // load the heads up display
  2221.  
  2222. Load_Heads();
  2223. Init_Heads();
  2224. Tech_Print(START_MESS_X,START_MESS_Y+120,"HEADS UP DISPLAY ACTIVE",video_buffer);
  2225.  
  2226. // blink ok
  2227.  
  2228. Tech_Print(START_MESS_X,START_MESS_Y+136,"SYSTEM BIOS O.K.",video_buffer);
  2229.  
  2230. Digital_FX_Play(BLZBIOS_VOC,1);
  2231.  
  2232. for (index=0; index<3; index++)
  2233.     {
  2234.     // draw the message and the erase the message
  2235.     Font_Engine_1(START_MESS_X,START_MESS_Y+136,0,0,"SYSTEM BIOS O.K.",video_buffer);
  2236.     Time_Delay(8);
  2237.  
  2238.     Font_Engine_1(START_MESS_X,START_MESS_Y+136,0,0,"                ",video_buffer);
  2239.     Time_Delay(8);
  2240.  
  2241.     } // end for
  2242.  
  2243. // get rid off this sound to save a little memory (we are running low!)
  2244.  
  2245. Sound_Unload((_sound_ptr)&digital_FX[BLZBIOS_VOC]);
  2246.  
  2247. // do intro piece
  2248.  
  2249. Intro_Title();
  2250.  
  2251. // save the system pallete here because we are going to really thrash it!!!
  2252.  
  2253. Read_Palette(0,255,(RGB_palette_ptr)&game_palette);
  2254.  
  2255. } // end Start_Up
  2256.  
  2257.  
  2258.