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

  1.  
  2. // STARBLAZER - Version 1.0
  3.  
  4. // I N C L U D E S ///////////////////////////////////////////////////////////
  5.  
  6. #include <io.h>
  7. #include <conio.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. #include <bios.h>
  12. #include <fcntl.h>
  13. #include <memory.h>
  14. #include <malloc.h>
  15. #include <math.h>
  16. #include <string.h>
  17.  
  18. // include all of our stuff
  19.  
  20. #include "black3.h"
  21. #include "black4.h"
  22. #include "black5.h"
  23. #include "black6.h"
  24. #include "black8.h"
  25. #include "black9.h"
  26.  
  27. #include "blazem0.h"
  28.  
  29. // G L O B A L S  ////////////////////////////////////////////////////////////
  30.  
  31. pcx_picture image_pcx,  // general PCX image used to load background and imagery
  32.             image_controls;  // this holds the controls screen
  33.  
  34.  
  35. RGB_color color_1,color_2; // used for temporaries during color rotation
  36.  
  37. RGB_palette game_palette;  // this will hold the startup system palette
  38.                            // so we can restore it after screen FX
  39.  
  40. sprite button_1,        // the setup buttons
  41.        button_2,
  42.        button_3,
  43.        displays,        // the display bitmaps
  44.        starburst,       // the startburt sprite
  45.        gryfon_r,        // this holds a generic gryfon ship with remote colors
  46.        raptor_r,        // this holds a generic raptor ship with remote colors
  47.        gryfon_l,        // this holds a generic gryfon ship with local colors
  48.        raptor_l,        // this holds a generic raptor ship with local colors
  49.        players_ship,    // this is the players ship
  50.        remotes_ship,    // this is the remotes ship
  51.        wormhole,        // a stationary worm hole in the game
  52.        fuel_cells[NUM_FUEL_CELLS], // the stationary fuel cells in the game
  53.  
  54.        heads_text,      // heads up display sprites
  55.        heads_numbers,
  56.        heads_gauge;
  57.  
  58.  
  59. monster alien;                     // the alien saucer that comes out of the
  60.                                    // wormhole
  61.  
  62. sprite explosions[NUM_EXPLOSIONS]; // the explosions in the game
  63.  
  64. nova novas[NUM_NOVAS];             // the super nova explosions!
  65.  
  66. int active_explosions=0;           // number of active explosions
  67.  
  68. asteroid asteroids[NUM_ASTEROIDS]; // the asteroid fields
  69.  
  70. star stars[NUM_STARS];             // the star fields
  71.  
  72. particle missiles[NUM_MISSILES];   // all the projectiles
  73.  
  74. bitmap tech_font[NUM_TECH_FONT];   // the tech font bitmaps
  75.  
  76. int game_state = GAME_SETUP;  // the overall state of the game
  77.  
  78. int comm_port         = 0,    // currently selected comm port
  79.     players_ship_type = 0,    // currently selected local ship type
  80.     remotes_ship_type = 1;    // the remotes ships type
  81.  
  82.  
  83. int comm_port_to_address[2] = {COM_1,COM_2}; // converts the selected com port
  84.                                             // to an address
  85.  
  86. int master            = 1,    // the the player dials up a player
  87.     slave             = 0,    // then he is master else he is slave
  88.     linked            = 0,    // state of the modem communications system
  89.     winner = WINNER_NONE;     // the winner of the game
  90.  
  91. // the start up arrays used to differentiate the player and remote
  92.  
  93. // master is index 1, slave is index 0
  94.  
  95. int game_start_x[] = {1200,1300};
  96. int game_start_y[] = {1200,1200};
  97.  
  98. // the variables for the player
  99.  
  100. int players_last_x      = 0,    // the last postiion of player
  101.     players_last_y      = 0,
  102.     players_x           = 0,    // current players position
  103.     players_y           = 0,
  104.     players_dx          = 0,       // players position deltas since last frame
  105.     players_dy          = 0,
  106.     players_xv          = 0,       // velocity of ship
  107.     players_yv          = 0,
  108.     players_engine      = 0,       // state of engines
  109.     players_stability   = 8,       // how long it takes for gravity
  110.     players_flame_count = 0,       // used for engine flicker
  111.     players_flame_time  = 1,
  112.     players_gravity     = 0,       // current gravitron count
  113.     players_shields     = 0,       // state of the shields
  114.     players_shield_time = 0,       // how long sheilds have been on
  115.     players_cloak       = -1,      // state of the shields  -1 off 1 on
  116.     players_heads       = -1,      // state of heads up display
  117.     players_comm        = -1,      // state of comm link
  118.     players_scanner     = -1,      // space scanner
  119.     players_num_ships   = 3,       // number of players ship
  120.     players_shield_strength = 22000, // the amount of energy players shields have
  121.     players_energy          = 22000, // the amount of ship energy
  122.     players_score           = 0,     // the score of the player
  123.     players_active_missiles = 0,     // the number of missiles the player has fired
  124.     players_state           = ALIVE, // satte of player
  125.     players_death_count     = 0;     // how long death sequence will last
  126.  
  127.  
  128. int debounce_hud        = 0,       // these are used to debounce the players
  129.     debounce_scan       = 0,       // inputs one some keys
  130.     debounce_cloak      = 0,
  131.     debounce_thrust     = 0,
  132.     debounce_fire       = 0,
  133.     debounce_shields    = 0;
  134.  
  135. int refresh_heads = 0,              // used to track when hud needs refreshing
  136.     under_players_blip,             // these hold the pixels under the scanner
  137.     under_remotes_blip;             // blip image of the player and remote
  138.  
  139. // remote variables
  140.  
  141. int remotes_last_x      = 0,    // the last postiion of player
  142.     remotes_last_y      = 0,
  143.     remotes_x           = 0,    // current remotes position
  144.     remotes_y           = 0,
  145.     remotes_dx          = 0,       // remotes position deltas since last frame
  146.     remotes_dy          = 0,
  147.     remotes_xv          = 0,       // velocity of ship
  148.     remotes_yv          = 0,
  149.     remotes_engine      = 0,       // state of engines
  150.     remotes_stability   = 8,       // how long it takes for gravity
  151.     remotes_flame_count = 0,       // used for engine flicker
  152.     remotes_flame_time  = 1,
  153.     remotes_gravity     = 0,       // current gravitron count
  154.     remotes_shields     = 0,       // state of the shields
  155.     remotes_shield_time = 0,       // how long sheilds have been on
  156.     remotes_cloak       = -1,      // state of the shields  -1 off 1 on
  157.     remotes_heads       = -1,      // state of heads up display
  158.     remotes_comm        = -1,      // comm link
  159.     remotes_scanner     = -1,      // space scanner
  160.     remotes_num_ships   = 3,       // number of remotes ship
  161.     remotes_shield_strength = 22000, // the amount of energy remotes shields have
  162.     remotes_energy          = 22000, // the amount of ship energy
  163.     remotes_score           = 0,     // the remotes score
  164.     remotes_active_missiles = 0,     // the number of missiles the remote has fired
  165.     remotes_state           = ALIVE, // state of remote
  166.     remotes_death_count     = 0;     // how long death sequence will last
  167.  
  168. // unit motion look up tables
  169.  
  170. int motion_dx[16] = {0,1,2,2,3,2,2,1,0,-1,-2,-2,-3,-2,-2,-1};
  171. int motion_dy[16] = {-3,-2,-2,-1,0,1,2,2,3,2,2,1,0,-1,-2,-2};
  172.  
  173. // musical sequence information
  174.  
  175. int music_enabled   = 0,      // flags that enable music and sound FX
  176.     digital_enabled = 0;
  177.  
  178. int digital_FX_priority = 10; // the priority tracker of the current effect
  179.  
  180. int intro_sequence[] = {0,2,3,4,3,4,2,3,4,3,3};
  181. int intro_seq_index  = 0;
  182.  
  183. int game_sequence[] = {0+5,1+5,4+5,5+5,4+5,2+5,1+5,3+5,1+5,5+5,5+5,4+5,1+5,
  184.                        2+5,3+5,2+5,4+5,4+5};
  185.  
  186. int game_seq_index  = 0;
  187.  
  188. music song;    // the music structure
  189.  
  190. // sound fx stuff
  191.  
  192. _sound digital_FX[NUM_SOUND_FX];
  193.  
  194. // these colors are used for the shields on the ships
  195.  
  196. RGB_color  primary_red   = {63,0,0},    // pure red
  197.            primary_blue  = {0,0,63},    // pure blue
  198.            primary_green = {0,63,0},    // pure green
  199.            primary_black = {0,0,0},     // pure black
  200.            primary_white = {63,63,63},  // pure white
  201.  
  202.            remotes_shield_color={0,0,0}, // the current color of the remotes shield
  203.            players_shield_color={0,0,0}, // the current color of the players shields
  204.  
  205.            players_engine_color={0,0,0}, // the color or the players engine
  206.               remotes_engine_color={0,0,0}; // the color or the remotes engine
  207.  
  208. // the instruction pages
  209.  
  210. char *instructions[]={
  211.  
  212.                "STARBLAZER MISSION BRIEFING,       ",
  213.                "STAR DATE: 2595.001                ",
  214.                "                                   ",
  215.                "LONG RANGE SCANS HAVE DETECTED THE ",
  216.                "PRESENCE OF AN UNKNOWN VESSEL IN   ",
  217.                "THE TALLEON ASTEROID BELT. YOUR    ",
  218.                "MISSION IS SIMPLE: SEEK OUT THE    ",
  219.                "AGGRESSOR AND DESTROY IT.          ",
  220.                "                                   ",
  221.                "THE ASTEROID BELT IS FAIRLY SPARSE ",
  222.                "AND POSES MINIMAL THREAT TO YOUR   ",
  223.                "SHIP, BUT THE ASTEROIDS ARE DEADLY ",
  224.                "IF THEY BREACH YOUR SHIPS HULL.    ",
  225.                "                                   ",
  226.                "                                   ",
  227.                "                                   ",
  228.                "               1                   ",
  229.                "THE ASTEROID BELT EXISTS AT        ",
  230.                "COORDINATES (0.0) TO (2500.2500),  ",
  231.                "(USING THE STANDARD CENTRAL        ",
  232.                "NAVIGATION MULTIVARIATE VECTOR     ",
  233.                "POSITIONING SYSTEM). IF YOU TRY TO ",
  234.                "GO BEYOND THESE BOUNDS YOUR SHIP   ",
  235.                "WILL AUTOMATICALLY HYPERWARP TO    ",
  236.                "THE OPPOSITE EDGE OF THE SECTOR.   ",
  237.                "THUS,YOU CAN NOT LEAVE UNTIL YOU   ",
  238.                "HAVE COMPLETED YOUR MISSION!       ",
  239.                "                                   ",
  240.                "THERE HAVE ALSO BEEN REPORTS OF A  ",
  241.                "STABLE WORMHOLE IN THIS SECTOR. THE",
  242.                "WORMHOLE SEEMS TO BE A SINGLE POLE ",
  243.                "TRANSVERSE DISTURBANCE AND EMITS NO",
  244.                "GRAVITRONS.                        ",
  245.                "               2                   ",
  246.                "BUT REPORTS DO DETIAL MATTER AND   ",
  247.                "ENERGY EMMISIONS FROM THE WORMHOLE,",
  248.                "SO STAY CLEAR OF IT! IT IS LOCATED ",
  249.                "AT COORDINATES (1200.1200).        ",
  250.                "                                   ",
  251.                "FINALLY, A SMALL SHIP HAS BEEN     ",
  252.                "DETECTED,HOWEVER,IT SEEMS TO HAVE  ",
  253.                "NO HOSTILE INTENTIONS. MOREOVER,IT ",
  254.                "APPEARS THAT IT HAS A SYMETRICAL   ",
  255.                "SUB-SPACE FIELD SHIELDING SYSTEM   ",
  256.                "WHICH OUR BEST SCIENTISTS STILL DO ",
  257.                "NOT FULLY UNDERSTAND. NEEDLESS TO  ",
  258.                "SAY, YOUR WEAPONS ARE USELESS      ",
  259.                "AGAINST IT...                      ",
  260.                "                                   ",
  261.                "                                   ",
  262.                "               3                   ",
  263.                "SPECIFICATIONS                     ",
  264.                "                                   ",
  265.                "YOUR SHIP IS EQUIPPED WITH ALL OF  ",
  266.                "THE LATEST FEATURES INCLUDING:     ",
  267.                "HEADS UP DISPLAYS, SECTOR SCANNER, ",
  268.                "TWIN TACHION DRIVE, AUTOFIRE       ",
  269.                "PARTICLE CANNONS, PLASMA-FIELD-    ",
  270.                "EFFECT SUB-SPACE SHIELDS,AND A     ",
  271.                "CLOAKING DEVICE BUILT IN THE       ",
  272.                "ANTARUS SYSTEM SPECIFICALLY FOR    ",
  273.                "YOUR SHIP.                         ",
  274.                "                                   ",
  275.                "FINALLY, YOUR SHIP HAS THE NEW     ",
  276.                "PROTOTYPE SHAPE SHIFTING PLASMA    ",
  277.                "ENERGY HULL SYSTEM.                ",
  278.                "                                   ",
  279.                "               4                   ",
  280.                "ENTERING INTO COMBAT               ",
  281.                "                                   ",
  282.                "TO PLAY THE GAME YOU CAN EITHER    ",
  283.                "PLAY IN THE SOLO MODE FOR PRACTICE ",
  284.                "OR MODEM-2-MODEM. TO PLAY SOLO     ",
  285.                "MODE,SELECT THE SHIP YOU LIKE BY   ",
  286.                "USING THE SELECT SHIP OPTION ON    ",
  287.                "THE MAIN MENU. ONCE YOU HAVE       ",
  288.                "SELECTED THE SHIP OF YOUR CHOICE,  ",
  289.                "USE THE PLAY SOLO OPTION AND YOU   ",
  290.                "WILL BE WARPED TO THE TALLEON      ",
  291.                "ASTEROID BELT FOR A PRACTICE       ",
  292.                "SESSION.                           ",
  293.                "                                   ",
  294.                "                                   ",
  295.                "                                   ",
  296.                "               5                   ",
  297.                "TO PLAY MODEM-2-MODEM, YOU CAN     ",
  298.                "EITHER DIAL UP A COMPETITOR OR WAIT",
  299.                "FOR A COMPETITOR TO CALL. HOWEVER, ",
  300.                "BEFORE YOU CAN DO THIS, YOU MUST   ",
  301.                "SELECT WHICH COMMUNICATIONS PORT   ",
  302.                "YOUR MODEM IS ON. THIS CAN BE DONE ",
  303.                "WITH THE SELECT COMM PORT MENU     ",
  304.                "OPTION.                            ",
  305.                "                                   ",
  306.                "ONCE YOU HAVE SELECTED THE COMM    ",
  307.                "PORT THEN EITHER DIAL UP A         ",
  308.                "COMPETITOR WITH THE MAKE CONNECTION",
  309.                "MENU ITEM OR WAIT FOR A CALL VIA   ",
  310.                "THE WAIT FOR CONNECTION MENU ITEM. ",
  311.                "ONCE A CONNECTION HAS BEEN MADE YOU",
  312.                "WILL BE WARPED INTO BATTLE.        ",
  313.                "               6                   ",
  314.                "CONTROLING THE SHIP                ",
  315.                "                                   ",
  316.                "NAVIGATION:                        ",
  317.                "                                   ",
  318.                "TO NAVIAGATE THE SHIP USE THE RIGHT",
  319.                "AND LEFT ARROWS TO TURN. TO THRUST ",
  320.                "FOWARD USE THE UP ARROW.           ",
  321.                "                                   ",
  322.                "SHIELDS:                           ",
  323.                "                                   ",
  324.                "TO ENGAGE YOUR SHIELDS PRESS THE   ",
  325.                "<ALT> KEY. THEY WILL LAST FOR      ",
  326.                "APPROXIMATELY 5 SECS BEFORE        ",
  327.                "SHUTTING DOWN.                     ",
  328.                "                                   ",
  329.                "                                   ",
  330.                "               7                   ",
  331.                "CLOAKING DEVICE:                   ",
  332.                "                                   ",
  333.                "THE CLOAKING DEVICE CAN BE TOGGLED ",
  334.                "BY PRESSING THE <C> KEY. CLOAKING  ",
  335.                "EXHIBITS HIGH POWER CONSUMPTION AND",
  336.                "YOUR SHIELDS ARE USELESS WHEN      ",
  337.                "CLOAKED.                           ",
  338.                "                                   ",
  339.                "HEADS UP DISPLAY:                  ",
  340.                "                                   ",
  341.                "THE HEADS UP DISPLAY CAN BE TOGGLED",
  342.                "WITH THE <H> KEY. IT DISPLAYS      ",
  343.                "PERTAINENT TACTICAL INFORMATION IN ",
  344.                "REAL-TIME.                         ",
  345.                "                                   ",
  346.                "                                   ",
  347.                "               8                   ",
  348.                "LONG RANGE SCANNERS:               ",
  349.                "                                   ",
  350.                "YOUR SHIP IS EQUIPPED WITH A LONG  ",
  351.                "RANGE SECTOR SCAN THAT WILL DISPLAY",
  352.                "ALL OBJECTS IN THE SECTOR. YOUR    ",
  353.                "SHIP IS MARKED GREEN, THE ENEMY IS ",
  354.                "MARKED RED. ALL OTHER OBJECTS ARE  ",
  355.                "BLUE. ENGAGE AND DISENGAGE THE     ",
  356.                "SCANNER BY PRESSING THE <S> KEY.   ",
  357.                "                                   ",
  358.                "WEAPONS:                           ",
  359.                "                                   ",
  360.                "TO FIRE YOUR CANNONS PRESS THE     ",
  361.                "<SPACE> KEY. THEY SUPPORT THE ATF  ",
  362.                "OPTION(ALL SHIPS BUILT AFTER       ",
  363.                "2491.300 SUPPORT RAPID FIRE).      ",
  364.                "               9                   ",
  365.                "EXITING THE GAME:                  ",
  366.                "                                   ",
  367.                "THE GAME CAN BE EXITED BY PRESSING ",
  368.                "<ESC> AT ANY TIME. IF THERE IS A   ",
  369.                "CONNECTIONM IT WILL BE TERMINATED. ",
  370.                "AFTER EXITING THE GAME, YOU WILL BE",
  371.                "SENT BACK TO THE MAIN MENU SYSTEM. ",
  372.                "                                   ",
  373.                "WARNINGS:                          ",
  374.                "                                   ",
  375.                "YOUR SHIP CONSUMES A GREAT DEAL OF ",
  376.                "POWER SINCE IT IS A FIGHTER. YOU   ",
  377.                "CAN MINIMIZE THIS POWER CONSUMPTION",
  378.                "BY USING YOUR WEAPONS,THRUSTER,AND ",
  379.                "CLOAKING DEVICE SPARINGLY.         ",
  380.                "                                   ",
  381.                "               10                  ",
  382.                "YOUR SHIELDS OPERATE BY A FUSION   ",
  383.                "REACTION OF TRI-RUBIDIUM, THUS ONCE",
  384.                "YOUR SHIELD STRENGTH IS DEPLETED,  ",
  385.                "YOUR SHIELDS ARE INOPERABLE!       ",
  386.                "                                   ",
  387.                "THE ORIGINAL REPORTS OF THE SECTOR ",
  388.                "NOTE LARGE ENERGY FLUX SOURCES     ",
  389.                "FLOATING AROUND FROM TIME TO TIME. ",
  390.                "IT MAY BE POSSIBLE TO EXTRACT THE  ",
  391.                "ENERGY FROM THESE ENERGY PODS.     ",
  392.                "                                   ",
  393.                "                                   ",
  394.                "                                   ",
  395.                "                                   ",
  396.                "                                   ",
  397.                "                                   ",
  398.                "               11                  ",
  399.                "TO HELP YOUR SHIP FACILITATE THIS, ",
  400.                "AN EXTERNAL ENERGION ACCEPTOR      ",
  401.                "MATRIX HAS BEEN FITTED TO THE HULL ",
  402.                "OF YOUR SHIP. YOU MAY BE ABLE TO   ",
  403.                "ABSORB THE ENERGY OF THE PODS BY   ",
  404.                "COMING IN CONTACT WITH THEM, BUT   ",
  405.                "THIS IS THEORETICAL AND YOU DO SO  ",
  406.                "AT YOUR OWN RISK.                  ",
  407.                "                                   ",
  408.                "GOOD HUNTING                       ",
  409.                "MAY THE WIND BE AT YOUR BACK...    ",
  410.                "                                   ",
  411.                "                                   ",
  412.                "                                   ",
  413.                "                                   ",
  414.                "                                   ",
  415.                "          END BREIFING             "};
  416.  
  417. // these were in the main
  418.  
  419. int index,             // looping variable
  420.     sel,               // used for input
  421.     px_window,         // starting upper left hand corner of players view port
  422.     py_window,
  423.     result,            // result from comm system
  424.     response,          // result from comm system
  425.     players_key_state, // state of players input
  426.     remotes_key_state, // state pf remotes input
  427.  
  428.     sent_right =0,     // diagnostic counters to track number of
  429.     sent_left  =0,     // of input instructions both sent and received
  430.     sent_up    =0,
  431.     rec_right  =0,
  432.     rec_left   =0,
  433.     rec_up     =0;
  434.  
  435. unsigned char seed;    // a random number seed
  436.  
  437. char buffer[64],            // general buffer
  438.      modem_ini_string[64],  // used for extra modem intialization string
  439.      number[32],            // used to print strings
  440.      ch;                    // used for keyboard input
  441.  
  442. // F U N C T I O N S ////////////////////////////////////////////////////////
  443.  
  444. //////////////////////////////////////////////////////////////////////////////
  445.  
  446. void Setup_Interface(void)
  447. {
  448.  
  449. // this event loop is for the setup phase
  450.  
  451. if (keys_active>0)
  452.    {
  453.  
  454.    // what is user trying to do
  455.  
  456.        if (keyboard_state[MAKE_UP])
  457.               {
  458.               // erase the button and move it up
  459.               Sprite_Erase((sprite_ptr)&button_1,video_buffer);
  460.  
  461.               button_1.y-=12;
  462.  
  463.               // test if we need to wrap around bottom
  464.  
  465.               if (--button_1.counter_1 < 0)
  466.                  {
  467.                  button_1.counter_1 = 6;
  468.                  button_1.y         = 63+6*12;
  469.                  } // end if wrap around
  470.  
  471.               // scan and draw button
  472.               Sprite_Under((sprite_ptr)&button_1,video_buffer);
  473.               Sprite_Draw((sprite_ptr)&button_1,video_buffer,1);
  474.  
  475.               Digital_FX_Play(BLZKEY_VOC,2);
  476.  
  477.               Time_Delay(1);
  478.  
  479.               } // end if up
  480.  
  481.        else
  482.        if (keyboard_state[MAKE_DOWN])
  483.               {
  484.               // erase the button and move it down
  485.               Sprite_Erase((sprite_ptr)&button_1,video_buffer);
  486.  
  487.               button_1.y+=12;
  488.  
  489.               // test if we need to wrap around top
  490.  
  491.               if (++button_1.counter_1 > 6)
  492.                  {
  493.                  button_1.counter_1 = 0;
  494.                  button_1.y         = 63;
  495.                  } // end if wrap around
  496.  
  497.               // scan and draw button
  498.               Sprite_Under((sprite_ptr)&button_1,video_buffer);
  499.               Sprite_Draw((sprite_ptr)&button_1,video_buffer,1);
  500.  
  501.               Digital_FX_Play(BLZKEY_VOC,2);
  502.  
  503.               Time_Delay(1);
  504.  
  505.               } // end if down
  506.         else
  507.         if (keyboard_state[MAKE_ENTER] )
  508.               {
  509.  
  510.               // illuminate button for a second
  511.  
  512.               // draw button down
  513.  
  514.               button_1.curr_frame = 1;
  515.               Sprite_Draw((sprite_ptr)&button_1,video_buffer,1);
  516.  
  517.               Digital_FX_Play(BLZKEY_VOC,2);
  518.  
  519.               Time_Delay(5);
  520.  
  521.               // now draw button up
  522.  
  523.               button_1.curr_frame = 0;
  524.               Sprite_Draw((sprite_ptr)&button_1,video_buffer,1);
  525.  
  526.               // test which item is being selected
  527.  
  528.               switch(button_1.counter_1)
  529.                     {
  530.                     case SETUP_PLAY_SOLO:
  531.                          {
  532.  
  533.                          Clear_Display(0);
  534.  
  535.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  536.                                        "ENTERING ARENA",
  537.                                        video_buffer);
  538.  
  539.                          // move to running state
  540.  
  541.                          game_state = GAME_RUNNING;
  542.  
  543.                          Time_Delay(5);
  544.  
  545.                          } break;
  546.  
  547.                     case SETUP_MAKE_CONNECTION:
  548.                          {
  549.  
  550.                          Clear_Display(0);
  551.  
  552.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  553.                                        "ENTER NUMBER",
  554.                                        video_buffer);
  555.  
  556.  
  557.  
  558.  
  559.                          // remove the keyboard handler,
  560.                          // makes user input easier for strings
  561.  
  562.                          Keyboard_Remove_Driver();
  563.  
  564.                          result = Get_Line(number);
  565.  
  566.                          // replace our handler
  567.  
  568.                          Keyboard_Install_Driver();
  569.  
  570.                          // get the number
  571.  
  572.                          if (!result)
  573.                             {
  574.  
  575.                             Clear_Display(0);
  576.  
  577.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  578.                                           "ABORTED...",
  579.                                           video_buffer);
  580.  
  581.                             Digital_FX_Play(BLZABRT_VOC,1);
  582.  
  583.                             Time_Delay(5);
  584.  
  585.                             Clear_Display(0);
  586.  
  587.                             break;
  588.  
  589.                             } // end if aborted input
  590.  
  591.                          // make a connection
  592.  
  593.                          // open com port
  594.  
  595.                          Modem_Control(MODEM_DTR_ON);
  596.  
  597.                          Serial_Open(comm_port_to_address[comm_port] ,SERIAL_BAUD_2400,SERIAL_PARITY_NONE |
  598.                                      SERIAL_BITS_8 | SERIAL_STOP_1);
  599.  
  600.                          Serial_Flush();
  601.  
  602.                          // initialize modem with standard initialization
  603.                          // plus any added init string in blaze.mod
  604.  
  605.                          Initialize_Modem(modem_ini_string);
  606.  
  607.                          // let user know whats going on
  608.  
  609.                          Clear_Display(0);
  610.  
  611.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  612.                                        "DIALING:",
  613.                                        video_buffer);
  614.  
  615.  
  616.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2+8,0,0,
  617.                                        number,
  618.                                        video_buffer);
  619.  
  620.                          Digital_FX_Play(BLZDIAL_VOC,1);
  621.  
  622.                          result = Make_Connection(number);
  623.  
  624.                          if (result==MODEM_CONNECT_1200 ||
  625.                              result==MODEM_CONNECT_2400 ||
  626.                              result==MODEM_CONNECT      ||
  627.                              result==MODEM_CARRIER_2400)
  628.                             {
  629.                             // set game to linked and local to
  630.                             // master
  631.  
  632.                             linked=1;
  633.                             master=1;
  634.                             slave=0;
  635.  
  636.                             game_state = GAME_LINKING;
  637.  
  638.                             Clear_Display(0);
  639.  
  640.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  641.                                           "CONNECTED!",
  642.                                           video_buffer);
  643.  
  644.                             Time_Delay(5);
  645.  
  646.                             Clear_Display(0);
  647.  
  648.                             } //end if connection made
  649.                          else
  650.                          if (result==MODEM_USER_ABORT)
  651.                             {
  652.                             // close down serial connection
  653.  
  654.                             Hang_Up();
  655.                             Serial_Flush();
  656.                             Serial_Close();
  657.  
  658.                             // print that selection was aborted
  659.  
  660.                             Clear_Display(0);
  661.  
  662.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  663.                                           "ABORTED...",
  664.                                           video_buffer);
  665.  
  666.                             Digital_FX_Play(BLZABRT_VOC,1);
  667.  
  668.                             Time_Delay(5);
  669.  
  670.                             Clear_Display(0);
  671.  
  672.                             } // end if user aborted
  673.                          else
  674.                             {
  675.                             // close down serial connection
  676.  
  677.                             Hang_Up();
  678.                             Serial_Flush();
  679.                             Serial_Close();
  680.  
  681.                             // print that selection was aborted
  682.  
  683.                             Clear_Display(0);
  684.  
  685.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  686.                                           "COMM PROBLEM",
  687.                                           video_buffer);
  688.  
  689.                             Time_Delay(5);
  690.  
  691.                             Clear_Display(0);
  692.  
  693.                             } // end if user aborted
  694.                          } break;
  695.  
  696.                     case SETUP_WAIT_FOR_CONNECTION:
  697.                          {
  698.  
  699.                          Clear_Display(0);
  700.  
  701.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  702.                                        "ANSWER MODE",
  703.                                        video_buffer);
  704.  
  705.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2+8,0,0,
  706.                                        "ENABLED...",
  707.                                        video_buffer);
  708.  
  709.                          // open com port
  710.  
  711.                          Modem_Control(MODEM_DTR_ON);
  712.  
  713.                          Serial_Open(comm_port_to_address[comm_port] ,SERIAL_BAUD_2400,SERIAL_PARITY_NONE |
  714.                                      SERIAL_BITS_8 | SERIAL_STOP_1);
  715.  
  716.                          Serial_Flush();
  717.  
  718.                          // wait for a call
  719.  
  720.  
  721.                          // initialize modem with standard initialization
  722.                          // plus any added init string in blaze.mod
  723.  
  724.                          Initialize_Modem(modem_ini_string);
  725.  
  726.                          result = Wait_For_Connection();
  727.  
  728.                          // is the connection message 2400?
  729.  
  730.                          if (result==MODEM_CONNECT_1200 ||
  731.                              result==MODEM_CONNECT_2400 ||
  732.                              result==MODEM_CONNECT      ||
  733.                              result==MODEM_CARRIER_2400)
  734.                             {
  735.                             // set game state to linked and local
  736.                             // to slave
  737.  
  738.                             linked=1;
  739.                             master = 0;
  740.                             slave = 1;
  741.  
  742.                             game_state = GAME_LINKING;
  743.  
  744.                             Clear_Display(0);
  745.  
  746.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  747.                                           "CONNECTED!",
  748.                                           video_buffer);
  749.  
  750.                             Time_Delay(5);
  751.  
  752.                             Clear_Display(0);
  753.  
  754.                             } // end if connection made
  755.                          else
  756.                          if (result==MODEM_USER_ABORT)
  757.                             {
  758.                             // user bailed so close down serial
  759.  
  760.                             Hang_Up();
  761.                             Serial_Flush();
  762.                             Serial_Close();
  763.  
  764.                             Clear_Display(0);
  765.  
  766.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  767.                                           "ABORTED...",
  768.                                           video_buffer);
  769.  
  770.                             // play sound fx
  771.  
  772.                             Digital_FX_Play(BLZABRT_VOC,1);
  773.  
  774.                             Time_Delay(5);
  775.  
  776.                             Clear_Display(0);
  777.  
  778.                             } // end if user aborted
  779.                          else
  780.                             {
  781.                             // close down serial connection
  782.  
  783.                             Hang_Up();
  784.                             Serial_Flush();
  785.                             Serial_Close();
  786.  
  787.                             // print that selection was aborted
  788.  
  789.                             Clear_Display(0);
  790.  
  791.                             Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  792.                                           "COMM PROBLEM",
  793.                                           video_buffer);
  794.  
  795.                             Time_Delay(5);
  796.  
  797.                             Clear_Display(0);
  798.  
  799.                             } // end if user aborted
  800.  
  801.                          } break;
  802.  
  803.                     case SETUP_SELECT_SHIP:
  804.                          {
  805.  
  806.                          Clear_Display(0);
  807.  
  808.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  809.                                        "GRYFON  RAPTOR",
  810.                                        video_buffer);
  811.  
  812.                          // draw ships
  813.  
  814.                          displays.curr_frame = DISPLAY_IMG_SHIPS;
  815.  
  816.                          Sprite_Draw((sprite_ptr)&displays,video_buffer,1);
  817.  
  818.                          // let user select one
  819.  
  820.                          sel = Display_Select(players_ship_type);
  821.  
  822.                          // test if user changed ship
  823.  
  824.                          if (sel!=-1)
  825.                             {
  826.                             players_ship_type = sel;
  827.  
  828.                             // set up sprite
  829.  
  830.                             if (players_ship_type==GRYFON_SHIP)
  831.                                 {
  832.                                 Copy_Frames((sprite_ptr)&players_ship,(sprite_ptr)&gryfon_l);
  833.                                 }
  834.                             else
  835.                                 {
  836.                                 Copy_Frames((sprite_ptr)&players_ship,(sprite_ptr)&raptor_l);
  837.  
  838.                                 }
  839.                             } // end if
  840.  
  841.                          } break;
  842.  
  843.                     case SETUP_SET_COMM_PORT:
  844.                          {
  845.  
  846.                          Clear_Display(0);
  847.  
  848.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  849.                                        "COMM 1  COMM 2",
  850.                                        video_buffer);
  851.  
  852.                          // draw comm ports
  853.  
  854.                          displays.curr_frame = DISPLAY_IMG_PORTS;
  855.  
  856.                          Sprite_Draw((sprite_ptr)&displays,video_buffer,1);
  857.  
  858.                          // let user select one
  859.  
  860.                          sel = Display_Select(comm_port);
  861.  
  862.                          // test if user changed selection
  863.  
  864.                          if (sel!=-1)
  865.                             {
  866.                             // change comm port
  867.  
  868.                             comm_port=sel;
  869.  
  870.                             } // end if
  871.  
  872.  
  873.                          } break;
  874.  
  875.                     case SETUP_BRIEFING:
  876.                          {
  877.                          // show user instructions
  878.  
  879.                          Digital_FX_Play(BLZMISS_VOC ,1);
  880.  
  881.                          Intro_Briefing();
  882.  
  883.                          // redisplay intro controls
  884.  
  885.                          Intro_Controls();
  886.  
  887.                          } break;
  888.  
  889.                     case SETUP_EXIT:
  890.                          {
  891.                          // set state to game over
  892.  
  893.                          game_state=GAME_OVER;
  894.  
  895.                          Clear_Display(0);
  896.  
  897.                          Font_Engine_1(DISPLAY_X+2,DISPLAY_Y+2,0,0,
  898.                                        "EXITING SYSTEM",
  899.                                        video_buffer);
  900.  
  901.                          } break;
  902.  
  903.                     default:break;
  904.  
  905.                     } // end switch
  906.  
  907.               } // end if enter
  908.  
  909.    } // end if keyboard hit
  910.  
  911. } // end Setup_Interface
  912.  
  913.  
  914. // M A I N //////////////////////////////////////////////////////////////////
  915.  
  916. void main(int argc, char **argv)
  917. {
  918.  
  919. // the main controls most of the platyer and remote logic, normally we would
  920. // probably move most of the code into functions, but for instructional purposes
  921. // this is easier to follow, believe me there are already enough function calls
  922. // to make your head spin!
  923.  
  924. // parse the command line and set up configuration
  925.  
  926. Parse_Commands(argc,argv);
  927.  
  928. // get the modem initialization string
  929.  
  930. Get_Modem_String(modem_ini_string);
  931.  
  932. printf("\nExtra modem initialization string = %s",modem_ini_string);
  933.  
  934. Time_Delay(25);
  935.  
  936. // start up game
  937.  
  938. Start_Up();
  939.  
  940. // main event loop ///////////////////////////////////////////////////////////
  941.  
  942. while(game_state!=GAME_OVER)
  943.      {
  944.      // test the overall game state
  945.  
  946.      if (game_state==GAME_SETUP)
  947.         {
  948.         // if machines were linked then break connection
  949.  
  950.         if (linked)
  951.            {
  952.            // close down serial connection
  953.  
  954.            Hang_Up();
  955.            Serial_Flush();
  956.            Serial_Close();
  957.  
  958.            // reset linked flag
  959.  
  960.            linked = 0;
  961.  
  962.            } // end if
  963.  
  964.         // user in in the setup state
  965.  
  966.         Intro_Controls();
  967.  
  968.         // restore pallete
  969.  
  970.         Write_Palette(0,255,(RGB_palette_ptr)&game_palette);
  971.  
  972.         // enter setup event loop
  973.  
  974.         while(game_state==GAME_SETUP)
  975.              {
  976.  
  977.              // perform setup input querying and preocessing
  978.  
  979.              Setup_Interface();
  980.  
  981.              // perform special effects to control panel
  982.  
  983.              Panel_FX();
  984.  
  985.              // slow things down a bit
  986.  
  987.              Time_Delay(1);
  988.  
  989.              // check on music
  990.  
  991.              if (music_enabled)
  992.                 {
  993.                 // test if piece is complete or has been stopped
  994.  
  995.                 if (Music_Status()==2 || Music_Status()==0)
  996.                    {
  997.                    // advance to next sequence
  998.  
  999.                    if (++intro_seq_index==11)
  1000.                       intro_seq_index=0;
  1001.  
  1002.                    Music_Play((music_ptr)&song,intro_sequence[intro_seq_index]);
  1003.  
  1004.                    } // end if
  1005.  
  1006.                 } // end if music enabled
  1007.  
  1008.              } // end setup event loop
  1009.  
  1010.         } // end if in control state
  1011.  
  1012. ///////////////////////////////////////////////////////////////////////////////
  1013.      else
  1014.      if (game_state==GAME_LINKING)
  1015.         {
  1016.  
  1017.         // wait a second to machine sure otehr machine is linked
  1018.  
  1019.         Time_Delay(DELAY_2_SECOND);
  1020.  
  1021.         // test if this machine is master or slave and negotiate
  1022.         // connection
  1023.  
  1024.         if (master)
  1025.            {
  1026.  
  1027.            // send master signal
  1028.  
  1029.            Serial_Write('M');
  1030.  
  1031.            // send ship type
  1032.  
  1033.            Serial_Write('0'+players_ship_type);
  1034.  
  1035.            // this is a crucial function call, both machines must use the same
  1036.            // random sequence, this is accomplised by the master sending a seed
  1037.            // to the remote to be used as the seed for the random number
  1038.            // generator
  1039.  
  1040.            // send random seed
  1041.  
  1042.            seed = (unsigned char)Timer_Query();
  1043.  
  1044.            Serial_Write(seed);
  1045.  
  1046.            // seed local random number generator
  1047.  
  1048.            srand(seed);
  1049.  
  1050.  
  1051.            // wait for acknowledge
  1052.  
  1053.            response = Serial_Read_Wait();
  1054.  
  1055.            if (response=='S')
  1056.               {
  1057.  
  1058.               // get remotes ship type
  1059.  
  1060.               response = Serial_Read_Wait();
  1061.  
  1062.               remotes_ship_type = response - '0';
  1063.  
  1064.               // move game state into running mode
  1065.  
  1066.               game_state=GAME_RUNNING;
  1067.  
  1068.               } // end if linked
  1069.  
  1070.            } // end if master
  1071.         else
  1072.         if (slave)
  1073.            {
  1074.            // send master signal
  1075.  
  1076.            Serial_Write('S');
  1077.  
  1078.            // send ship type
  1079.  
  1080.            Serial_Write('0'+players_ship_type);
  1081.  
  1082.            // wait for a master signal
  1083.  
  1084.            // wait for acknowledge
  1085.  
  1086.            response = Serial_Read_Wait();
  1087.  
  1088.            if (response=='M')
  1089.               {
  1090.               // get remotes ship type
  1091.  
  1092.               response = Serial_Read_Wait();
  1093.  
  1094.               remotes_ship_type = response - '0';
  1095.  
  1096.               // the next byte is the random number generator seed
  1097.  
  1098.               seed = (unsigned char)Serial_Read_Wait();
  1099.  
  1100.               srand(seed);
  1101.  
  1102.  
  1103.               // move game state into running mode
  1104.  
  1105.               game_state=GAME_RUNNING;
  1106.  
  1107.               } // end if linked
  1108.  
  1109.            } // end if slave
  1110.  
  1111.         } // end if game linking
  1112.  
  1113. ////////////////////////////////////////////////////////////////////////////////
  1114.  
  1115.      else
  1116.      if (game_state==GAME_RUNNING)
  1117.         {
  1118.  
  1119.         // restore pallete
  1120.  
  1121.         Write_Palette(0,255,(RGB_palette_ptr)&game_palette);
  1122.  
  1123.         // turn shields off
  1124.  
  1125.         Shield_Control(THE_PLAYER,0);
  1126.         Shield_Control(THE_REMOTE,0);
  1127.  
  1128.         // reset system variables
  1129.  
  1130.         Reset_System();
  1131.  
  1132.         // select engine colors
  1133.  
  1134.         if (players_ship_type==GRYFON_SHIP)
  1135.            players_engine_color = primary_white;
  1136.         else
  1137.            players_engine_color = primary_green;
  1138.  
  1139.         if (remotes_ship_type==GRYFON_SHIP)
  1140.            remotes_engine_color = primary_white;
  1141.         else
  1142.            remotes_engine_color = primary_green;
  1143.  
  1144.         // set up remote ships ship type
  1145.  
  1146.         if (remotes_ship_type==GRYFON_SHIP)
  1147.             Copy_Frames((sprite_ptr)&remotes_ship,(sprite_ptr)&gryfon_r);
  1148.         else
  1149.             Copy_Frames((sprite_ptr)&remotes_ship,(sprite_ptr)&raptor_r);
  1150.  
  1151.         // restart everything
  1152.  
  1153.         Init_Wormhole();
  1154.         Init_Stars();
  1155.         Init_Missiles();
  1156.         Init_Asteroids(16,6,4);
  1157.         Init_Explosions();
  1158.         Init_Novas();
  1159.         Init_Alien();
  1160.         Init_Heads();
  1161.         Init_Fuel_Cells();
  1162.  
  1163.         // start music
  1164.  
  1165.         if (music_enabled)
  1166.            {
  1167.            Music_Stop();
  1168.  
  1169.            game_seq_index=0;
  1170.  
  1171.            Music_Play((music_ptr)&song,game_sequence[game_seq_index]);
  1172.  
  1173.            } // end if music enabled
  1174.  
  1175.         Digital_FX_Play(BLZENTR_VOC,1);
  1176.  
  1177.         // clear double buffer
  1178.  
  1179.         Fill_Double_Buffer(0);
  1180.  
  1181.         // scan under all objects
  1182.  
  1183.         Under_Wormhole();
  1184.         Under_Asteroids();
  1185.         Under_Stars();
  1186.         Under_Fuel_Cells();
  1187.  
  1188. // BEGIN PLAYER ///////////////////////////////////////////////////////////////
  1189.  
  1190.         Sprite_Under((sprite_ptr)&players_ship,double_buffer);
  1191.  
  1192. // END PLAYER ///////////////////////////////////////////////////////////////
  1193.  
  1194. // BEGIN REMOTE ///////////////////////////////////////////////////////////////
  1195.  
  1196.         px_window = players_x - 160+11;
  1197.         py_window = players_y - 100+9;
  1198.  
  1199.         remotes_ship.x = remotes_x - px_window;
  1200.         remotes_ship.y = remotes_y - py_window;
  1201.  
  1202.         Sprite_Under_Clip((sprite_ptr)&remotes_ship,double_buffer);
  1203.  
  1204. // END REMOTE ///////////////////////////////////////////////////////////////
  1205.  
  1206.         // enter into the main game loop
  1207.  
  1208.         while(game_state==GAME_RUNNING)
  1209.              {
  1210.  
  1211.              // compute starting time of this frame
  1212.  
  1213.              starting_time = Timer_Query();
  1214.  
  1215.              // reset all vars
  1216.  
  1217.              refresh_heads=0;
  1218.  
  1219.              // flag engines off
  1220.  
  1221.              players_engine = 0;
  1222.              remotes_engine = 0;
  1223.  
  1224.              // erase all objects
  1225.  
  1226.              Erase_Fuel_Cells();
  1227.              Erase_Alien();
  1228.              Erase_Wormhole();
  1229.              Erase_Stars();
  1230.              Erase_Asteroids();
  1231.              Erase_Missiles();
  1232.              Erase_Explosions();
  1233.              Erase_Novas();
  1234.  
  1235.              // erase scanner data
  1236.  
  1237.              if (players_scanner==1)
  1238.                 Erase_Blips();
  1239.  
  1240. // BEGIN PLAYER//////////////////////////////////////////////////////////////////
  1241.  
  1242.  
  1243.              Sprite_Erase((sprite_ptr)&players_ship,double_buffer);
  1244.  
  1245.  
  1246. // END PLAYER///////////////////////////////////////////////////////////////////
  1247.  
  1248. // BEGIN REMOTE//////////////////////////////////////////////////////////////////
  1249.  
  1250.  
  1251.              Sprite_Erase_Clip((sprite_ptr)&remotes_ship,double_buffer);
  1252.  
  1253.  
  1254. // END REMOTE///////////////////////////////////////////////////////////////////
  1255.  
  1256.  
  1257. // BEGIN PLAYER//////////////////////////////////////////////////////////////////
  1258.  
  1259.              // move player
  1260.  
  1261.              players_last_x = players_x;
  1262.              players_last_y = players_y;
  1263.  
  1264.              // test if a key is depressed
  1265.  
  1266.              players_key_state = 0;
  1267.  
  1268.              if (players_state==ALIVE)
  1269.              {
  1270.              if (keys_active > 0)
  1271.                 {
  1272.                 // which key ?
  1273.  
  1274.                 if (keyboard_state[MAKE_LEFT] )
  1275.                      {
  1276.                      // rotate left
  1277.  
  1278.                      if (--players_ship.curr_frame < 0)
  1279.                         players_ship.curr_frame = 15;
  1280.  
  1281.                      // add this action to key state
  1282.  
  1283.                      players_key_state += REMOTE_LEFT;
  1284.  
  1285. #if DEBUG
  1286.                      sent_left++;
  1287. #endif
  1288.  
  1289.                      } // end if left
  1290.                 else
  1291.                 if (keyboard_state[MAKE_RIGHT])
  1292.                      {
  1293.                      // rotate right
  1294.  
  1295.                      if (++players_ship.curr_frame > 15)
  1296.                         players_ship.curr_frame = 0;
  1297.  
  1298.                      // add this action to key state
  1299.  
  1300.                      players_key_state += REMOTE_RIGHT;
  1301.  
  1302. #if DEBUG
  1303.                      sent_right++;
  1304. #endif
  1305.  
  1306.  
  1307.                      } // end if right
  1308.  
  1309.                 if (keyboard_state[MAKE_UP] && players_energy>0)
  1310.                      {
  1311.                      // thrust foward
  1312.  
  1313.                      players_xv+=motion_dx[players_ship.curr_frame];
  1314.                      players_yv+=motion_dy[players_ship.curr_frame];
  1315.  
  1316.                      // bound maximum velocity
  1317.  
  1318.                      if (players_xv > 8)
  1319.                         players_xv=8;
  1320.                      else
  1321.                      if (players_xv <-8)
  1322.                         players_xv=-8;
  1323.  
  1324.                      if (players_yv > 8)
  1325.                         players_yv=8;
  1326.                      else
  1327.                      if (players_yv <-8)
  1328.                         players_yv=-8;
  1329.  
  1330.                      // flag engines on
  1331.  
  1332.                      players_engine = 1;
  1333.  
  1334.                      players_energy--;
  1335.  
  1336.                      // add this action to key state
  1337.  
  1338.                      players_key_state += REMOTE_THRUST;
  1339.  
  1340. #if DEBUG
  1341.                      sent_up++;
  1342. #endif
  1343.  
  1344.                      } // end if up
  1345.  
  1346.                 if (keyboard_state[MAKE_SPACE] && !debounce_fire &&
  1347.                     players_active_missiles < 5 && players_energy>0)
  1348.                      {
  1349.                      // fire weapons
  1350.  
  1351.                      Start_Missile(players_x+SHIP_WIDTH/2,players_y+SHIP_HEIGHT/2,
  1352.                                    players_xv+2*motion_dx[players_ship.curr_frame],
  1353.                                    players_yv+2*motion_dy[players_ship.curr_frame],
  1354.                                    10,PLAYER_MISSILE);
  1355.  
  1356.                      // update energy
  1357.  
  1358.                      players_energy-=5;
  1359.  
  1360.                      // now there is one more active missile
  1361.  
  1362.                      players_active_missiles++;
  1363.  
  1364.                      // add this action to key state
  1365.  
  1366.                      players_key_state += REMOTE_FIRE;
  1367.  
  1368.                      // set fire button debounce
  1369.  
  1370.                      debounce_fire = 1;
  1371.  
  1372.                      } // end if weapons
  1373.  
  1374.                  // instrumentation
  1375.  
  1376.                  if (keyboard_state[MAKE_ALT] && !debounce_shields &&
  1377.                      players_cloak==-1 && players_shield_strength>0)
  1378.                      {
  1379.                      // turn the shields on
  1380.  
  1381.                      Shield_Control(THE_PLAYER,1);
  1382.  
  1383.                      Digital_FX_Play(BLZSHLD_VOC,1);
  1384.  
  1385.                      // start timer
  1386.  
  1387.                      players_shield_time = 100;
  1388.  
  1389.                      // add this action to key state
  1390.  
  1391.                      players_key_state += REMOTE_SHIELDS;
  1392.  
  1393.                      // request debounce
  1394.  
  1395.                      debounce_shields = 1;
  1396.  
  1397.                      } // end if shields
  1398.                  else
  1399.                  if (keyboard_state[MAKE_C] && !debounce_cloak && players_energy>0)
  1400.                       {
  1401.                       // toggle the cloaking device
  1402.  
  1403.                       players_cloak = -players_cloak;
  1404.  
  1405.                       Digital_FX_Play(BLZCLK_VOC ,1);
  1406.  
  1407.                       // refresh heads up if it's on
  1408.  
  1409.                       refresh_heads=1;
  1410.  
  1411.                       // request debounce
  1412.  
  1413.                       debounce_cloak = 1;
  1414.  
  1415.                       // add this action to key state
  1416.  
  1417.                       players_key_state += REMOTE_CLOAK;
  1418.  
  1419.                       } // emd if cloak
  1420.                 else
  1421.                 if (keyboard_state[MAKE_H] && !debounce_hud)
  1422.                      {
  1423.                      // toggle the display status
  1424.  
  1425.                      players_heads=-players_heads;
  1426.  
  1427.                      // test if it's on or off
  1428.  
  1429.                      if (players_heads==1)
  1430.                         {
  1431.                         Draw_Heads();
  1432.                         Digital_FX_Play(BLZTAC_VOC ,1);
  1433.                         }
  1434.                      else
  1435.                         Erase_Heads();
  1436.  
  1437.  
  1438.                      // request debounce
  1439.  
  1440.                      debounce_hud = 1;
  1441.  
  1442.                      } // end if heads
  1443.                 else
  1444.                 if (keyboard_state[MAKE_S] && !debounce_scan)
  1445.                      {
  1446.                      // toggle the scanner
  1447.  
  1448.                      players_scanner=-players_scanner;
  1449.  
  1450.                      // test if it's on or off
  1451.  
  1452.                      if (players_scanner==1)
  1453.                         {
  1454.                         Draw_Scanner();
  1455.                         Digital_FX_Play(BLZSCN_VOC ,1);
  1456.                         }
  1457.                      else
  1458.                         Erase_Scanner();
  1459.  
  1460.                      // refresh heads up if it's on
  1461.  
  1462.                      refresh_heads=1;
  1463.  
  1464.                      // request debounce
  1465.  
  1466.                      debounce_scan = 1;
  1467.  
  1468.                      } // end if scanner
  1469.                 else
  1470.                 if (keyboard_state[MAKE_ESC])
  1471.                      {
  1472.                      game_state = GAME_SETUP;
  1473.  
  1474.                      // add this action to key state
  1475.  
  1476.                      players_key_state += REMOTE_ESC;
  1477.  
  1478.                      } // end if escape
  1479.  
  1480.                 } // end if kbhit
  1481.  
  1482.              } // end if player alive
  1483.  
  1484.                // debounce section
  1485.  
  1486.                if (!keyboard_state[MAKE_C])
  1487.                    debounce_cloak=0;
  1488.  
  1489.                if (!keyboard_state[MAKE_H])
  1490.                   debounce_hud=0;
  1491.  
  1492.                if (!keyboard_state[MAKE_S])
  1493.                   debounce_scan=0;
  1494.  
  1495.                if (!keyboard_state[MAKE_SPACE])
  1496.                   debounce_fire=0;
  1497.  
  1498.                if (!keyboard_state[MAKE_ALT])
  1499.                   debounce_shields=0;
  1500.  
  1501.              // send local players data to remote machine
  1502.  
  1503.              if (linked)
  1504.                 {
  1505.  
  1506.                 Serial_Write(players_key_state);
  1507.  
  1508.                 } // end if linked
  1509.  
  1510.              // update energy loss due to normal operation
  1511.  
  1512.              if (players_cloak==1)
  1513.                 players_energy--;
  1514.  
  1515.              if (players_energy>0)
  1516.                 {
  1517.                 players_energy--;
  1518.  
  1519.                 // enable refresh
  1520.  
  1521.                 refresh_heads = 1;
  1522.  
  1523.                 } // end energy update
  1524.              else
  1525.                 players_energy=0;
  1526.  
  1527.  
  1528.              // test if shields are on
  1529.  
  1530.              if (players_shields==1)
  1531.                 {
  1532.                 players_shield_strength-=8;
  1533.  
  1534.                 if (players_shield_strength<0)
  1535.                     players_shield_strength = 0;
  1536.  
  1537.                 // enable refresh
  1538.  
  1539.                 refresh_heads = 1;
  1540.  
  1541.                 } // end if shields are on
  1542.  
  1543.              // test if hud needs refreshing
  1544.  
  1545.              if (players_heads==1 && refresh_heads)
  1546.                 {
  1547.  
  1548.                 Draw_Heads();
  1549.  
  1550.                 // reset refresh flag
  1551.                 refresh_heads = 0;
  1552.  
  1553.                 } // end if hud needs a refresh
  1554.  
  1555.              // translate player and apply friction if engines aren't on
  1556.  
  1557.              players_x+=players_xv;
  1558.              players_y+=players_yv;
  1559.  
  1560.  
  1561.              // test for gravity
  1562.  
  1563.              if (!players_engine)
  1564.                 {
  1565.                 if (++players_gravity >=players_stability)
  1566.                    {
  1567.                    // reset gravity count
  1568.  
  1569.                    players_gravity = 0;
  1570.  
  1571.                    // apply friction (in space!!!). hey it's just a game
  1572.  
  1573.                    if (players_xv>0)
  1574.                       players_xv--;
  1575.                    else
  1576.                    if (players_xv<0)
  1577.                       players_xv++;
  1578.  
  1579.                    if (players_yv>0)
  1580.                       players_yv--;
  1581.                    else
  1582.                    if (players_yv<0)
  1583.                       players_yv++;
  1584.  
  1585.                    } // end if time to apply friction
  1586.  
  1587.                 } // end if engines are off
  1588.  
  1589.  
  1590.              // show engines flicker
  1591.  
  1592.              if (players_engine)
  1593.                 {
  1594.                 if (++players_flame_count > players_flame_time)
  1595.                    {
  1596.                    // turn engines on
  1597.  
  1598.                    Write_Color_Reg(PLAYERS_ENGINE_REG,
  1599.                                    (RGB_color_ptr)&players_engine_color);
  1600.  
  1601.                    // reset counter
  1602.  
  1603.                    players_flame_count = 0;
  1604.  
  1605.                    } // end if time to toggle engines
  1606.                 else
  1607.                    {
  1608.                    // turn engines off
  1609.  
  1610.                    Write_Color_Reg(PLAYERS_ENGINE_REG,
  1611.                                    (RGB_color_ptr)&primary_black);
  1612.  
  1613.                    } // end else
  1614.  
  1615.                 } // end if engines are on
  1616.  
  1617.  
  1618.              // test if shields should turn off
  1619.  
  1620.              if (players_shield_time>0)
  1621.                 {
  1622.                 // try and turn off shields
  1623.  
  1624.                 if (--players_shield_time<=0)
  1625.                    Shield_Control(THE_PLAYER,0);
  1626.                 else
  1627.                    {
  1628.                    // which shield colors?
  1629.  
  1630.                    if (players_ship_type==GRYFON_SHIP)
  1631.                       {
  1632.                       if ((players_shield_color.blue+=8) >=64)
  1633.                          players_shield_color.blue = 24;
  1634.  
  1635.                       Write_Color_Reg(PLAYERS_SHIELD_REG,(RGB_color_ptr)&players_shield_color);
  1636.                       }
  1637.                    else
  1638.                       {
  1639.                       // must be a raptor
  1640.  
  1641.                       if ((players_shield_color.red+=8) >=64)
  1642.                          players_shield_color.red = 24;
  1643.  
  1644.                       Write_Color_Reg(PLAYERS_SHIELD_REG,(RGB_color_ptr)&players_shield_color);
  1645.  
  1646.                       } // end else
  1647.  
  1648.                    } // end else modulate shields
  1649.  
  1650.                 } // end if
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.              // compute players delta
  1657.  
  1658.              players_dx = players_last_x - players_x;
  1659.              players_dy = players_last_y - players_y;
  1660.  
  1661.              // do player boundary detection
  1662.              // we are going to wrap universe around, but maybe placing
  1663.              // a barrier at edges would be better?
  1664.  
  1665.              if (players_x > UNIVERSE_WIDTH)
  1666.                 players_x = players_x - UNIVERSE_WIDTH;
  1667.              else
  1668.              if (players_x < 0)
  1669.                 players_x = players_x + UNIVERSE_WIDTH;
  1670.  
  1671.              if (players_y > UNIVERSE_HEIGHT)
  1672.                 players_y = players_y - UNIVERSE_HEIGHT;
  1673.              else
  1674.              if (players_y < 0)
  1675.                 players_y = players_y + UNIVERSE_HEIGHT;
  1676.  
  1677.  
  1678. //END PLAYER///////////////////////////////////////////////////////////////////
  1679.  
  1680.  
  1681.  
  1682.  
  1683. // BEGIN REMOTE//////////////////////////////////////////////////////////////////
  1684.  
  1685.  
  1686.              // only process remote if machines are linked
  1687.  
  1688.              if (linked)
  1689.              {
  1690.  
  1691.              // move remote
  1692.  
  1693.              remotes_last_x = remotes_x;
  1694.              remotes_last_y = remotes_y;
  1695.  
  1696.              // reset remotes input
  1697.  
  1698.              remotes_key_state = 0;
  1699.  
  1700.              // get input from remote machine
  1701.  
  1702.              remotes_key_state = Serial_Read_Wait();
  1703.  
  1704.              // test if a key is depressed
  1705.  
  1706.  
  1707.              if (remotes_state==ALIVE)
  1708.              {
  1709.  
  1710.              if (remotes_key_state > 0)
  1711.                 {
  1712.                 // which key ?
  1713.  
  1714.                 if ((remotes_key_state & REMOTE_LEFT))
  1715.                      {
  1716.                      // rotate left
  1717.  
  1718.                      if (--remotes_ship.curr_frame < 0)
  1719.                         remotes_ship.curr_frame = 15;
  1720. #if DEBUG
  1721.  
  1722.                      rec_left++;
  1723. #endif
  1724.  
  1725.                      } // end if left
  1726.                 else
  1727.                 if ((remotes_key_state & REMOTE_RIGHT))
  1728.                      {
  1729.                      // rotate right
  1730.  
  1731.                      if (++remotes_ship.curr_frame > 15)
  1732.                         remotes_ship.curr_frame = 0;
  1733.  
  1734. #if DEBUG
  1735.                      rec_right++;
  1736. #endif
  1737.  
  1738.                      } // end if right
  1739.  
  1740.                 if ((remotes_key_state & REMOTE_THRUST) && remotes_energy>0)
  1741.                      {
  1742.                      // thrust foward
  1743.  
  1744.                      remotes_xv+=motion_dx[remotes_ship.curr_frame];
  1745.                      remotes_yv+=motion_dy[remotes_ship.curr_frame];
  1746.  
  1747.                      // bound maximum velocity
  1748.  
  1749.                      if (remotes_xv > 8)
  1750.                         remotes_xv=8;
  1751.                      else
  1752.                      if (remotes_xv <-8)
  1753.                         remotes_xv=-8;
  1754.  
  1755.                      if (remotes_yv > 8)
  1756.                         remotes_yv=8;
  1757.                      else
  1758.                      if (remotes_yv <-8)
  1759.                         remotes_yv=-8;
  1760.  
  1761.                      // flag engines on
  1762.  
  1763.                      remotes_engine = 1;
  1764.                      remotes_energy--;
  1765.  
  1766. #if DEBUG
  1767.                      rec_up++;
  1768. #endif
  1769.  
  1770.  
  1771.                      } // end if up
  1772.  
  1773.                 if ((remotes_key_state & REMOTE_FIRE) && remotes_active_missiles < 5 &&
  1774.                     remotes_energy>0)
  1775.                      {
  1776.                      // fire weapons
  1777.  
  1778.                      Start_Missile(remotes_x+SHIP_WIDTH/2,remotes_y+SHIP_HEIGHT/2,
  1779.                                    remotes_xv+2*motion_dx[remotes_ship.curr_frame],
  1780.                                    remotes_yv+2*motion_dy[remotes_ship.curr_frame],
  1781.                                    10,REMOTE_MISSILE);
  1782.  
  1783.                      // decrease energy
  1784.  
  1785.                      remotes_energy-=5;
  1786.  
  1787.                      // now there is one more active missile
  1788.  
  1789.                      remotes_active_missiles++;
  1790.  
  1791.                      } // end if weapons
  1792.  
  1793.                  // instrumentation
  1794.  
  1795.                  if ((remotes_key_state & REMOTE_SHIELDS) &&
  1796.                     remotes_cloak==-1 && remotes_shield_strength>0)
  1797.                      {
  1798.                      // turn the shields on
  1799.  
  1800.                      Shield_Control(THE_REMOTE,1);
  1801.  
  1802.                      // start timer
  1803.  
  1804.                      remotes_shield_time = 100;
  1805.  
  1806.                      } // end if shields
  1807.                  else
  1808.                  if ((remotes_key_state & REMOTE_CLOAK) && remotes_energy>0)
  1809.                       {
  1810.                       // toggle the cloaking device
  1811.  
  1812.                       remotes_cloak = -remotes_cloak;
  1813.  
  1814.                       } // emd if cloak
  1815.                 else
  1816.                 if ((remotes_key_state & REMOTE_ESC))
  1817.                      {
  1818.  
  1819.                      game_state = GAME_SETUP;
  1820.  
  1821.                      } // end if escape
  1822.  
  1823.                 } // end if kbhit
  1824.  
  1825.              // update energy loss due to normal operation
  1826.  
  1827.              if (remotes_cloak==1)
  1828.                 remotes_energy--;
  1829.  
  1830.              if (remotes_energy>0)
  1831.                 {
  1832.                 remotes_energy--;
  1833.  
  1834.                 } // end energy update
  1835.              else
  1836.                 remotes_energy=0;
  1837.  
  1838.              // test if shields are on
  1839.  
  1840.              if (remotes_shields==1)
  1841.                 {
  1842.                 remotes_shield_strength-=8;
  1843.  
  1844.                 if (remotes_shield_strength<0)
  1845.                     remotes_shield_strength = 0;
  1846.  
  1847.                 } // end if shields are on
  1848.  
  1849.              } // end if remote alive
  1850.  
  1851.              // translate remote and apply friction if engines aren't on
  1852.  
  1853.              remotes_x+=remotes_xv;
  1854.              remotes_y+=remotes_yv;
  1855.  
  1856.              // test for gravity
  1857.  
  1858.              if (!remotes_engine)
  1859.                 {
  1860.                 if (++remotes_gravity >=remotes_stability)
  1861.                    {
  1862.                    // reset gravity count
  1863.  
  1864.                    remotes_gravity = 0;
  1865.  
  1866.                    // apply friction (in space!!!). hey it's just a game
  1867.  
  1868.                    if (remotes_xv>0)
  1869.                       remotes_xv--;
  1870.                    else
  1871.                    if (remotes_xv<0)
  1872.                       remotes_xv++;
  1873.  
  1874.                    if (remotes_yv>0)
  1875.                       remotes_yv--;
  1876.                    else
  1877.                    if (remotes_yv<0)
  1878.                       remotes_yv++;
  1879.  
  1880.                    } // end if time to apply friction
  1881.  
  1882.                 } // end if engines are off
  1883.  
  1884.              // show engines flicker
  1885.  
  1886.              if (remotes_engine)
  1887.                 {
  1888.                 if (++remotes_flame_count > remotes_flame_time)
  1889.                    {
  1890.                    // turn engines on
  1891.  
  1892.                    Write_Color_Reg(REMOTES_ENGINE_REG,
  1893.                                    (RGB_color_ptr)&remotes_engine_color);
  1894.  
  1895.                    // reset counter
  1896.  
  1897.                    remotes_flame_count = 0;
  1898.  
  1899.                    } // end if time to toggle engines
  1900.                 else
  1901.                    {
  1902.                    // turn engines off
  1903.  
  1904.                    Write_Color_Reg(REMOTES_ENGINE_REG,
  1905.                                    (RGB_color_ptr)&primary_black);
  1906.  
  1907.                    } // end else
  1908.  
  1909.                 } // end if engines are on
  1910.  
  1911.  
  1912.              // test if shields should turn off
  1913.  
  1914.              if (remotes_shield_time>0)
  1915.                 {
  1916.                 // try and turn off shields
  1917.  
  1918.                 if (--remotes_shield_time<=0)
  1919.                    Shield_Control(THE_REMOTE,0);
  1920.                 else
  1921.                    {
  1922.                    // which shield colors?
  1923.  
  1924.                    if (remotes_ship_type==GRYFON_SHIP)
  1925.                       {
  1926.                       if ((remotes_shield_color.blue+=8) >=64)
  1927.                          remotes_shield_color.blue = 24;
  1928.  
  1929.                       Write_Color_Reg(REMOTES_SHIELD_REG,(RGB_color_ptr)&remotes_shield_color);
  1930.                       }
  1931.                    else
  1932.                       {
  1933.                       // must be a raptor
  1934.  
  1935.                       if ((remotes_shield_color.red+=8) >=64)
  1936.                          remotes_shield_color.red = 24;
  1937.  
  1938.                       Write_Color_Reg(REMOTES_SHIELD_REG,(RGB_color_ptr)&remotes_shield_color);
  1939.  
  1940.                       } // end else
  1941.  
  1942.                    } // end else modulate shields
  1943.  
  1944.                 } // end if
  1945.  
  1946.              // compute remotes delta
  1947.  
  1948.              remotes_dx = remotes_last_x - remotes_x;
  1949.              remotes_dy = remotes_last_y - remotes_y;
  1950.  
  1951.              // do remotes boundary detection
  1952.              // we are going to wrap universe around, but maybe placing
  1953.              // a barrier at edges would be better?
  1954.  
  1955.              if (remotes_x > UNIVERSE_WIDTH)
  1956.                 remotes_x = remotes_x - UNIVERSE_WIDTH;
  1957.              else
  1958.              if (remotes_x < 0)
  1959.                 remotes_x = remotes_x + UNIVERSE_WIDTH;
  1960.  
  1961.              if (remotes_y > UNIVERSE_HEIGHT)
  1962.                 remotes_y = remotes_y - UNIVERSE_HEIGHT;
  1963.              else
  1964.              if (remotes_y < 0)
  1965.                 remotes_y = remotes_y + UNIVERSE_HEIGHT;
  1966.  
  1967.              } // end if linked
  1968.  
  1969. //END REMOTE///////////////////////////////////////////////////////////////////
  1970.  
  1971.              // call AI logic for alien
  1972.  
  1973.              Alien_Control();
  1974.  
  1975.              // move all objects
  1976.  
  1977.              Move_Stars();
  1978.              Move_Alien();
  1979.              Move_Asteroids();
  1980.              Move_Missiles();
  1981.              Animate_Explosions();
  1982.              Move_Novas();
  1983.              Animate_Wormhole();
  1984.              Animate_Fuel_Cells();
  1985.  
  1986.              // perform death sequence logic for player
  1987.  
  1988.              if (players_state==DYING)
  1989.                 {
  1990.  
  1991.                 // decrement death counter
  1992.  
  1993.                 if (--players_death_count<=0)
  1994.                    {
  1995.                    // reset player to starting position
  1996.  
  1997.                    Reset_Player();
  1998.  
  1999.                    // test if this is it...
  2000.  
  2001.                    if (--players_num_ships==0)
  2002.                       {
  2003.                       // return to setup
  2004.  
  2005.                       game_state = GAME_SETUP;
  2006.                       winner = WINNER_REMOTE;
  2007.  
  2008.                       } // end if it's all over
  2009.  
  2010.                       // refresh hud in any case
  2011.  
  2012.                       if (players_heads==1)
  2013.                          Draw_Heads();
  2014.  
  2015.                    } // end if death done
  2016.  
  2017.                 } // end if player dying
  2018.  
  2019.  
  2020.              // perform death sequence logic for remote
  2021.  
  2022.              if (linked && remotes_state==DYING)
  2023.                 {
  2024.  
  2025.                 // decrement death counter
  2026.  
  2027.                 if (--remotes_death_count<=0)
  2028.                    {
  2029.                    // reset remote to starting position
  2030.  
  2031.                    Reset_Remote();
  2032.  
  2033.                    // test if this is it...
  2034.  
  2035.                    if (--remotes_num_ships==0)
  2036.                       {
  2037.  
  2038.                       game_state = GAME_SETUP;
  2039.                       winner = WINNER_PLAYER;
  2040.  
  2041.                       } // end if it's all over
  2042.  
  2043.                    } // end if death done
  2044.  
  2045.                 } // end if remote dying
  2046.  
  2047.              // scan under all objects
  2048.  
  2049.              Under_Fuel_Cells();
  2050.              Under_Stars();
  2051.              Under_Asteroids();
  2052.  
  2053.              Under_Missiles();
  2054.              Under_Explosions();
  2055.              Under_Novas();
  2056.              Under_Wormhole();
  2057.              Under_Alien();
  2058.  
  2059.              // render scanner with new data
  2060.  
  2061.              if (players_scanner==1)
  2062.                 Under_Blips();
  2063.  
  2064. // BEGIN PLAYER ////////////////////////////////////////////////////////////////
  2065.  
  2066.              Sprite_Under((sprite_ptr)&players_ship,double_buffer);
  2067.  
  2068. // END PLAYER //////////////////////////////////////////////////////////////////
  2069.  
  2070.  
  2071. // BEGIN REMOTE ////////////////////////////////////////////////////////////////
  2072.  
  2073.              // translate remote to player
  2074.  
  2075.              px_window = players_x - 160+11;
  2076.              py_window = players_y - 100+9;
  2077.  
  2078.              remotes_ship.x = remotes_x - px_window;
  2079.              remotes_ship.y = remotes_y - py_window;
  2080.  
  2081.              Sprite_Under_Clip((sprite_ptr)&remotes_ship,double_buffer);
  2082.  
  2083. // END REMOTE //////////////////////////////////////////////////////////////////
  2084.  
  2085.              // draw all objects
  2086.  
  2087.              Draw_Wormhole();
  2088.              Draw_Fuel_Cells();
  2089.              Draw_Stars();
  2090.              Draw_Asteroids();
  2091.  
  2092. //BEGIN PLAYER//////////////////////////////////////////////////////////////////
  2093.  
  2094.              // display proper image of ship depending on state of engines
  2095.              // and cloak
  2096.  
  2097.  
  2098.              // but first is there a ship?
  2099.  
  2100.              if (players_state==ALIVE)
  2101.              {
  2102.              // test if ship is totally cloaked
  2103.              if (players_cloak==-1)
  2104.                 {
  2105.                 // ship isn't cloaked
  2106.  
  2107.                 if (players_engine)
  2108.                    {
  2109.                    // index into frames with thrust
  2110.  
  2111.                    players_ship.curr_frame+=16;
  2112.  
  2113.                    // draw the ship with thrust showing
  2114.  
  2115.                    Sprite_Draw((sprite_ptr)&players_ship,double_buffer,1);
  2116.  
  2117.                    // restore the original frame
  2118.  
  2119.                    players_ship.curr_frame-=16;
  2120.  
  2121.                    } // end if engines are on
  2122.                 else
  2123.                    {
  2124.                    // no engines
  2125.  
  2126.                    Sprite_Draw((sprite_ptr)&players_ship,double_buffer,1);
  2127.  
  2128.                    } // end else no engine flicker
  2129.  
  2130.                 } // end if not cloaked
  2131.              else
  2132.                 {
  2133.                 // player is cloaked
  2134.  
  2135.                 // test if player is trying to engage shields
  2136.  
  2137.                 if (players_shields)
  2138.                    {
  2139.                    // force shields off
  2140.  
  2141.                    Shield_Control(THE_PLAYER,0);
  2142.                    players_shield_time=0;
  2143.  
  2144.                    } // end if trying to engage sheilds
  2145.  
  2146.                 } // end else ship cloaked
  2147.  
  2148.              } // end if player alive
  2149.  
  2150. //END PLAYER//////////////////////////////////////////////////////////////////
  2151.  
  2152.  
  2153. //BEGIN REMOTE//////////////////////////////////////////////////////////////////
  2154.  
  2155.              // display proper image of ship depending on state of engines
  2156.              // and cloak
  2157.  
  2158.              // but first is there is a ship?
  2159.  
  2160.              if (remotes_state==ALIVE)
  2161.              {
  2162.              // test if ship is totally cloaked
  2163.              if (remotes_cloak==-1)
  2164.                 {
  2165.                 // ship isn't cloaked
  2166.  
  2167.                 if (remotes_engine)
  2168.                    {
  2169.                    // index into frames with thrust
  2170.  
  2171.                    remotes_ship.curr_frame+=16;
  2172.  
  2173.                    // draw the ship with thrust showing
  2174.  
  2175.                    Sprite_Draw_Clip((sprite_ptr)&remotes_ship,double_buffer,1);
  2176.  
  2177.                    // restore the original frame
  2178.  
  2179.                    remotes_ship.curr_frame-=16;
  2180.  
  2181.                    } // end if engines are on
  2182.                 else
  2183.                    {
  2184.                    // no engines
  2185.  
  2186.                    Sprite_Draw_Clip((sprite_ptr)&remotes_ship,double_buffer,1);
  2187.  
  2188.                    } // end else no engine flicker
  2189.  
  2190.                 } // end if not cloaked
  2191.              else
  2192.                 {
  2193.                 // player is cloaked
  2194.  
  2195.                 // test if player is trying to engage shields
  2196.  
  2197.                 if (remotes_shields)
  2198.                    {
  2199.                    // force shields off
  2200.  
  2201.                    Shield_Control(THE_REMOTE,0);
  2202.                    remotes_shield_time=0;
  2203.  
  2204.                    } // end if trying to engage sheilds
  2205.  
  2206.                 } // end else ship cloaked
  2207.  
  2208.              } // end if remote is alive
  2209.  
  2210.  
  2211. //END REMOTE//////////////////////////////////////////////////////////////////
  2212.  
  2213.              // draw remaining priority objects
  2214.  
  2215.              Draw_Missiles();
  2216.              Draw_Alien();
  2217.              Draw_Explosions();
  2218.              Draw_Novas();
  2219.  
  2220.              // render scanner with new data
  2221.  
  2222.              if (players_scanner==1)
  2223.                 Draw_Blips();
  2224.  
  2225.              // display coordinates and score
  2226.  
  2227.              sprintf(buffer,"COORDINATES:[%d,%d]    ",players_x,players_y);
  2228.              Font_Engine_1(0,0,0,0,buffer,double_buffer);
  2229.  
  2230.              sprintf(buffer,"SCORE: %d",players_score);
  2231.              Font_Engine_1(250,0,0,0,buffer,double_buffer);
  2232.  
  2233. #if DEBUG
  2234.              // diagnostic stuff
  2235.  
  2236.              sprintf(buffer,"REMOTE:[%d,%d]    ",remotes_x,remotes_y);
  2237.              Font_Engine_1(0,10,0,0,buffer,double_buffer);
  2238.  
  2239.              sprintf(buffer,"SENT: R=%d L=%d U=%d ",sent_right,sent_left,sent_up);
  2240.              Font_Engine_1(0,20,0,0,buffer,double_buffer);
  2241.  
  2242.              sprintf(buffer,"REC: R=%d L=%d U=%d ",rec_right,rec_left,rec_up);
  2243.              Font_Engine_1(0,30,0,0,buffer,double_buffer);
  2244.  
  2245.              // end diagnostic stuff
  2246.  
  2247. #endif
  2248.  
  2249.              // display double buffer
  2250.  
  2251.              Display_Double_Buffer(double_buffer,0);
  2252.  
  2253.              // lock onto 18 frames per second max
  2254.  
  2255.              while((Timer_Query()-starting_time)<1);
  2256.  
  2257.              // check on music
  2258.  
  2259.              if (music_enabled)
  2260.              {
  2261.              if (Music_Status()==2 || Music_Status()==0)
  2262.                 {
  2263.  
  2264.                 // advance to next sequence
  2265.  
  2266.                 if (++game_seq_index==18)
  2267.                    game_seq_index=0;
  2268.  
  2269.                 Music_Play((music_ptr)&song,game_sequence[game_seq_index]);
  2270.  
  2271.                 } // end if
  2272.  
  2273.              } // end if music enabled
  2274.  
  2275.              } // end game loop
  2276.  
  2277.         // test if there is a winner or user just decided to exit
  2278.  
  2279.         if (winner==WINNER_REMOTE)
  2280.            {
  2281.            // tell player remote is winner
  2282.  
  2283.            Tech_Print(128,80,"CEASE COMBAT!",video_buffer);
  2284.  
  2285.            if (music_enabled)
  2286.               {
  2287.               Music_Stop();
  2288.               Music_Play((music_ptr)&song,11);
  2289.               }
  2290.            Time_Delay(25);
  2291.            Digital_FX_Play(BLZLOS_VOC,2);
  2292.            Tech_Print(120,100,"YOU ARE DEFEATED",video_buffer);
  2293.            Time_Delay(50);
  2294.  
  2295.            } // end if remote won
  2296.         else
  2297.         if (winner==WINNER_PLAYER)
  2298.            {
  2299.            // tell player he is winner
  2300.  
  2301.            Tech_Print(128,80,"CEASE COMBAT!",video_buffer);
  2302.            if (music_enabled)
  2303.               {
  2304.               Music_Stop();
  2305.               Music_Play((music_ptr)&song,11);
  2306.               }
  2307.            Time_Delay(25);
  2308.            Digital_FX_Play(BLZWIN_VOC,2);
  2309.            Tech_Print(115,100,"YOU ARE VICTORIOUS",video_buffer);
  2310.            Time_Delay(50);
  2311.  
  2312.            } // end if player won
  2313.  
  2314.         // do all exit clean up here to move back to the setup state
  2315.  
  2316.         Screen_Transition(SCREEN_DARKNESS);
  2317.  
  2318.         // restart intro music
  2319.  
  2320.         if (music_enabled)
  2321.            {
  2322.            // stop game music, start intro music again
  2323.  
  2324.            intro_seq_index=0;
  2325.            Music_Stop();
  2326.            Music_Play((music_ptr)&song,intro_sequence[intro_seq_index]);
  2327.  
  2328.            } // end if music enabled
  2329.  
  2330.         } // end if running
  2331.  
  2332.      } // end main system event loop
  2333.  
  2334. ///////////////////////////////////////////////////////////////////////////////
  2335.  
  2336. // exit in a very cool way
  2337.  
  2338. Screen_Transition(SCREEN_DARKNESS);
  2339.  
  2340. // free up all resources
  2341.  
  2342. Delete_Double_Buffer();
  2343.  
  2344. // remove the keyboard handler
  2345.  
  2346. Keyboard_Remove_Driver();
  2347.  
  2348. // close down FX
  2349.  
  2350. Digital_FX_Close();
  2351.  
  2352. // show the credits
  2353.  
  2354. Closing_Screen();
  2355.  
  2356. // close down music
  2357.  
  2358. Music_Close();
  2359.  
  2360. Set_Graphics_Mode(TEXT_MODE);
  2361.  
  2362. // see ya!
  2363.  
  2364. printf("\nSTARBLAZER Shutdown Normal.\n");
  2365.  
  2366. } // end main
  2367.  
  2368.  
  2369.