home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / tempgame.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  99KB  |  3,508 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*                                               
  14.  * $Source: f:/miner/source/main/rcs/tempgame.c $
  15.  * $Revision: 2.0 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/27 11:28:06 $
  18.  *
  19.  * Game loop for Inferno
  20.  *
  21.  * $Log: tempgame.c $
  22.  * Revision 2.0  1995/02/27  11:28:06  john
  23.  * New version 2.0, which has no anonymous unions, builds with
  24.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  25.  * 
  26.  * Revision 1.747  1995/02/06  12:24:45  allender
  27.  * force Endlevel_sequence in game() to fix rare bug
  28.  * 
  29.  * Revision 1.745  1995/02/02  15:57:52  john
  30.  * Added turbo mode cheat.
  31.  * 
  32.  * Revision 1.744  1995/02/02  14:43:39  john
  33.  * Uppped frametime limit to 150 Hz.
  34.  * 
  35.  * Revision 1.743  1995/02/02  13:37:16  mike
  36.  * move T-?? message down in certain modes.
  37.  * 
  38.  * Revision 1.742  1995/02/02  01:26:59  john
  39.  * Took out no key repeating.
  40.  * 
  41.  * Revision 1.741  1995/01/29  21:36:44  mike
  42.  * make fusion cannon not make pitching slow.
  43.  * 
  44.  * Revision 1.740  1995/01/28  15:57:57  john
  45.  * Made joystick calibration be only when wrong detected in
  46.  * menu or joystick axis changed.
  47.  * 
  48.  * Revision 1.739  1995/01/28  15:21:03  yuan
  49.  * Added X-tra life cheat.
  50.  * 
  51.  * Revision 1.738  1995/01/27  14:08:31  rob
  52.  * Fixed a bug.
  53.  * 
  54.  * Revision 1.737  1995/01/27  14:04:59  rob
  55.  * Its not my fault, Mark told me to do it!
  56.  * 
  57.  * Revision 1.736  1995/01/27  13:12:18  rob
  58.  * Added charging noises to play across net.
  59.  * 
  60.  * Revision 1.735  1995/01/27  11:48:28  allender
  61.  * check for newdemo_state to be paused and stop recording.  We might be
  62.  * in between levels
  63.  * 
  64.  * Revision 1.734  1995/01/26  22:11:41  mike
  65.  * Purple chromo-blaster (ie, fusion cannon) spruce up (chromification)
  66.  * 
  67.  * Revision 1.733  1995/01/26  17:03:04  mike
  68.  * make fusion cannon have more chrome, make fusion, mega rock you!
  69.  * 
  70.  * Revision 1.732  1995/01/25  14:37:25  john
  71.  * Made joystick only prompt for calibration once...
  72.  * 
  73.  * Revision 1.731  1995/01/24  15:49:14  john
  74.  * Made typeing in long net messages wrap on 
  75.  * small screen sizes.
  76.  * 
  77.  * Revision 1.730  1995/01/24  15:23:42  mike
  78.  * network message tweaking.
  79.  * 
  80.  * Revision 1.729  1995/01/24  12:00:47  john
  81.  * Fixed bug with defing macro passing keys to controls.
  82.  * 
  83.  * Revision 1.728  1995/01/24  11:53:35  john
  84.  * Added better macro defining code.
  85.  * 
  86.  * Revision 1.727  1995/01/23  22:17:15  john
  87.  * Fixed bug with not clearing key buffer when leaving f8.
  88.  * 
  89.  * Revision 1.726  1995/01/23  22:07:09  john
  90.  * Added flush to game inputs during F8.
  91.  * 
  92.  */
  93.  
  94. #pragma off (unreferenced)
  95. static char rcsid[] = "$Id: tempgame.c 2.0 1995/02/27 11:28:06 john Exp $";
  96. #pragma on (unreferenced)
  97.  
  98. #include <stdio.h>
  99. #include <malloc.h>
  100. #include <stdlib.h>
  101. #include <string.h>
  102. #include <conio.h>
  103. #include <stdarg.h>
  104.  
  105. #include "inferno.h"
  106. #include "game.h"
  107. #include "key.h"
  108. #include "object.h"
  109. #include "physics.h"
  110. #include "error.h"
  111. #include "joy.h"
  112. #include "mono.h"
  113. #include "iff.h"
  114. #include "pcx.h"
  115. #include "timer.h"
  116. #include "render.h"
  117. #include "laser.h"
  118. #include "screens.h"
  119. #include "textures.h"
  120. #include "slew.h"
  121. #include "gauges.h"
  122. #include "texmap.h"
  123. #include "3d.h"
  124. #include "effects.h"
  125. #include "effect2d.h"
  126. #include "menu.h"
  127. #include "gameseg.h"
  128. #include "wall.h"
  129. #include "ai.h"
  130. #include "hostage.h"
  131. #include "fuelcen.h"
  132. #include "switch.h"
  133. #include "digi.h"
  134. #include "gamesave.h"
  135. #include "scores.h"
  136. #include "ibitblt.h"
  137. #include "mem.h"
  138. #include "palette.h"
  139. #include "morph.h"
  140. #include "lighting.h"
  141. #include "newdemo.h"
  142. #include "titles.h"
  143. #include "collide.h"
  144. #include "weapon.h"
  145. #include "sounds.h"
  146. #include "args.h"
  147. #include "gameseq.h"
  148. #include "automap.h"
  149. #include "text.h"
  150. #include "powerup.h"
  151. #include "fireball.h"
  152. #include "controls.h"
  153. #include "newmenu.h"
  154. #include "network.h"
  155. #include "gamefont.h"
  156. #include "endlevel.h"
  157. #include "joydefs.h"
  158. #include "kconfig.h"
  159. #include "mouse.h"
  160. #include "coindev.h"
  161. #include "multi.h"
  162. #include "desc_id.h"
  163. #include "cntrlcen.h"
  164. #include "pcx.h"
  165. #include "dpmi.h"
  166. #include "state.h"
  167. #include "piggy.h"
  168. #include "multibot.h"
  169.  
  170. //#define TEST_TIMER    1        //if this is set, do checking on timer
  171.  
  172. #define FINAL_CHEATS 1
  173.  
  174. #ifdef ARCADE
  175. #include "arcade.h"
  176. #else
  177. #define Arcade_mode 0
  178. #endif
  179.  
  180. #define VICTOR 1
  181. #ifdef VICTOR
  182. #include "victor.h"
  183. #endif
  184.  
  185. #define VFX 1
  186. #ifdef VFX
  187. #include "vfx.h"
  188. #endif
  189.  
  190. #ifdef EDITOR
  191. #include "editor\editor.h"
  192. #endif
  193.  
  194. //#define _MARK_ON 1
  195. //#include <wsample.h>            //should come after inferno.h to get mark setting//disabled by KRB
  196.  
  197. #ifndef NDEBUG
  198. int    Mark_count = 0;                 // number of debugging marks set
  199. int    Speedtest_on = 0;
  200. int    Speedtest_start_time;
  201. int    Speedtest_segnum;
  202. int    Speedtest_sidenum;
  203. int    Speedtest_frame_start;
  204. int    Speedtest_count=0;                //    number of times to do the debug test.
  205. #endif
  206.  
  207. static fix last_timer_value=0;
  208.  
  209. #if defined(TIMER_TEST) && !defined(NDEBUG)
  210. fix _timer_value,actual_last_timer_value,_last_frametime;
  211. int stop_count,start_count;
  212. int time_stopped,time_started;
  213. #endif
  214.  
  215. ubyte * Game_cockpit_copy_code = NULL;
  216.  
  217. //these are instances of canvases, pointed to by variables below
  218. grs_canvas _canv_3d;                                    //the 3d window, on screen
  219. grs_canvas _canv_3d_offscrn;            //the 3d window, off screen
  220.  
  221. //these are pointers to our canvases
  222. grs_canvas *Canv_game=NULL;                          //what you acutally see on screen
  223. grs_canvas *Canv_game_offscrn=NULL;  //off-screen buffer the size of the screen 
  224. grs_canvas *Canv_3d=&_canv_3d;  //the 3d window, on screen
  225. grs_canvas *Canv_3d_offscrn=NULL;            //the 3d window, off screen
  226. #ifdef VFX
  227. grs_canvas *Canv_vfx[2][2];            // Eye, buffer
  228. #endif
  229. #ifdef VICTOR
  230. grs_canvas *Canv_victor[2] = { NULL, NULL };            // Eye pages
  231. grs_canvas Canv_victor_3d[2] ;            // Eye pages
  232. ubyte Victor_eye_switch=0;
  233. #endif
  234.  
  235. int Debug_pause=0;                //John's debugging pause system
  236.  
  237. int Cockpit_mode=CM_FULL_COCKPIT;        //set game.h for values
  238. int old_cockpit_mode=-1;
  239. int force_cockpit_redraw=0;
  240.  
  241. int framerate_on=0;
  242.  
  243. int PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd;
  244.  
  245. //    Toggle_var points at a variable which gets !ed on ctrl-alt-T press.
  246. int    Dummy_var;
  247. int    *Toggle_var = &Dummy_var;
  248.  
  249. #ifdef EDITOR
  250. //flag for whether initial fade-in has been done
  251. char faded_in;
  252. #endif
  253.  
  254. #ifndef NDEBUG                          //these only exist if debugging
  255.  
  256. int Game_double_buffer = 1;     //double buffer by default
  257. fix fixed_frametime=0;          //if non-zero, set frametime to this
  258.  
  259. #endif
  260.  
  261. int Game_suspended=0;           //if non-zero, nothing moves but player
  262.  
  263. #ifdef VFX
  264.     int Game_vfx_flag = 0;
  265. #endif
  266.  
  267. #ifdef VICTOR
  268.     int Game_victor_flag = 0;
  269. #endif
  270.  
  271. fix RealFrameTime;
  272. fix    Auto_fire_fusion_cannon_time = 0;
  273. fix    Fusion_charge = 0;
  274. fix    Fusion_next_sound_time = 0;
  275.  
  276. int Debug_spew = 1;
  277. int Game_turbo_mode = 0;
  278.  
  279. int Game_mode = GM_GAME_OVER;
  280.  
  281. int    Global_laser_firing_count = 0;
  282. int    Global_missile_firing_count = 0;
  283.  
  284. grs_bitmap background_bitmap;
  285.  
  286. int Game_aborted;
  287.  
  288. #define BACKGROUND_NAME "statback.pcx"
  289.  
  290. //    ==============================================================================================
  291.  
  292. #ifndef NDEBUG
  293. void speedtest_init(void)
  294. {
  295.     Speedtest_start_time = timer_get_fixed_seconds();
  296.     Speedtest_on = 1;
  297.     Speedtest_segnum = 0;
  298.     Speedtest_sidenum = 0;
  299.     Speedtest_frame_start = FrameCount;
  300.  
  301.     mprintf((0, "Starting speedtest.  Will be %i frames.  Each . = 10 frames.\n", Highest_segment_index+1));
  302. }
  303.  
  304. void speedtest_frame(void)
  305. {
  306.     vms_vector    view_dir, center_point;
  307.  
  308.     Speedtest_sidenum=Speedtest_segnum % MAX_SIDES_PER_SEGMENT;
  309.  
  310.     compute_segment_center(&Viewer->pos, &Segments[Speedtest_segnum]);
  311.     Viewer->pos.x += 0x10;        Viewer->pos.y -= 0x10;        Viewer->pos.z += 0x17;
  312.  
  313.     obj_relink(Viewer-Objects, Speedtest_segnum);
  314.     compute_center_point_on_side(¢er_point, &Segments[Speedtest_segnum], Speedtest_sidenum);
  315.     vm_vec_normalized_dir_quick(&view_dir, ¢er_point, &Viewer->pos);
  316.     vm_vector_2_matrix(&Viewer->orient, &view_dir, NULL, NULL);
  317.  
  318.     if (((FrameCount - Speedtest_frame_start) % 10) == 0)
  319.         mprintf((0, "."));
  320.  
  321.     Speedtest_segnum++;
  322.  
  323.     if (Speedtest_segnum > Highest_segment_index) {
  324.         mprintf((0, "\nSpeedtest done:  %i frames, %7.3f seconds, %7.3f frames/second.\n", 
  325.             FrameCount-Speedtest_frame_start,
  326.             f2fl(timer_get_fixed_seconds() - Speedtest_start_time),
  327.             (float) (FrameCount-Speedtest_frame_start) / f2fl(timer_get_fixed_seconds() - Speedtest_start_time)));
  328.         Speedtest_count--;
  329.         if (Speedtest_count == 0)
  330.             Speedtest_on = 0;
  331.         else
  332.             speedtest_init();
  333.     }                
  334.  
  335. }
  336.  
  337. #endif
  338.  
  339. //this is called once per game
  340. void init_game()
  341. {
  342.     ubyte pal[256*3];
  343.     int pcx_error;
  344.  
  345.     atexit(close_game);             //for cleanup
  346.  
  347.     #ifdef VFX
  348.     if ( FindArg( "-vfx" ) )
  349.         Game_vfx_flag = 1;
  350.     #endif
  351.  
  352.     #ifdef VICTOR
  353.     if ( FindArg( "-cybermaxx" ) )
  354.         Game_victor_flag = 1;
  355.     #endif
  356.  
  357.     init_objects();
  358.  
  359.     hostage_init();
  360.  
  361.     init_special_effects();
  362.  
  363.     init_ai_system();
  364.  
  365.     init_gauge_canvases();
  366.  
  367.     init_exploding_walls();
  368.  
  369.     background_bitmap.bm_data=NULL;
  370.     pcx_error = pcx_read_bitmap(BACKGROUND_NAME,&background_bitmap,BM_LINEAR,pal);
  371.     if (pcx_error != PCX_ERROR_NONE)
  372.         Error("File %s - PCX error: %s",BACKGROUND_NAME,pcx_errormsg(pcx_error));
  373.     gr_remap_bitmap_good( &background_bitmap, pal, -1, -1 );
  374.  
  375.     Clear_window = 2;        //    do portal only window clear.
  376. }
  377.  
  378.  
  379. void reset_palette_add()
  380. {
  381.     PaletteRedAdd         = 0;
  382.     PaletteGreenAdd    = 0;
  383.     PaletteBlueAdd        = 0;
  384.     //gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  385. }
  386.  
  387.  
  388. game_show_warning(char *s)
  389. {
  390.  
  391.     if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  392.         stop_time();
  393.  
  394.     nm_messagebox( TXT_WARNING, 1, TXT_OK, s );
  395.  
  396.     if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  397.         start_time();
  398. }
  399.  
  400.  
  401. //these should be in gr.h 
  402. #define cv_w  cv_bitmap.bm_w
  403. #define cv_h  cv_bitmap.bm_h
  404.  
  405. #define LETTERBOX_HEIGHT 140
  406.  
  407. int Game_window_w,Game_window_h,max_window_h;
  408.  
  409. #ifdef VFX
  410. int special_halfsize_window=0;
  411. #endif
  412.  
  413. int last_drawn_cockpit = -1;
  414.  
  415. extern int Rear_view;
  416.  
  417. // This actually renders the new cockpit onto the screen.
  418. void update_cockpits(int force_redraw)
  419. {
  420.     int x, y, w, h;
  421.  
  422.     if (Cockpit_mode != last_drawn_cockpit || force_redraw )
  423.         last_drawn_cockpit = Cockpit_mode;
  424.     else
  425.         return;
  426.  
  427.     //Redraw the on-screen cockpit bitmaps
  428.     if (Screen_mode != SCREEN_GAME )    return;
  429.  
  430.     switch( Cockpit_mode )    {
  431.     case CM_FULL_COCKPIT:
  432.     case CM_REAR_VIEW:
  433.         gr_set_current_canvas(Canv_game);
  434.         PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode]);
  435.         gr_ubitmapm(0,0, cockpit_bitmap[Cockpit_mode]);    
  436.         break;
  437.     case CM_FULL_SCREEN:
  438.         break;
  439.     case CM_STATUS_BAR:
  440.         gr_set_current_canvas(Canv_game);
  441.         PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode]);
  442.         gr_ubitmapm(0,max_window_h,cockpit_bitmap[Cockpit_mode]);
  443.         w = Game_window_w;
  444.         h = Game_window_h;
  445.         x = (Canv_game->cv_bitmap.bm_w - w)/2;
  446.         y = (max_window_h - h)/2;
  447.         fill_background(x,y,w,h,x,y);
  448.         break;
  449.     case CM_LETTERBOX:
  450.         gr_set_current_canvas(Canv_game);
  451.         gr_clear_canvas( BM_XRGB(0,0,0) );
  452.         break;
  453.     }
  454.  
  455.     gr_set_current_canvas(Canv_game);
  456.     
  457.     if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
  458.         init_gauges();
  459.  
  460. }
  461.  
  462. //initialize the various canvases on the game screen
  463. //called every time the screen mode or cockpit changes
  464. void init_game_screen()
  465. {
  466.     int minx, maxx, miny, maxy;
  467.     grs_bitmap *bmp;
  468.  
  469.     //Initialize the on-screen canvases
  470.  
  471.     Canv_game->cv_font = GAME_FONT;
  472.  
  473.     switch( Screen_mode )    {
  474.  
  475.         case SCREEN_GAME:
  476.             if (Game_cockpit_copy_code)
  477.                 free(Game_cockpit_copy_code);
  478.             Game_cockpit_copy_code  = NULL;
  479.         
  480.             if (Cockpit_mode==CM_FULL_COCKPIT ||  Cockpit_mode==CM_REAR_VIEW) {
  481.                 grs_bitmap *bm = cockpit_bitmap[Cockpit_mode];
  482.  
  483.                 PIGGY_PAGE_IN(bm);
  484.                 //calculate copy code for current cockpit
  485.                 gr_set_current_canvas(Canv_game_offscrn);
  486.                 gr_bitmap( 0, 0, bm );
  487.                 bm = &Canv_game_offscrn->cv_bitmap;
  488.                 bm->bm_flags = BM_FLAG_TRANSPARENT;
  489.                 gr_ibitblt_find_hole_size ( bm, &minx, &miny, &maxx, &maxy );
  490.                 Game_cockpit_copy_code  = gr_ibitblt_create_mask( bm, minx, miny, maxx-minx+1, maxy-miny+1, Canv_game_offscrn->cv_bitmap.bm_rowsize );
  491.                 bm->bm_flags = 0;        // Clear all flags for offscreen canvas
  492.                 gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, minx, miny, maxx-minx+1, maxy-miny+1 );
  493.             }
  494.             else if (Cockpit_mode == CM_FULL_SCREEN) {
  495.  
  496.                 minx = miny = 0;
  497.                 maxx = Canv_game->cv_w-1;
  498.                 maxy = Canv_game->cv_h-1;
  499.  
  500.                 #ifdef VFX
  501.                 if (special_halfsize_window) {
  502.                     maxx /= 2;
  503.                     maxy /= 2;
  504.                 }
  505.                 #endif
  506.  
  507.                 gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, minx, miny, maxx-minx+1, maxy-miny+1 );
  508.  
  509.                 Game_window_w = maxx-minx+1;
  510.                 Game_window_h = maxy-miny+1;
  511.  
  512.             }
  513.             else if (Cockpit_mode == CM_STATUS_BAR) {
  514.                  int x,y,w,h;
  515.  
  516.                 if (Game_window_h > max_window_h) {
  517.                     Game_window_h = max_window_h;
  518.                     Game_window_w = Canv_game->cv_w;
  519.                 }
  520.  
  521.                 w = Game_window_w;
  522.                 h = Game_window_h;
  523.  
  524.                 x = (Canv_game->cv_bitmap.bm_w - w)/2;
  525.                 y = (max_window_h - h)/2;
  526.  
  527.                 gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, x, y, w, h );
  528.  
  529.             }
  530.             else if (Cockpit_mode == CM_LETTERBOX) {
  531.                 int x,y,w,h;
  532.             
  533.                 x = 0; w = Canv_game->cv_bitmap.bm_w;
  534.                 h = LETTERBOX_HEIGHT;
  535.                 y = (Canv_game->cv_bitmap.bm_h-h)/2;
  536.             
  537.                 gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, x, y, w, h );
  538.             }
  539.  
  540.             bmp =    &_canv_3d_offscrn.cv_bitmap;
  541.             gr_init_sub_canvas( &_canv_3d, Canv_game, bmp->bm_x, bmp->bm_y, bmp->bm_w, bmp->bm_h );
  542.  
  543.             Canv_3d = &_canv_3d;
  544.             Canv_3d_offscrn = &_canv_3d_offscrn;
  545.  
  546.             //@@if (Cockpit_mode==CM_FULL_SCREEN || Cockpit_mode==CM_STATUS_BAR)
  547.             //@@    init_reticle();
  548.  
  549.             gr_set_current_canvas(Canv_game);
  550.  
  551.             break;
  552.  
  553.         #ifdef VFX
  554.         case SCREEN_VFX: {
  555.             #ifdef ARCADE
  556.             int i;
  557.  
  558.             // Use different lighting with VFX
  559.             i = FindArg( "-vfxlight" );
  560.             if ( i ) {
  561.                 fix beam = fl2f(atof(Args[i+1]));
  562.  
  563.                 if (beam < 0)
  564.                     Lighting_on = 0;
  565.                 else
  566.                     Beam_brightness = beam;
  567.             }
  568.             else
  569.             #endif
  570.                 //NOTE LINK TO ABOVE!!
  571.                 Beam_brightness=0x38000;
  572.  
  573.             Cockpit_mode = CM_FULL_SCREEN;
  574.     
  575.             if ( Game_vfx_flag == 1 )    {
  576.                 minx = 0; miny = 0;
  577.                 maxx = 159; maxy = 119;
  578.             } else {
  579.                 minx = 0; miny = 0;
  580.                 maxx = 159; maxy = 239;
  581.             }
  582.             gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, minx, miny, maxx-minx+1, maxy-miny+1 );
  583.             Game_cockpit_copy_code = NULL;
  584.             bmp =    &_canv_3d_offscrn.cv_bitmap;
  585.             gr_init_sub_canvas( &_canv_3d, Canv_game, bmp->bm_x, bmp->bm_y, bmp->bm_w, bmp->bm_h );
  586.             gr_set_current_canvas(Canv_game);
  587.             Canv_3d = &_canv_3d;
  588.             Canv_3d_offscrn = &_canv_3d_offscrn;
  589.             break;
  590.         }
  591.         #endif
  592.     
  593.         #ifdef VICTOR
  594.         case SCREEN_VICTOR:
  595.             //minx = (Canv_game->cv_bitmap.bm_w - Game_window_w)/2;
  596.             //miny = (max_window_h - Game_window_h)/2;
  597.             //maxx = minx + Game_window_w - 1;
  598.             //maxy = miny + Game_window_h - 1;
  599.         
  600.             minx = 0; miny = 0;
  601.             maxx = 319; maxy = 199;
  602.  
  603.             gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, minx, miny, maxx-minx+1, maxy-miny+1 );
  604.             Game_cockpit_copy_code = NULL;
  605.             gr_set_current_canvas(Canv_game);
  606.             bmp =    &Canv_game->cv_bitmap;
  607.             gr_init_sub_canvas( &_canv_3d, Canv_game, bmp->bm_x, bmp->bm_y, bmp->bm_w, bmp->bm_h );
  608.             Canv_3d = &_canv_3d;
  609.             Canv_3d_offscrn = &_canv_3d_offscrn;
  610.     
  611.             if (Canv_victor[0]==NULL)
  612.                 Canv_victor[0] = gr_create_canvas( 320,100 );
  613.             if (Canv_victor[1]==NULL)
  614.                 Canv_victor[1] = gr_create_canvas( 320,100 );
  615.  
  616.             gr_init_sub_canvas(&Canv_victor_3d[0], Canv_victor[0], 0, 0, maxx-minx+1, (maxy-miny+1)/2 );
  617.             gr_init_sub_canvas(&Canv_victor_3d[1], Canv_victor[1], 0, 0, maxx-minx+1, (maxy-miny+1)/2 );
  618.     
  619.             Assert( Canv_victor[0] != NULL );
  620.             Assert( Canv_victor[1] != NULL );
  621.     
  622.             break;
  623.         #endif
  624.     
  625.         case SCREEN_EDITOR:
  626.             Canv_3d = Canv_game;
  627.             Canv_3d_offscrn = Canv_game_offscrn;
  628.             break;
  629.  
  630.         default:
  631.             Error( "Invalid screen type in game.c" );
  632.     
  633.     }
  634. }
  635.  
  636. //selects a given cockpit (or lack of one).  See types in game.h
  637. void select_cockpit(int mode)
  638. {
  639.     if (mode != Cockpit_mode) {        //new mode
  640.         Cockpit_mode=mode;
  641.         init_game_screen();
  642.     }
  643. }
  644.  
  645. //force cockpit redraw next time. call this if you've trashed the screen
  646. void reset_cockpit()
  647. {
  648.     force_cockpit_redraw=1;
  649.  
  650. }
  651.  
  652. void HUD_clear_messages();
  653.  
  654. toggle_cockpit()
  655. {
  656.     int new_mode;
  657.  
  658.     switch (Cockpit_mode) {
  659.  
  660.         case CM_FULL_COCKPIT:
  661.             if (Game_window_h > max_window_h)            //too big for scalable
  662.                 new_mode = CM_FULL_SCREEN;
  663.             else
  664.                 new_mode = CM_STATUS_BAR;
  665.             break;
  666.  
  667.         case CM_STATUS_BAR:
  668.         case CM_FULL_SCREEN:
  669.             if (Rear_view)
  670.                 return;
  671.             new_mode = CM_FULL_COCKPIT;
  672.             break;
  673.  
  674.         case CM_REAR_VIEW:
  675.         case CM_LETTERBOX:
  676.             return;            //do nothing
  677.             break;
  678.  
  679.     }
  680.  
  681.     select_cockpit(new_mode);
  682.     HUD_clear_messages();
  683. }
  684.  
  685. #define WINDOW_W_DELTA 24    //20
  686. #define WINDOW_H_DELTA 12    //10
  687.  
  688. #define WINDOW_MIN_W        160
  689.  
  690. grow_window()
  691. {
  692.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  693.         Game_window_h = max_window_h;
  694.         Game_window_w = Canv_game->cv_w;
  695.         toggle_cockpit();
  696.         grow_window();
  697.         HUD_init_message("Press F3 to return to Cockpit mode");
  698.         return;
  699.     }
  700.  
  701.     if (Cockpit_mode != CM_STATUS_BAR)
  702.         return;
  703.  
  704.     if (Canv_3d->cv_bitmap.bm_h == max_window_h) {
  705.  
  706.         //select_cockpit(CM_FULL_COCKPIT);
  707.         select_cockpit(CM_FULL_SCREEN);
  708.  
  709.     }
  710.     else {
  711.         int x,y,w,h;
  712.  
  713.         w = Canv_3d->cv_bitmap.bm_w + WINDOW_W_DELTA;
  714.         h = Canv_3d->cv_bitmap.bm_h + WINDOW_H_DELTA;
  715.  
  716.         if (w > Canv_game->cv_bitmap.bm_w)
  717.             w = Canv_game->cv_bitmap.bm_w;
  718.  
  719.         if (h > max_window_h)
  720.             h = max_window_h;
  721.  
  722.         x = (Canv_game->cv_bitmap.bm_w - w)/2;
  723.         y = (max_window_h - h)/2;
  724.  
  725.         gr_init_sub_canvas( &_canv_3d, Canv_game, x, y, w,h  );
  726.         gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, x, y, w, h );
  727.  
  728.         Game_window_w = w;
  729.         Game_window_h = h;
  730.  
  731.         //@@init_reticle();            
  732.     }
  733. HUD_clear_messages();    //    @mk, 11/11/94
  734. }
  735.  
  736. grs_bitmap background_bitmap;
  737.  
  738. copy_background_rect(int left,int top,int right,int bot)
  739. {
  740.     grs_bitmap *bm = &background_bitmap;
  741.     int x,y;
  742.     int tile_left,tile_right,tile_top,tile_bot;
  743.     int ofs_x,ofs_y;
  744.     int dest_x,dest_y;
  745.  
  746.     tile_left = left / bm->bm_w;
  747.     tile_right = right / bm->bm_w;
  748.     tile_top = top / bm->bm_h;
  749.     tile_bot = bot / bm->bm_h;
  750.  
  751.     ofs_y = top % bm->bm_h;
  752.     dest_y = top;
  753.  
  754.     for (y=tile_top;y<=tile_bot;y++) {
  755.         int w,h;
  756.  
  757.         ofs_x = left % bm->bm_w;
  758.         dest_x = left;
  759.  
  760.         //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
  761.         h = min(bot-dest_y+1,bm->bm_h-ofs_y);
  762.  
  763.         for (x=tile_left;x<=tile_right;x++) {
  764.  
  765.             //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
  766.             w = min(right-dest_x+1,bm->bm_w-ofs_x);
  767.         
  768.             gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
  769.                     &background_bitmap,&grd_curcanv->cv_bitmap);
  770.  
  771.             ofs_x = 0;
  772.             dest_x += w;
  773.         }
  774.  
  775.         ofs_y = 0;
  776.         dest_y += h;
  777.     }
  778.  
  779.  
  780. }
  781.  
  782. fill_background(int x,int y,int w,int h,int dx,int dy)
  783. {
  784.     gr_set_current_canvas(Canv_game);
  785.     copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
  786.     copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
  787.     copy_background_rect(x,y-dy,x+w-1,y-1);
  788.     copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
  789. }
  790.  
  791. shrink_window()
  792. {
  793.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  794.         Game_window_h = max_window_h;
  795.         Game_window_w = Canv_game->cv_w;
  796.         toggle_cockpit();
  797.         shrink_window();
  798.         shrink_window();
  799.         HUD_init_message("Press F3 to return to Cockpit mode");
  800.         return;
  801.     }
  802.  
  803.     if (Cockpit_mode == CM_FULL_SCREEN )    {
  804.         Game_window_h = max_window_h;
  805.         select_cockpit(CM_STATUS_BAR);
  806.         return;
  807.     }
  808.  
  809.     if (Cockpit_mode != CM_STATUS_BAR)
  810.         return;
  811.  
  812.     if (Canv_3d->cv_bitmap.bm_w > WINDOW_MIN_W) {
  813.         int x,y,w,h,dx,dy;
  814.  
  815.         dx = WINDOW_W_DELTA/2;
  816.         dy = WINDOW_H_DELTA/2;
  817.  
  818.         w = Canv_3d->cv_bitmap.bm_w - WINDOW_W_DELTA;
  819.         h = Canv_3d->cv_bitmap.bm_h - WINDOW_H_DELTA;
  820.  
  821.         x = (Canv_game->cv_bitmap.bm_w - w)/2;
  822.         y = (max_window_h - h)/2;
  823.  
  824.         fill_background(x,y,w,h,dx,dy);
  825.  
  826.         gr_init_sub_canvas( &_canv_3d, Canv_game, x, y, w,h  );
  827.         gr_init_sub_canvas(&_canv_3d_offscrn, Canv_game_offscrn, x, y, w, h );
  828.  
  829.         Game_window_w = w;
  830.         Game_window_h = h;
  831.  
  832.         //@@init_reticle();            
  833.     }
  834.  
  835.     HUD_clear_messages();
  836.  
  837. }
  838.  
  839.  
  840. //called to change the screen mode. Parameter sm is the new mode, one of
  841. //SMODE_GAME or SMODE_EDITOR. returns mode acutally set (could be other
  842. //mode if cannot init requested mode)
  843. int set_screen_mode(int sm)
  844. {
  845.     #ifdef VFX
  846.     if ( (sm==SCREEN_GAME) && (Game_vfx_flag) ) 
  847.         sm=SCREEN_VFX;
  848.     #endif
  849.  
  850.     #ifdef VICTOR
  851.     if ( (sm==SCREEN_GAME) && (Game_victor_flag) ) 
  852.         sm=SCREEN_VICTOR;
  853.     #endif
  854.  
  855.     if (Screen_mode == sm) return Screen_mode;              //already set
  856.  
  857.     //create our off-screen buffer
  858.  
  859.     if (Canv_game_offscrn == NULL )    {
  860.         #ifdef VFX
  861.         if ( Game_vfx_flag )
  862.             Canv_game_offscrn = gr_create_canvas(320,240);
  863.         else
  864.         #endif
  865.             Canv_game_offscrn = gr_create_canvas(GAMESCREEN_MAX_W,GAMESCREEN_MAX_H);
  866.     }
  867.  
  868.     Screen_mode = sm;
  869.  
  870.     switch( sm )    {
  871.     case SCREEN_GAME:
  872.         if (grd_curscreen->sc_mode != GRMODE_GAME )    
  873.             if (gr_set_mode(GRMODE_GAME)) Error(TXT_CANNOT_SET_SCREEN);
  874.  
  875.         Canv_game = &grd_curscreen->sc_canvas;
  876.  
  877.         Game_window_w = Canv_game->cv_w;
  878.         max_window_h = Game_window_h = Canv_game->cv_h - cockpit_bitmap[CM_STATUS_BAR]->bm_h;
  879.  
  880.         #ifdef EDITOR
  881.             Canv_editor = NULL;
  882.         #endif
  883.  
  884.         set_warn_func(game_show_warning);
  885.         break;
  886.  
  887.     #ifdef VFX
  888.     case SCREEN_VFX:
  889.         if (grd_curscreen->sc_mode != GRMODE_VFX)    
  890.             if (gr_set_mode(GRMODE_VFX)) Error("Cannot set screen mode for vfx mode");
  891.         Cockpit_mode = CM_FULL_SCREEN;
  892.  
  893.         Canv_vfx[0][0] = gr_create_sub_canvas(grd_curcanv,0,0,320,240);
  894.         Canv_vfx[0][0]->cv_bitmap.bm_rowsize *= 2;
  895.         Canv_vfx[0][1] = gr_create_sub_canvas(grd_curcanv,0,1,320,240);
  896.         Canv_vfx[0][1]->cv_bitmap.bm_rowsize *= 2;
  897.  
  898.         Canv_vfx[1][0] = gr_create_sub_canvas(grd_curcanv,320,0,320,240);
  899.         Canv_vfx[1][0]->cv_bitmap.bm_rowsize *= 2;
  900.         Canv_vfx[1][1] = gr_create_sub_canvas(grd_curcanv,320,1,320,240);
  901.         Canv_vfx[1][1]->cv_bitmap.bm_rowsize *= 2;
  902.  
  903.         vfx_init_graphics();
  904.     
  905.         Canv_game = &grd_curscreen->sc_canvas;
  906.         Canv_game->cv_bitmap.bm_rowsize *= 2;
  907.  
  908.         #ifdef EDITOR
  909.             Canv_editor = NULL;
  910.         #endif
  911.  
  912.         set_warn_func(game_show_warning);
  913.         break;
  914.     #endif
  915.  
  916.     #ifdef VICTOR
  917.     case SCREEN_VICTOR:
  918.         if (grd_curscreen->sc_mode != GRMODE_VICTOR)    
  919.             if (gr_set_mode(GRMODE_VICTOR)) Error("Cannot set screen mode for victor mode");
  920.         Cockpit_mode = CM_FULL_SCREEN;
  921.  
  922.         //victor_init_graphics();
  923.         
  924.         {
  925.             char *vswitch = getenv( "CYBERMAXX" );
  926.             if ( vswitch )    {
  927.                 char *p = strstr( vswitch, "/E:R" ); 
  928.                 if ( p )    {
  929.                     Victor_eye_switch = 1;
  930.                 } else 
  931.                     Victor_eye_switch = 0;
  932.             } else {        
  933.                  Victor_eye_switch = 0;
  934.             }
  935.         }
  936.         Canv_game = &grd_curscreen->sc_canvas;
  937.  
  938.         #ifdef EDITOR
  939.             Canv_editor = NULL;
  940.         #endif
  941.  
  942.         set_warn_func(game_show_warning);
  943.         break;
  944.     #endif
  945.  
  946.     #ifdef EDITOR
  947.     case SCREEN_EDITOR:    {
  948.         int gr_error;
  949.         if (grd_curscreen->sc_mode != GRMODE_EDITOR)    
  950.             if ((gr_error=gr_set_mode(GRMODE_EDITOR))!=0) { //force into game scrren
  951.                 Warning("Cannot init editor screen (error=%d)",gr_error);
  952.                 return set_screen_mode(SCREEN_GAME);
  953.             }
  954.             gr_palette_load( gr_palette );
  955.         Canv_editor = &grd_curscreen->sc_canvas;
  956.  
  957.         init_editor_screen();   //setup other editor stuff
  958.         }
  959.         break;
  960.     #endif
  961.  
  962.     default:
  963.         Error("Invalid screen mode %d",sm);
  964.     }
  965.  
  966.     init_game_screen();     //reinitialize canvases for new screen
  967.  
  968.     return Screen_mode;
  969. }
  970.  
  971. #ifndef RELEASE
  972. fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
  973. fix frame_time_total=0;
  974. int frame_time_cntr=0;
  975.  
  976. show_framerate()
  977. {
  978.     float rate;
  979.             
  980.     frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
  981.     frame_time_list[frame_time_cntr] = RealFrameTime;
  982.     frame_time_cntr = (frame_time_cntr+1)%8;
  983.  
  984.     rate = f2fl(fixdiv(f1_0*8,frame_time_total));
  985.  
  986.     gr_set_curfont( GAME_FONT );    
  987.     gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  988.  
  989.     gr_printf(grd_curcanv->cv_w-50,grd_curcanv->cv_h-20,"FPS: %2.2f ",rate);
  990.  
  991. }
  992. #endif
  993.  
  994. static timer_paused=0;        
  995.  
  996. void stop_time()
  997. {
  998.     if (timer_paused==0) {
  999.         fix time;
  1000.         time = timer_get_fixed_seconds();
  1001.         last_timer_value = time - last_timer_value;
  1002.         if (last_timer_value < 0) {
  1003.             #if defined(TIMER_TEST) && !defined(NDEBUG)
  1004.             Int3();        //get Matt!!!!
  1005.             #endif
  1006.             last_timer_value = 0;
  1007.         }
  1008.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1009.         time_stopped = time;
  1010.         #endif
  1011.     }
  1012.     timer_paused++;
  1013.  
  1014.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1015.     stop_count++;
  1016.     #endif
  1017. }
  1018.  
  1019. void start_time()
  1020. {
  1021.     timer_paused--;
  1022.     Assert(timer_paused >= 0);
  1023.     if (timer_paused==0) {
  1024.         fix time;
  1025.         time = timer_get_fixed_seconds();
  1026.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1027.         if (last_timer_value < 0)
  1028.             Int3();        //get Matt!!!!
  1029.         }
  1030.         #endif
  1031.         last_timer_value = time - last_timer_value;
  1032.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1033.         time_started = time;
  1034.         #endif
  1035.     }
  1036.  
  1037.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1038.     start_count++;
  1039.     #endif
  1040. }
  1041.  
  1042. void game_flush_inputs()
  1043. {
  1044.     int dx,dy;
  1045.     key_flush();
  1046.     joy_flush();            
  1047.     mouse_flush();
  1048.     mouse_get_delta( &dx, &dy );    // Read mouse
  1049.     memset(&Controls,0,sizeof(control_info));
  1050. }
  1051.  
  1052. void reset_time()
  1053. {
  1054.     last_timer_value = timer_get_fixed_seconds();
  1055.  
  1056. }
  1057.  
  1058. void calc_frame_time()
  1059. {
  1060.     fix timer_value,last_frametime = FrameTime;
  1061.  
  1062.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1063.     _last_frametime = last_frametime;
  1064.     #endif
  1065.  
  1066.     timer_value = timer_get_fixed_seconds();
  1067.     FrameTime = timer_value - last_timer_value;
  1068.  
  1069.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1070.     _timer_value = timer_value;
  1071.     #endif
  1072.     
  1073.     #ifndef NDEBUG
  1074.     if (!(((FrameTime > 0) && (FrameTime <= F1_0)) || (Function_mode == FMODE_EDITOR) || (Newdemo_state == ND_STATE_PLAYBACK))) {
  1075.         mprintf((1,"Bad FrameTime - value = %x\n",FrameTime));
  1076.         if (FrameTime == 0)
  1077.             Int3();    //    Call Mike or Matt or John!  Your interrupts are probably trashed!
  1078. //        if ( !dpmi_virtual_memory )
  1079. //            Int3();        //Get MATT if hit this!
  1080.     }
  1081.     #endif
  1082.  
  1083.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1084.     actual_last_timer_value = last_timer_value;
  1085.     #endif
  1086.  
  1087.     if ( Game_turbo_mode )
  1088.         FrameTime *= 2;
  1089.  
  1090.     // Limit frametime to be between 5 and 150 fps.
  1091.     RealFrameTime = FrameTime;
  1092.     if ( FrameTime < F1_0/150 ) FrameTime = F1_0/150;
  1093.     if ( FrameTime > F1_0/5 ) FrameTime = F1_0/5;
  1094.  
  1095.     last_timer_value = timer_value;
  1096.  
  1097.     if (FrameTime < 0)                        //if bogus frametime...
  1098.         FrameTime = last_frametime;        //...then use time from last frame
  1099.  
  1100.     #ifndef NDEBUG
  1101.     if (fixed_frametime) FrameTime = fixed_frametime;
  1102.     #endif
  1103.  
  1104.     #ifndef NDEBUG
  1105.     // Pause here!!!
  1106.     if ( Debug_pause )      {
  1107.         int c;
  1108.         c = 0;
  1109.         while( c==0 )
  1110.             c = key_peekkey();
  1111.             
  1112.         if ( c == KEY_P )       {
  1113.             Debug_pause = 0;
  1114.             c = key_inkey();
  1115.         }
  1116.         last_timer_value = timer_get_fixed_seconds();
  1117.     }
  1118.     #endif
  1119.  
  1120.     #if Arcade_mode
  1121.         FrameTime /= 2;
  1122.     #endif
  1123.  
  1124.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1125.     stop_count = start_count = 0;
  1126.     #endif
  1127.  
  1128.     //    Set value to determine whether homing missile can see target.
  1129.     //    The lower frametime is, the more likely that it can see its target.
  1130.     if (FrameTime <= F1_0/16)
  1131.         Min_trackable_dot = 3*(F1_0 - MIN_TRACKABLE_DOT)/4 + MIN_TRACKABLE_DOT;
  1132.     else if (FrameTime < F1_0/4)
  1133.         Min_trackable_dot = fixmul(F1_0 - MIN_TRACKABLE_DOT, F1_0-4*FrameTime) + MIN_TRACKABLE_DOT;
  1134.     else
  1135.         Min_trackable_dot = MIN_TRACKABLE_DOT;
  1136.  
  1137. }
  1138.  
  1139. //--unused-- int Auto_flythrough=0;  //if set, start flythough automatically
  1140.  
  1141. void move_player_2_segment(segment *seg,int side)
  1142. {
  1143.     vms_vector vp;
  1144.  
  1145.     compute_segment_center(&ConsoleObject->pos,seg);
  1146.     compute_center_point_on_side(&vp,seg,side);
  1147.     vm_vec_sub2(&vp,&ConsoleObject->pos);
  1148.     vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
  1149.  
  1150.     obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
  1151.     
  1152. }
  1153.  
  1154. fix Show_view_text_timer = -1;
  1155.  
  1156. #ifndef NDEBUG
  1157.  
  1158. draw_window_label()
  1159. {
  1160.     if ( Show_view_text_timer > 0 )
  1161.     {
  1162.         char *viewer_name,*control_name;
  1163.  
  1164.         Show_view_text_timer -= FrameTime;
  1165.         gr_set_curfont( GAME_FONT );
  1166.  
  1167.         switch( Viewer->type )
  1168.         {
  1169.             case OBJ_FIREBALL:    viewer_name = "Fireball"; break;
  1170.             case OBJ_ROBOT:        viewer_name = "Robot"; break;
  1171.             case OBJ_HOSTAGE:        viewer_name = "Hostage"; break;
  1172.             case OBJ_PLAYER:        viewer_name = "Player"; break;
  1173.             case OBJ_WEAPON:        viewer_name = "Weapon"; break;
  1174.             case OBJ_CAMERA:        viewer_name = "Camera"; break;
  1175.             case OBJ_POWERUP:        viewer_name = "Powerup"; break;
  1176.             case OBJ_DEBRIS:        viewer_name = "Debris"; break;
  1177.             case OBJ_CNTRLCEN:    viewer_name = "Control Center"; break;
  1178.             default:                    viewer_name = "Unknown"; break;
  1179.         }
  1180.  
  1181.         switch ( Viewer->control_type) {
  1182.             case CT_NONE:            control_name = "Stopped"; break;
  1183.             case CT_AI:                control_name = "AI"; break;
  1184.             case CT_FLYING:        control_name = "Flying"; break;
  1185.             case CT_SLEW:            control_name = "Slew"; break;
  1186.             case CT_FLYTHROUGH:    control_name = "Flythrough"; break;
  1187.             case CT_MORPH:            control_name = "Morphing"; break;
  1188.             default:                    control_name = "Unknown"; break;
  1189.         }
  1190.  
  1191.         gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
  1192.         gr_printf( 0x8000, 45, "%s View - %s",viewer_name,control_name );
  1193.  
  1194.     }
  1195. }
  1196. #endif
  1197.  
  1198. #ifdef VFX
  1199. int vfx_page=0;
  1200.  
  1201. extern void gr_bm_ubitblt02_2x(short w, short h, short dx, short dy, short sx, short sy, grs_bitmap * src, grs_bitmap * dest);
  1202. extern void gr_bm_ubitblt00_2x(short w, short h, short dx, short dy, short sx, short sy, grs_bitmap * src, grs_bitmap * dest);
  1203.  
  1204.  
  1205. fix eye_offset = F1_0/2;
  1206.  
  1207. //render a frame for the game in stereo
  1208. game_render_frame_stereo_vfx()
  1209. {
  1210.     int i,w,h,y;
  1211.     fix save_aspect;
  1212.  
  1213.     if (grd_curscreen->sc_mode != GRMODE_VFX )    {
  1214.         gr_set_mode( GRMODE_VFX );
  1215.         vfx_init_graphics();
  1216.     }
  1217.  
  1218.     save_aspect = grd_curscreen->sc_aspect;
  1219.     if ( Game_vfx_flag == 2 )
  1220.         grd_curscreen->sc_aspect /= 2;    //Muck with aspect ratio
  1221.  
  1222.     vfx_page ^= 1;
  1223.     for ( i=0; i<2; i++ )    {
  1224.  
  1225. //        if ( keyd_pressed[KEY_F11]) eye_offset -= F1_0/100;
  1226. //        if ( keyd_pressed[KEY_F12]) eye_offset += F1_0/100;
  1227. //        if ( keyd_pressed[KEY_F11] || keyd_pressed[KEY_F12] )    {
  1228. //            mprintf( 0, "Eye offset is %.8f\n", f2fl(eye_offset) );
  1229. //        }
  1230.         gr_set_current_canvas(Canv_3d_offscrn);
  1231.  
  1232.         if (i==0)
  1233.             render_frame(-eye_offset);        // Left eye
  1234.         else
  1235.             render_frame(eye_offset);        // Right eye
  1236.  
  1237.         #ifdef ARCADE
  1238.         arcade_frame_info();
  1239.         #endif
  1240.  
  1241.         Canv_3d = Canv_vfx[i][vfx_page];
  1242.  
  1243.         w = Canv_3d_offscrn->cv_bitmap.bm_w;
  1244.         h = Canv_3d_offscrn->cv_bitmap.bm_h;
  1245.  
  1246.         if ( Game_vfx_flag == 1 )    {
  1247.             for (y=0; y<h; y++ )    {    
  1248.                 gr_bm_ubitblt02_2x( w*2, 1, 0, y*2, 0, y, &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap);
  1249.                 gr_bm_ubitblt02_2x( w*2, 1, 0, y*2+1, 0, y, &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap);
  1250.             }
  1251.         } else {
  1252.             for (y=0; y<h; y++ )    {    
  1253.                 gr_bm_ubitblt02_2x( w*2, 1, 0, y, 0, y, &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap);
  1254.             }
  1255.             //gr_bm_ubitblt( w, h, 0, 0, 0, 0, &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap);
  1256.         } 
  1257.     }
  1258.  
  1259.     vfx_set_page(vfx_page);        // 0 or 1
  1260.  
  1261.     grd_curscreen->sc_aspect = save_aspect; //restore aspect
  1262.  
  1263.  
  1264. }
  1265. #endif
  1266.  
  1267.  
  1268. #ifdef VICTOR
  1269. //render a frame for the game in stereo
  1270. game_render_frame_stereo_victor()
  1271. {
  1272.     int i,w,h,y;
  1273.     fix save_aspect;
  1274.  
  1275.     save_aspect = grd_curscreen->sc_aspect;
  1276.     grd_curscreen->sc_aspect *= 2;    //Muck with aspect ratio
  1277.  
  1278.     for ( i=0; i<2; i++ )    {
  1279.  
  1280.         gr_set_current_canvas(&Canv_victor_3d[i]);
  1281.  
  1282.         if (i==0)
  1283.             render_frame(-F1_0);        // Left eye
  1284.         else
  1285.             render_frame(F1_0);        // Right eye
  1286.  
  1287.     }
  1288.  
  1289.     //Canv_3d = &grd_curscreen->sc_canvas;
  1290.     w = Canv_3d->cv_bitmap.bm_w;
  1291.     h = Canv_3d->cv_bitmap.bm_h;
  1292.  
  1293.     if (!Victor_eye_switch)    {
  1294.         for (y=0; y<h/2; y++ )    {
  1295.             gr_bm_ubitblt( w, 1, 0, y*2+0, 0, y, &Canv_victor_3d[1].cv_bitmap, &Canv_3d->cv_bitmap);
  1296.             gr_bm_ubitblt( w, 1, 0, y*2+1, 0, y, &Canv_victor_3d[0].cv_bitmap, &Canv_3d->cv_bitmap);
  1297.         }
  1298.     } else {            // switch l/r eyes
  1299.         for (y=0; y<h/2; y++ )    {                     
  1300.             gr_bm_ubitblt( w, 1, 0, y*2+0, 0, y, &Canv_victor_3d[0].cv_bitmap, &Canv_3d->cv_bitmap);
  1301.             gr_bm_ubitblt( w, 1, 0, y*2+1, 0, y, &Canv_victor_3d[1].cv_bitmap, &Canv_3d->cv_bitmap);
  1302.         }
  1303.     }
  1304.     grd_curscreen->sc_aspect=save_aspect;
  1305.  
  1306. }
  1307. #endif
  1308.  
  1309.  
  1310. extern fix Cruise_speed;
  1311.  
  1312. // Returns the length of the first 'n' characters of a string.
  1313. int string_width( char * s, int n )
  1314. {
  1315.     int w,h,aw;
  1316.     char p;
  1317.     p = s[n];
  1318.     s[n] = 0;
  1319.     gr_get_string_size( s, &w, &h, &aw );
  1320.     s[n] = p;
  1321.     return w;
  1322. }
  1323.  
  1324. // Draw string 's' centered on a canvas... if wider than
  1325. // canvas, then wrap it.
  1326. void draw_centered_text( int y, char * s )
  1327. {
  1328.     int i, l;
  1329.     char p;
  1330.  
  1331.     l = strlen(s);
  1332.  
  1333.     if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w )    {
  1334.         gr_string( 0x8000, y, s );
  1335.         return;
  1336.     }
  1337.  
  1338.     for (i=0; i<l; i++ )    {
  1339.         if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) )    {
  1340.             p = s[i];
  1341.             s[i] = 0;
  1342.             gr_string( 0x8000, y, s );
  1343.             s[i] = p;
  1344.             gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
  1345.             return;
  1346.         }
  1347.     }
  1348. }
  1349.  
  1350. //render a frame for the game
  1351. void game_render_frame_mono(void)
  1352. {
  1353.     char temp_string[MAX_MULTI_MESSAGE_LEN+25];
  1354.     #ifdef EDITOR
  1355.     fix save_aspect;
  1356.     if (Screen_mode == SCREEN_EDITOR) {
  1357.         save_aspect = grd_curscreen->sc_aspect;
  1358.         #ifndef NDEBUG
  1359.         Game_double_buffer=1;           //can't tmap to VESA screen
  1360.         #endif
  1361.         grd_curscreen->sc_aspect = 0x13333;                     //make like 320x200 screen
  1362.     }
  1363.     #endif
  1364.  
  1365.     gr_set_current_canvas(Game_double_buffer?Canv_3d_offscrn:Canv_3d);
  1366.  
  1367.     render_frame(0);
  1368.  
  1369.     //NEW CODE BY JOHN
  1370.  
  1371.  
  1372.     #ifndef NDEBUG
  1373.     if (Debug_pause) {
  1374.         gr_set_curfont( HELP_FONT );
  1375.         gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
  1376.         gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
  1377.     }
  1378.     #endif
  1379.  
  1380. //--repair--     if (RepairObj) {
  1381. //--repair--         gr_set_curfont( HELP_FONT );
  1382. //--repair--         gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
  1383. //--repair--         gr_ustring( 124, 10, "Repairing");
  1384. //--repair--         gr_ustring( 0x8000, 20, "Press SHIFT-Q to abort" );
  1385. //--repair--     }
  1386.  
  1387.     #ifdef CROSSHAIR
  1388.     if ( Viewer->type == OBJ_PLAYER )
  1389.         laser_do_crosshair(Viewer);
  1390.     #endif
  1391.     
  1392.     #ifndef NDEBUG
  1393.     draw_window_label();
  1394.     #endif
  1395.  
  1396.     if ( (Game_mode&GM_MULTI) && (multi_sending_message))    {
  1397.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1398.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1399.         sprintf( temp_string, "Message: %s_", Network_message );
  1400.         draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
  1401.  
  1402.     }
  1403.  
  1404.     if ( (Game_mode&GM_MULTI) && (multi_defining_message))    {
  1405.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1406.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1407.         sprintf( temp_string, "Macro #%d: %s_", multi_defining_message, Network_message );
  1408.         draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
  1409.     }
  1410.  
  1411.     if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
  1412.         char message[128];
  1413.         int h,w,aw;
  1414.  
  1415.         if (Newdemo_state == ND_STATE_PLAYBACK) {
  1416.             if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
  1417.                   sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
  1418.             } else {
  1419.                 sprintf (message, "");
  1420.             }
  1421.         } else 
  1422.             sprintf (message, TXT_DEMO_RECORDING);
  1423.  
  1424.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1425.         gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
  1426.  
  1427.         gr_get_string_size(message, &w, &h, &aw );
  1428.         if (Cockpit_mode == CM_FULL_COCKPIT)
  1429.             h += 15;
  1430.         else if ( Cockpit_mode == CM_LETTERBOX )
  1431.             h += 7;
  1432.         if (Cockpit_mode != CM_REAR_VIEW)
  1433.             gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
  1434.     }
  1435.  
  1436.     if (!Endlevel_sequence && Fuelcen_control_center_destroyed  && (Fuelcen_seconds_left>-1) && (Fuelcen_seconds_left<127))    {
  1437.         int    y;
  1438.  
  1439.         gr_set_curfont( Gamefonts[4] );    //GAME_FONT );
  1440.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1441.         y = 20;
  1442.         if (!((Cockpit_mode == CM_STATUS_BAR) && (Canv_3d->cv_bitmap.bm_y >= 19)))
  1443.             y += 5;
  1444.         gr_printf(0x8000, y, "T-%d s", Fuelcen_seconds_left );
  1445.     }
  1446.  
  1447.     if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num )    {
  1448.         int    x = 3;
  1449.         int    y = grd_curcanv->cv_bitmap.bm_h;
  1450.  
  1451.         gr_set_curfont( GAME_FONT );
  1452.         gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
  1453.         if (Cruise_speed > 0)
  1454.             if (Cockpit_mode==CM_FULL_SCREEN) {
  1455.                 if (Game_mode & GM_MULTI)
  1456.                     y -= 64;
  1457.                 else
  1458.                     y -= 24;
  1459.             } else if (Cockpit_mode == CM_STATUS_BAR) {
  1460.                 if (Game_mode & GM_MULTI)
  1461.                     y -= 48;
  1462.                 else
  1463.                     y -= 24;
  1464.             } else {
  1465.                 y = 12;
  1466.                 x = 20;
  1467.             }
  1468.  
  1469.             gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
  1470.  
  1471. //        gr_printf( 3, y-20, "Laser: %2d", Players[Player_num].laser_level+1 );
  1472. //        gr_printf( 3, y-10, "Missiles: %2d", Players[Player_num].secondary_ammo[CONCUSSION_INDEX] );
  1473.     }
  1474.  
  1475.     #ifdef ARCADE
  1476.     arcade_frame_info();
  1477.     #endif
  1478.  
  1479. #ifndef RELEASE
  1480.     if (framerate_on)
  1481.         show_framerate();
  1482. #endif
  1483.  
  1484. #ifndef SHAREWARE
  1485.     if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1486.         Game_mode = Newdemo_game_mode;
  1487. #endif
  1488.  
  1489.     draw_hud();
  1490.  
  1491. #ifndef SHAREWARE
  1492.     if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1493.         Game_mode = GM_NORMAL;
  1494. #endif
  1495.  
  1496.     if ( Player_is_dead )
  1497.         player_dead_message();
  1498.  
  1499.     #ifdef VFX
  1500.     if (Cockpit_mode==CM_FULL_SCREEN && special_halfsize_window) {
  1501.         int y,w,h;
  1502.  
  1503.         w = Canv_3d_offscrn->cv_bitmap.bm_w;
  1504.         h = Canv_3d_offscrn->cv_bitmap.bm_h;
  1505.  
  1506.         for (y=0; y<h; y++ )    {    
  1507.             gr_bm_ubitblt00_2x( w*2, 1, 0, y*2, 0, y, &Canv_3d_offscrn->cv_bitmap, &Canv_game->cv_bitmap);
  1508.             gr_bm_ubitblt00_2x( w*2, 1, 0, y*2+1, 0, y, &Canv_3d_offscrn->cv_bitmap, &Canv_game->cv_bitmap);
  1509.         }
  1510.  
  1511.         return;
  1512.     }
  1513.     #endif
  1514.  
  1515.     if (Game_double_buffer) {        //copy to visible screen
  1516.         if ( (Screen_mode == SCREEN_EDITOR) || (Game_cockpit_copy_code==NULL) )
  1517.             gr_bm_ubitblt( Canv_3d->cv_bitmap.bm_w, Canv_3d->cv_bitmap.bm_h, 0, 0, 0, 0, &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap);
  1518.         else
  1519.             if (Cockpit_mode==CM_FULL_SCREEN || Cockpit_mode==CM_STATUS_BAR) {
  1520.                 Int3();        //this case can't happen, can it?  Get Matt if it does.
  1521.                 gr_ibitblt( &Canv_3d_offscrn->cv_bitmap, &Canv_3d->cv_bitmap, Game_cockpit_copy_code );
  1522.             }
  1523.             else
  1524.                 gr_ibitblt( &Canv_3d_offscrn->cv_bitmap, &Canv_game->cv_bitmap, Game_cockpit_copy_code );
  1525.     }
  1526.  
  1527.     #ifdef EDITOR
  1528.     if (Screen_mode == SCREEN_EDITOR) {
  1529.         grd_curscreen->sc_aspect = save_aspect; //restore aspect
  1530.     }
  1531.     #endif
  1532.  
  1533.     play_homing_warning();
  1534.     if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
  1535.  
  1536. #ifndef SHAREWARE
  1537.         if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1538.             Game_mode = Newdemo_game_mode;
  1539. #endif
  1540.  
  1541.         render_gauges();
  1542.  
  1543. #ifndef SHAREWARE
  1544.         if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1545.             Game_mode = GM_NORMAL;
  1546. #endif
  1547.     }
  1548.  
  1549. }
  1550.  
  1551. void game_render_frame()
  1552. {
  1553. //--repair--     if (!check_lsegments_validity()) {
  1554. //--repair--         mprintf(1, "Oops, Lsegments array appears to be bogus.  Recomputing.\n");
  1555. //--repair--         create_local_segment_data();
  1556. //--repair--     }
  1557.  
  1558.     update_cockpits(0);
  1559.  
  1560.     #ifdef VFX                                    
  1561.     if (Screen_mode == SCREEN_VFX) 
  1562.         game_render_frame_stereo_vfx();
  1563.     #endif
  1564.  
  1565.     #ifdef VICTOR
  1566.     if (Screen_mode == SCREEN_VICTOR) 
  1567.         game_render_frame_stereo_victor();
  1568.     #endif
  1569.  
  1570.     if (Screen_mode == SCREEN_GAME )
  1571.         game_render_frame_mono();        
  1572.  
  1573.     #ifdef EDITOR
  1574.     if (Screen_mode == SCREEN_EDITOR )
  1575.         game_render_frame_mono();        
  1576.     #endif
  1577.  
  1578.     // Make sure palette is faded in
  1579.     stop_time();
  1580.     gr_palette_fade_in( gr_palette, 32, 0 );
  1581.     start_time();
  1582.  
  1583. }
  1584.  
  1585. void do_photos();
  1586. void level_with_floor();
  1587.  
  1588. void save_screen_shot(int automap_flag)
  1589. {
  1590.     fix t1;
  1591.     char message[100];
  1592.     grs_canvas *screen_canv=&grd_curscreen->sc_canvas;
  1593.     grs_font *save_font;
  1594.     static savenum=0;
  1595.     grs_canvas *temp_canv,*save_canv;
  1596.     char savename[13];
  1597.     ubyte pal[768];
  1598.     int w,h,aw,x,y;
  1599.  
  1600.     stop_time();
  1601.  
  1602.     save_canv = grd_curcanv;
  1603.     temp_canv = gr_create_canvas(screen_canv->cv_bitmap.bm_w,screen_canv->cv_bitmap.bm_h);
  1604.     gr_set_current_canvas(temp_canv);
  1605.     gr_ubitmap(0,0,&screen_canv->cv_bitmap);
  1606.  
  1607.     if ( savenum > 99 ) savenum = 0;
  1608.     sprintf(savename,"screen%02d.pcx",savenum++);
  1609.     sprintf( message, "%s '%s'", TXT_DUMPING_SCREEN, savename );
  1610.  
  1611.     gr_set_current_canvas(Canv_game);
  1612.     save_font = grd_curcanv->cv_font;
  1613.     gr_set_curfont(GAME_FONT);
  1614.     gr_set_fontcolor(gr_find_closest_color_current(0,31,0),-1);
  1615.     gr_get_string_size(message,&w,&h,&aw);
  1616.     x = (grd_curcanv->cv_bitmap.bm_w-w)/2;
  1617.     y = (grd_curcanv->cv_bitmap.bm_h-h)/2;
  1618.  
  1619.     if (automap_flag) {
  1620.         modex_print_message(32, y, message);
  1621.     } else {
  1622.         gr_setcolor(gr_find_closest_color_current(0,0,0));
  1623.         gr_rect(x-2,y-2,x+w+2,y+h+2);
  1624.         gr_printf(x,y,message);
  1625.         gr_set_curfont(save_font);
  1626.     }
  1627.     t1 = timer_get_fixed_seconds() + F1_0;
  1628.  
  1629.     gr_palette_read(pal);        //get actual palette from the hardware
  1630.     pcx_write_bitmap(savename,&temp_canv->cv_bitmap,pal);
  1631.  
  1632.     while ( timer_get_fixed_seconds() < t1 );        // Wait so that messag stays up at least 1 second.
  1633.  
  1634.     gr_set_current_canvas(screen_canv);
  1635.  
  1636.     if (!automap_flag)
  1637.         gr_ubitmap(0,0,&temp_canv->cv_bitmap);
  1638.  
  1639.     gr_free_canvas(temp_canv);
  1640.  
  1641.     gr_set_current_canvas(save_canv);
  1642.     key_flush();
  1643.     start_time();
  1644. }
  1645.  
  1646. //initialize flying
  1647. fly_init(object *obj)
  1648. {
  1649.     obj->control_type = CT_FLYING;
  1650.     obj->movement_type = MT_PHYSICS;
  1651.  
  1652.     vm_vec_zero(&obj->phys_info.velocity);
  1653.     vm_vec_zero(&obj->phys_info.thrust);
  1654.     vm_vec_zero(&obj->phys_info.rotvel);
  1655.     vm_vec_zero(&obj->phys_info.rotthrust);
  1656. }
  1657.     
  1658. //void morph_test(), morph_step();
  1659.  
  1660. int sound_nums[] = {10,11,20,21,30,31,32,33,40,41,50,51,60,61,62,70,80,81,82,83,90,91};
  1661.  
  1662. #define N_TEST_SOUNDS (sizeof(sound_nums) / sizeof(*sound_nums))
  1663.  
  1664. int test_sound_num=0;
  1665.  
  1666. play_test_sound()
  1667. {
  1668.  
  1669.     digi_play_sample(sound_nums[test_sound_num], F1_0);
  1670. }
  1671.  
  1672. //    ------------------------------------------------------------------------------------
  1673. advance_sound()
  1674. {
  1675.     if (++test_sound_num == N_TEST_SOUNDS)
  1676.         test_sound_num=0;
  1677.  
  1678. }
  1679.  
  1680. test_anim_states();
  1681.  
  1682. #include "fvi.h"
  1683.  
  1684. //put up the help message
  1685. void do_show_help()
  1686. {
  1687. //    if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  1688. //        stop_time();
  1689.  
  1690.     show_help();
  1691.  
  1692. //    if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  1693. //        start_time();
  1694.  
  1695. }
  1696.  
  1697. //--unused-- int save_newdemo_state;
  1698.  
  1699. extern int been_in_editor;
  1700.  
  1701. //--killed--//    ------------------------------------------------------------------------------------
  1702. //--killed--//    Return 1 if toggled, else return 0.
  1703. //--killed--//    Might not be able to toggle if off and not allowed to turn on.
  1704. //--killed--int toggle_afterburner_status(void)
  1705. //--killed--{
  1706. //--killed--    player    *pp = &Players[Player_num];
  1707. //--killed--
  1708. //--killed--    if (!(pp->flags & PLAYER_FLAGS_AFTERBURNER)) {
  1709. //--killed--        //    Was off, try to turn on.
  1710. //--killed--        if ((pp->afterburner_time > AFTERBURNER_MAX_TIME/4) && (pp->energy > 0)) {
  1711. //--killed--            pp->flags |= PLAYER_FLAGS_AFTERBURNER;
  1712. //--killed--        } else {
  1713. //--killed--            mprintf(0, "Cannot turn on afterburner due to energy or recharge.\n");
  1714. //--killed--            return 0;
  1715. //--killed--        }
  1716. //--killed--        return 1;
  1717. //--killed--    } else {
  1718. //--killed--        pp->flags ^= PLAYER_FLAGS_AFTERBURNER;
  1719. //--killed--        return 1;
  1720. //--killed--    }
  1721. //--killed--}
  1722.  
  1723. //    ------------------------------------------------------------------------------------
  1724. void do_cloak_stuff(void)
  1725. {
  1726.     int i;
  1727.     for (i = 0; i < N_players; i++)
  1728.         if (Players[i].flags & PLAYER_FLAGS_CLOAKED) {
  1729.             // mprintf(0, "Cloak time left: %7.3f\n", f2fl(CLOAK_TIME_MAX - (GameTime - Players[Player_num].cloak_time)));
  1730.             if (GameTime - Players[i].cloak_time > CLOAK_TIME_MAX) {
  1731.                 Players[i].flags &= ~PLAYER_FLAGS_CLOAKED;
  1732.                 if (i == Player_num) {
  1733.                     digi_play_sample( SOUND_CLOAK_OFF, F1_0);
  1734.                     if (Game_mode & GM_MULTI)
  1735.                         multi_send_play_sound(SOUND_CLOAK_OFF, F1_0);
  1736.                     maybe_drop_net_powerup(POW_CLOAK);
  1737.                     multi_send_decloak(); // For demo recording
  1738. //                    mprintf((0, " --- You have been DE-CLOAKED! ---\n"));
  1739.                 }
  1740.             }
  1741.         }
  1742. }
  1743.  
  1744. //    ------------------------------------------------------------------------------------
  1745. void do_invulnerable_stuff(void)
  1746. {
  1747.     if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
  1748.         if (GameTime - Players[Player_num].invulnerable_time > INVULNERABLE_TIME_MAX) {
  1749.             Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  1750.             maybe_drop_net_powerup(POW_INVULNERABILITY);
  1751.             digi_play_sample( SOUND_INVULNERABILITY_OFF, F1_0);
  1752.             if (Game_mode & GM_MULTI)
  1753.                 multi_send_play_sound(SOUND_INVULNERABILITY_OFF, F1_0);
  1754.             mprintf((0, " --- You have been DE-INVULNERABLEIZED! ---\n"));
  1755.         }
  1756.     }
  1757. }
  1758.     
  1759. //--killed--//    ------------------------------------------------------------------------------------
  1760. //--killed--void do_afterburner_stuff(void)
  1761. //--killed--{
  1762. //--killed--    player    *pp = &Players[Player_num];
  1763. //--killed--
  1764. //--killed--//    mprintf(0, "[Afterburner] Time: %7.3f, status = %i\n", f2fl(pp->afterburner_time), pp->flags & PLAYER_FLAGS_AFTERBURNER);
  1765. //--killed--
  1766. //--killed--    if (pp->flags & PLAYER_FLAGS_AFTERBURNER) {
  1767. //--killed--        if (pp->afterburner_time > 0) {
  1768. //--killed--            pp->afterburner_time -= FrameTime;
  1769. //--killed--            pp->energy -= FrameTime/2;
  1770. //--killed--            if (pp->afterburner_time <= 0) {
  1771. //--killed--                pp->afterburner_time = 0;
  1772. //--killed--                pp->flags &= ~PLAYER_FLAGS_AFTERBURNER;
  1773. //--killed--                say_afterburner_status();
  1774. //--killed--            }
  1775. //--killed--            if (pp->energy <= 0) {
  1776. //--killed--                pp->energy = 0;
  1777. //--killed--                pp->flags &= ~PLAYER_FLAGS_AFTERBURNER;
  1778. //--killed--                say_afterburner_status();
  1779. //--killed--            }
  1780. //--killed--        }
  1781. //--killed--    } else {
  1782. //--killed--        //    Since afterburner is probably almost always max, do the check, we save time.
  1783. //--killed--        if (pp->afterburner_time < AFTERBURNER_MAX_TIME) {
  1784. //--killed--            pp->afterburner_time += FrameTime/2;
  1785. //--killed--            if (pp->afterburner_time > AFTERBURNER_MAX_TIME)
  1786. //--killed--                pp->afterburner_time = AFTERBURNER_MAX_TIME;
  1787. //--killed--        }
  1788. //--killed--    }
  1789. //--killed--
  1790. //--killed--}
  1791.  
  1792. //    Amount to diminish guns towards normal, per second.
  1793. #define    DIMINISH_RATE    16        //    gots to be a power of 2, else change the code in diminish_palette_towards_normal
  1794.  
  1795. //    ------------------------------------------------------------------------------------
  1796. //    Diminish palette effects towards normal.
  1797. void diminish_palette_towards_normal(void)
  1798. {
  1799.     int    dec_amount = 0;
  1800.  
  1801.     //    Diminish at DIMINISH_RATE units/second.
  1802.     //    For frame rates > DIMINISH_RATE Hz, use randomness to achieve this.
  1803.     if (FrameTime < F1_0/DIMINISH_RATE) {
  1804.         if (rand() < FrameTime*DIMINISH_RATE/2)    //    Note: rand() is in 0..32767, and 8 Hz means decrement every frame
  1805.             dec_amount = 1;
  1806.     } else {
  1807.         dec_amount = f2i(FrameTime*DIMINISH_RATE);        // one second = DIMINISH_RATE counts
  1808.         if (dec_amount == 0)
  1809.             dec_amount++;                        // make sure we decrement by something
  1810.     }
  1811.  
  1812.     if (PaletteRedAdd > 0 ) { PaletteRedAdd -= dec_amount; if (PaletteRedAdd < 0 ) PaletteRedAdd = 0; }
  1813.     if (PaletteRedAdd < 0 ) { PaletteRedAdd += dec_amount; if (PaletteRedAdd > 0 ) PaletteRedAdd = 0; }
  1814.  
  1815.     if (PaletteGreenAdd > 0 ) { PaletteGreenAdd -= dec_amount; if (PaletteGreenAdd < 0 ) PaletteGreenAdd = 0; }
  1816.     if (PaletteGreenAdd < 0 ) { PaletteGreenAdd += dec_amount; if (PaletteGreenAdd > 0 ) PaletteGreenAdd = 0; }
  1817.  
  1818.     if (PaletteBlueAdd > 0 ) { PaletteBlueAdd -= dec_amount; if (PaletteBlueAdd < 0 ) PaletteBlueAdd = 0; }
  1819.     if (PaletteBlueAdd < 0 ) { PaletteBlueAdd += dec_amount; if (PaletteBlueAdd > 0 ) PaletteBlueAdd = 0; }
  1820.  
  1821.     if ( (Newdemo_state==ND_STATE_RECORDING) && (PaletteRedAdd || PaletteGreenAdd || PaletteBlueAdd) )
  1822.         newdemo_record_palette_effect(PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd);
  1823.  
  1824.     gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  1825.  
  1826.     //mprintf(0, "%2i %2i %2i\n", PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd);
  1827. }
  1828.  
  1829. int    Redsave, Bluesave, Greensave;
  1830.  
  1831. void palette_save(void)
  1832. {
  1833.     Redsave = PaletteRedAdd; Bluesave = PaletteBlueAdd; Greensave = PaletteGreenAdd;
  1834. }
  1835.  
  1836. void palette_restore(void)
  1837. {
  1838.     PaletteRedAdd = Redsave; PaletteBlueAdd = Bluesave; PaletteGreenAdd = Greensave;
  1839.     gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  1840. }
  1841.  
  1842. extern void dead_player_frame(void);
  1843.  
  1844. #ifndef RELEASE
  1845. do_cheat_menu()
  1846. {
  1847.     int mmn;
  1848.     newmenu_item mm[16];
  1849.     char score_text[21];
  1850.  
  1851.     sprintf( score_text, "%d", Players[Player_num].score );
  1852.  
  1853.     mm[0].type=NM_TYPE_CHECK; mm[0].value=Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE; mm[0].text="Invulnerability";
  1854.     mm[1].type=NM_TYPE_CHECK; mm[1].value=Players[Player_num].flags & PLAYER_FLAGS_IMMATERIAL; mm[1].text="Immaterial";
  1855.     mm[2].type=NM_TYPE_CHECK; mm[2].value=0; mm[2].text="All keys";
  1856.     mm[3].type=NM_TYPE_NUMBER; mm[3].value=f2i(Players[Player_num].energy); mm[3].text="% Energy"; mm[3].min_value=0; mm[3].max_value=200;
  1857.     mm[4].type=NM_TYPE_NUMBER; mm[4].value=f2i(Players[Player_num].shields); mm[4].text="% Shields"; mm[4].min_value=0; mm[4].max_value=200;
  1858.     mm[5].type=NM_TYPE_TEXT; mm[5].text = "Score:";
  1859.     mm[6].type=NM_TYPE_INPUT; mm[6].text_len = 10; mm[6].text = score_text;
  1860.     mm[7].type=NM_TYPE_RADIO; mm[7].value=(Players[Player_num].laser_level==0); mm[7].group=0; mm[7].text="Laser level 1";
  1861.     mm[8].type=NM_TYPE_RADIO; mm[8].value=(Players[Player_num].laser_level==1); mm[8].group=0; mm[8].text="Laser level 2";
  1862.     mm[9].type=NM_TYPE_RADIO; mm[9].value=(Players[Player_num].laser_level==2); mm[9].group=0; mm[9].text="Laser level 3";
  1863.     mm[10].type=NM_TYPE_RADIO; mm[10].value=(Players[Player_num].laser_level==3); mm[10].group=0; mm[10].text="Laser level 4";
  1864.     mm[11].type=NM_TYPE_NUMBER; mm[11].value=Players[Player_num].secondary_ammo[CONCUSSION_INDEX]; mm[11].text="Missiles"; mm[11].min_value=0; mm[11].max_value=200;
  1865.  
  1866.     mmn = newmenu_do("Wimp Menu",NULL,12, mm, NULL );
  1867.  
  1868.     if (mmn > -1 )    {
  1869.         if ( mm[0].value )  {
  1870.             Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
  1871.             Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  1872.         } else
  1873.             Players[Player_num].flags &= ~PLAYER_FLAGS_INVULNERABLE;
  1874.         if ( mm[1].value ) 
  1875.             Players[Player_num].flags |= PLAYER_FLAGS_IMMATERIAL;
  1876.         else
  1877.             Players[Player_num].flags &= ~PLAYER_FLAGS_IMMATERIAL;
  1878.         if (mm[2].value) Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  1879.         Players[Player_num].energy=i2f(mm[3].value);
  1880.         Players[Player_num].shields=i2f(mm[4].value);
  1881.         Players[Player_num].score = atoi(mm[6].text);
  1882.         if (mm[7].value) Players[Player_num].laser_level=0;
  1883.         if (mm[8].value) Players[Player_num].laser_level=1;
  1884.         if (mm[9].value) Players[Player_num].laser_level=2;
  1885.         if (mm[10].value) Players[Player_num].laser_level=3;
  1886.         Players[Player_num].secondary_ammo[CONCUSSION_INDEX] = mm[11].value;
  1887.         init_gauges();
  1888.     }
  1889. }
  1890. #endif
  1891.  
  1892. //    --------------------------------------------------------------------------------------------------
  1893. int allowed_to_fire_laser(void)
  1894. {
  1895.     if (Player_is_dead) {
  1896.         Global_missile_firing_count = 0;
  1897.         return 0;
  1898.     }
  1899.  
  1900.     //    Make sure enough time has elapsed to fire laser, but if it looks like it will
  1901.     //    be a long while before laser can be fired, then there must be some mistake!
  1902.     if (Next_laser_fire_time > GameTime)
  1903.         if (Next_laser_fire_time < GameTime + 2*F1_0)
  1904.             return 0;
  1905.  
  1906.     return 1;
  1907. }
  1908.  
  1909. fix    Next_flare_fire_time = 0;
  1910.  
  1911. int allowed_to_fire_flare(void)
  1912. {
  1913.     if (Next_flare_fire_time > GameTime)
  1914.         if (Next_flare_fire_time < GameTime + F1_0)    //    In case time is bogus, never wait > 1 second.
  1915.             return 0;
  1916.  
  1917.     Next_flare_fire_time = GameTime + F1_0/4;
  1918.  
  1919.     return 1;
  1920. }
  1921.  
  1922. int allowed_to_fire_missile(void)
  1923. {
  1924. // mprintf(0, "Next fire = %7.3f, Cur time = %7.3f\n", f2fl(Next_missile_fire_time), f2fl(GameTime));
  1925.     //    Make sure enough time has elapsed to fire missile, but if it looks like it will
  1926.     //    be a long while before missile can be fired, then there must be some mistake!
  1927.     if (Next_missile_fire_time > GameTime)
  1928.         if (Next_missile_fire_time < GameTime + 5*F1_0)
  1929.             return 0;
  1930.  
  1931.     return 1;
  1932. }
  1933.  
  1934. typedef struct bkg {
  1935.     short x, y, w, h;            // The location of the menu.
  1936.     grs_bitmap * bmp;            // The background under the menu.
  1937. } bkg;
  1938.  
  1939. bkg bg = {0,0,0,0,NULL};
  1940.  
  1941. //show a message in a nice little box
  1942. show_boxed_message(char *msg)
  1943. {    
  1944.     int w,h,aw;
  1945.     int x,y;
  1946.  
  1947.     gr_set_current_canvas(Canv_game);
  1948.     gr_set_curfont( HELP_FONT );
  1949.  
  1950.     gr_get_string_size(msg,&w,&h,&aw);
  1951.  
  1952.     x = (grd_curscreen->sc_w-w)/2;
  1953.     y = (grd_curscreen->sc_h-h)/2;
  1954.  
  1955.     if (bg.bmp) {
  1956.         gr_free_bitmap(bg.bmp);
  1957.         bg.bmp = NULL;
  1958.     }
  1959.  
  1960.     // Save the background of the display
  1961.     bg.x=x; bg.y=y; bg.w=w; bg.h=h;
  1962.  
  1963.     bg.bmp = gr_create_bitmap( w+30, h+30 );
  1964.     gr_bm_ubitblt(w+30, h+30, 0, 0, x-15, y-15, &(grd_curscreen->sc_canvas.cv_bitmap), bg.bmp );
  1965.  
  1966.     nm_draw_background(x-15,y-15,x+w+15-1,y+h+15-1);
  1967.  
  1968.     gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
  1969.     gr_ustring( 0x8000, y, msg );
  1970.  
  1971. }
  1972.  
  1973. clear_boxed_message()
  1974. {
  1975.  
  1976.     if (bg.bmp) {
  1977.  
  1978.         gr_bitmap(bg.x-15, bg.y-15, bg.bmp);
  1979.  
  1980.         gr_free_bitmap(bg.bmp);
  1981.  
  1982.         bg.bmp = NULL;
  1983.     }
  1984. }
  1985.  
  1986. extern int Death_sequence_aborted;
  1987.  
  1988. //Process selected keys until game unpaused. returns key that left pause (p or esc)
  1989. int do_game_pause(int allow_menu)
  1990. {
  1991.     int paused;
  1992.     int key;
  1993.  
  1994.     if (Game_mode & GM_MULTI)
  1995.     {
  1996.         HUD_init_message(TXT_CANT_PAUSE);
  1997.         return(KEY_PAUSE);
  1998.     }
  1999.  
  2000.     digi_pause_all();
  2001.     stop_time();
  2002.  
  2003.     palette_save();
  2004.     reset_palette_add();
  2005.  
  2006.     game_flush_inputs();
  2007.  
  2008.     paused=1;
  2009.  
  2010.     show_boxed_message(TXT_PAUSE);
  2011.  
  2012.     while (paused) {
  2013.  
  2014.         key = key_getch();
  2015.  
  2016.         switch (key) {
  2017.             case 0:
  2018.                 break;
  2019.  
  2020.             case KEY_ESC:
  2021.                 if (allow_menu)
  2022.                     Function_mode = FMODE_MENU;
  2023.                  clear_boxed_message();
  2024.                 paused=0;
  2025.                 break;
  2026.  
  2027.             case KEY_F1:
  2028.                  clear_boxed_message();
  2029.                 do_show_help();
  2030.                 show_boxed_message(TXT_PAUSE);
  2031.                 break;
  2032.  
  2033.             case KEY_PRINT_SCREEN:
  2034.                 save_screen_shot(0);
  2035.                 break;
  2036.  
  2037.             #ifndef RELEASE
  2038.             case KEY_BACKSP: Int3(); break;
  2039.             #endif
  2040.  
  2041.             default:
  2042.                  clear_boxed_message();
  2043.                 paused=0;
  2044.                 break;
  2045.  
  2046.         }
  2047.  
  2048.     }
  2049.  
  2050.     game_flush_inputs();
  2051.  
  2052.     palette_restore();
  2053.  
  2054.     start_time();
  2055.     digi_resume_all();
  2056.  
  2057.     return key;
  2058. }
  2059.  
  2060.  
  2061. void show_help()
  2062. {
  2063.     newmenu_item m[14];
  2064.  
  2065.     m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_HELP_ESC;
  2066.     m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_HELP_ALT_F2;
  2067.     m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_HELP_ALT_F3;
  2068.     m[ 3].type = NM_TYPE_TEXT; m[ 3].text = TXT_HELP_F2;
  2069.     m[ 4].type = NM_TYPE_TEXT; m[ 4].text = TXT_HELP_F3;
  2070.     m[ 5].type = NM_TYPE_TEXT; m[ 5].text = TXT_HELP_F4;
  2071.     m[ 6].type = NM_TYPE_TEXT; m[ 6].text = TXT_HELP_F5;
  2072.     m[ 7].type = NM_TYPE_TEXT; m[ 7].text = TXT_HELP_PAUSE;
  2073.     m[ 8].type = NM_TYPE_TEXT; m[ 8].text = TXT_HELP_MINUSPLUS;
  2074.     m[ 9].type = NM_TYPE_TEXT; m[ 9].text = TXT_HELP_PRTSCN;
  2075.     m[10].type = NM_TYPE_TEXT; m[10].text = TXT_HELP_1TO5;
  2076.     m[11].type = NM_TYPE_TEXT; m[11].text = TXT_HELP_6TO10;
  2077.     m[12].type = NM_TYPE_TEXT; m[12].text = "";
  2078.     m[13].type = NM_TYPE_TEXT; m[13].text = TXT_HELP_TO_VIEW;
  2079.  
  2080.     newmenu_do( NULL, TXT_KEYS, sizeof(m)/sizeof(*m), m, NULL );
  2081. }
  2082.  
  2083.  
  2084. #ifdef ARCADE
  2085. void arcade_frame_info()
  2086. {
  2087.     if (!Arcade_mode) return;
  2088.  
  2089.     if ( Newdemo_state == ND_STATE_PLAYBACK )    {
  2090.         gr_set_curfont( GAME_FONT );    //game_font );
  2091.         gr_set_fontcolor(gr_getcolor(0,31,0), -1 );
  2092.         gr_printf(0x8000, 5, "Insert Coins to Play" );
  2093.         return;
  2094.     } 
  2095.  
  2096.     if (Arcade_timer > 0 )    {
  2097.         gr_set_curfont( GAME_FONT );
  2098.         gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
  2099.         gr_printf( 0x8000, 5, "%d seconds left", f2i(Arcade_timer) );
  2100.      } else {
  2101.         gr_set_curfont( Gamefonts[GFONT_BIG_1] );    //GAME_FONT );
  2102.         gr_printf(0x8000, 40, "Game Over" );
  2103.     
  2104.         gr_set_curfont( Gamefonts[GFONT_MEDIUM_2] );    //GAME_FONT );
  2105.         gr_printf(0x8000, 60, "Insert Coins to Continue" );
  2106.         gr_printf(0x8000, 75, "%d", f2i(Arcade_timer)+10 );
  2107.     }    
  2108. }
  2109. #endif
  2110.  
  2111. //temp function until Matt cleans up game sequencing
  2112. extern void temp_reset_stuff_on_level();
  2113.  
  2114. int old_cockpit_mode;
  2115.  
  2116. //deal with rear view - switch it on, or off, or whatever
  2117. check_rear_view()
  2118. {
  2119.  
  2120.     #define LEAVE_TIME 0x4000        //how long until we decide key is down
  2121.  
  2122.     static int leave_mode;
  2123.     static fix entry_time;
  2124.  
  2125.     if ( Controls.rear_view_down_count )    {        //key/button has gone down
  2126.  
  2127.         if (Rear_view) {
  2128.             Rear_view = 0;
  2129.             if (Cockpit_mode==CM_REAR_VIEW) {
  2130.                 select_cockpit(old_cockpit_mode);
  2131.             }
  2132.             if (Newdemo_state == ND_STATE_RECORDING)
  2133.                 newdemo_record_restore_rearview();
  2134.         }
  2135.         else {
  2136.             Rear_view = 1;
  2137.             leave_mode = 0;        //means wait for another key
  2138.             entry_time = timer_get_fixed_seconds();
  2139.             if (Cockpit_mode == CM_FULL_COCKPIT) {
  2140.                 old_cockpit_mode = Cockpit_mode;
  2141.                 select_cockpit(CM_REAR_VIEW);
  2142.             }
  2143.             if (Newdemo_state == ND_STATE_RECORDING)
  2144.                 newdemo_record_rearview();
  2145.         }
  2146.     }
  2147.     else
  2148.         if (Controls.rear_view_down_state) {
  2149.  
  2150.             if (leave_mode==0 && (timer_get_fixed_seconds()-entry_time)>LEAVE_TIME)
  2151.                 leave_mode = 1;
  2152.         }
  2153.         else {
  2154.  
  2155.             //@@if (leave_mode==1 && Cockpit_mode==CM_REAR_VIEW) {
  2156.  
  2157.             if (leave_mode==1 && Rear_view) {
  2158.                 Rear_view = 0;
  2159.                 if (Cockpit_mode==CM_REAR_VIEW) {
  2160.                     select_cockpit(old_cockpit_mode); 
  2161.                 }
  2162.                 if (Newdemo_state == ND_STATE_RECORDING)
  2163.                     newdemo_record_restore_rearview();
  2164.             }
  2165.         }
  2166. }
  2167.  
  2168. void reset_rear_view(void)
  2169. {
  2170.     Rear_view = 0;
  2171.  
  2172.     if (Cockpit_mode == CM_REAR_VIEW)
  2173.         select_cockpit(old_cockpit_mode);
  2174. }
  2175.  
  2176. #ifdef ARCADE
  2177. int keys_override;
  2178. #endif
  2179.  
  2180. int Automap_flag;
  2181. int Config_menu_flag;
  2182.  
  2183. jmp_buf LeaveGame;
  2184.  
  2185.  
  2186. #ifndef FINAL_CHEATS
  2187. ubyte cheat_enable_keys[] = {KEY_G,KEY_A,KEY_B,KEY_B,KEY_A,KEY_G,KEY_A,KEY_B,KEY_B,KEY_A,KEY_H,KEY_E,KEY_Y};
  2188. #endif
  2189.  
  2190. int cheat_enable_index;
  2191. #define CHEAT_ENABLE_LENGTH (sizeof(cheat_enable_keys) / sizeof(*cheat_enable_keys))
  2192.  
  2193. #ifdef FINAL_CHEATS
  2194. ubyte cheat_enable_keys[] = {KEY_G,KEY_A,KEY_B,KEY_B,KEY_A,KEY_G,KEY_A,KEY_B,KEY_B,KEY_A,KEY_H,KEY_E,KEY_Y};
  2195.  
  2196. ubyte cheat_wowie[] = {KEY_S,KEY_C,KEY_O,KEY_U,KEY_R,KEY_G,KEY_E};
  2197. ubyte cheat_allkeys[] = {KEY_M,KEY_I,KEY_T,KEY_Z,KEY_I};
  2198. ubyte cheat_invuln[] = {KEY_R,KEY_A,KEY_C,KEY_E,KEY_R,KEY_X};
  2199. ubyte cheat_cloak[] = {KEY_G,KEY_U,KEY_I,KEY_L,KEY_E};
  2200. ubyte cheat_shield[] = {KEY_T,KEY_W,KEY_I,KEY_L,KEY_I,KEY_G,KEY_H,KEY_T};
  2201. ubyte cheat_warp[] = {KEY_F,KEY_A,KEY_R,KEY_M,KEY_E,KEY_R,KEY_J,KEY_O,KEY_E};
  2202. ubyte cheat_turbomode[] = { KEY_B, KEY_U, KEY_G, KEY_G, KEY_I, KEY_N };
  2203. ubyte cheat_faster[] = { KEY_F, KEY_L, KEY_A, KEY_S, KEY_H };
  2204.  
  2205. #define CHEAT_WOWIE_LENGTH (sizeof(cheat_wowie) / sizeof(*cheat_wowie))
  2206. #define CHEAT_ALLKEYS_LENGTH (sizeof(cheat_allkeys) / sizeof(*cheat_allkeys))
  2207. #define CHEAT_INVULN_LENGTH (sizeof(cheat_invuln) / sizeof(*cheat_invuln))
  2208. #define CHEAT_CLOAK_LENGTH (sizeof(cheat_cloak) / sizeof(*cheat_cloak))
  2209. #define CHEAT_SHIELD_LENGTH (sizeof(cheat_shield) / sizeof(*cheat_shield))
  2210. #define CHEAT_WARP_LENGTH (sizeof(cheat_warp) / sizeof(*cheat_warp))
  2211. #define CHEAT_TURBOMODE_LENGTH (sizeof(cheat_turbomode) / sizeof(*cheat_turbomode))
  2212. #define CHEAT_FASTER_LENGTH (sizeof(cheat_faster) / sizeof(*cheat_faster))
  2213.  
  2214. int cheat_wowie_index;
  2215. int cheat_allkeys_index;
  2216. int cheat_invuln_index;
  2217. int cheat_cloak_index;
  2218. int cheat_shield_index;
  2219. int cheat_warp_index;
  2220. int cheat_turbomode_index;
  2221. int cheat_faster_index;
  2222.  
  2223. #endif
  2224.  
  2225. int Cheats_enabled=0;
  2226.  
  2227. void game_disable_cheats()
  2228. {
  2229.     Game_turbo_mode = 0;
  2230.     Cheats_enabled=0;
  2231. }
  2232.  
  2233. //    ------------------------------------------------------------------------------------
  2234. //this function is the game.  called when game mode selected.  runs until
  2235. //editor mode or exit selected
  2236. void game()
  2237. {
  2238.     //@@int demo_playing=0;
  2239.     //@@int multi_game=0;
  2240.  
  2241.     Game_aborted = 0;
  2242.     last_drawn_cockpit = -1;                // Force cockpit to redraw next time a frame renders.
  2243.     Endlevel_sequence = 0;                    // force to zero to avoid being in exit sequence when starting game or demo
  2244.  
  2245.     cheat_enable_index = 0;
  2246.  
  2247. #ifdef FINAL_CHEATS
  2248.     cheat_wowie_index = cheat_allkeys_index = cheat_invuln_index = cheat_cloak_index = cheat_shield_index = cheat_warp_index = 0;
  2249.     cheat_turbomode_index = cheat_faster_index = 0;
  2250. #endif
  2251.  
  2252.     //@@if ( Newdemo_state == ND_STATE_PLAYBACK )
  2253.     //@@    demo_playing = 1;
  2254.     //@@if ( Game_mode & GM_MULTI )
  2255.     //@@    multi_game = 1;
  2256.  
  2257.     set_screen_mode(SCREEN_GAME);
  2258.     reset_palette_add();
  2259.  
  2260.     #ifdef ARCADE
  2261.     keys_override = FindArg("-keys");
  2262.     #endif
  2263.  
  2264.     set_warn_func(game_show_warning);
  2265.  
  2266.     #ifdef VFX
  2267.     if ((FindArg("-vfxmono"))) {
  2268.         Cockpit_mode = CM_FULL_SCREEN;
  2269.         special_halfsize_window=1;
  2270.         vfx_set_palette();
  2271.     }
  2272.     #endif
  2273.  
  2274.     init_game_screen();
  2275.     init_gauges();
  2276.     //digi_init_sounds();
  2277.  
  2278.     //keyd_repeat = 0;                // Don't allow repeat in game
  2279.     keyd_repeat = 1;                // Do allow repeat in game
  2280.  
  2281. //    _MARK_("start of game");//Nuked to compile -KRB
  2282.  
  2283.     #ifdef EDITOR
  2284.         if (Segments[ConsoleObject->segnum].segnum == -1)      //segment no longer exists
  2285.             obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(Cursegp) );
  2286.  
  2287.         if (!check_obj_seg(ConsoleObject))
  2288.             move_player_2_segment(Cursegp,Curside);
  2289.     #endif
  2290.  
  2291.     Viewer = ConsoleObject;
  2292.     fly_init(ConsoleObject);
  2293.  
  2294.     Game_suspended = 0;
  2295.  
  2296.     #ifdef ARCADE
  2297.     if (Arcade_mode)    {
  2298.         NewGame(1);
  2299.         newdemo_start_playback(NULL);
  2300.     }
  2301.     #endif
  2302.  
  2303.     reset_time();
  2304.     FrameTime = 0;            //make first frame zero
  2305.  
  2306.     #ifdef EDITOR
  2307.     if (Current_level_num == 0) {            //not a real level
  2308.         init_player_stats_game();
  2309.         init_ai_objects();
  2310.     }
  2311.     #endif
  2312.  
  2313.     fix_object_segs();
  2314.  
  2315.     game_flush_inputs();
  2316.  
  2317.     if ( setjmp(LeaveGame)==0 )    {
  2318.         while (1) {
  2319.             // GAME LOOP!
  2320.             Automap_flag = 0;
  2321.             Config_menu_flag = 0;
  2322.  
  2323.             GameLoop( 1, 1 );        // Do game loop with rendering and reading controls.
  2324.  
  2325.             if (Config_menu_flag)     {
  2326.                 if (!(Game_mode&GM_MULTI)) palette_save();
  2327.                 do_options_menu();
  2328.                 if (!(Game_mode&GM_MULTI)) palette_restore();        
  2329.             }
  2330.  
  2331.             if (Automap_flag) {
  2332.                 int save_w=Game_window_w,save_h=Game_window_h;
  2333.                 do_automap(0);
  2334.                 Screen_mode=-1; set_screen_mode(SCREEN_GAME);
  2335.                 Game_window_w=save_w; Game_window_h=save_h;
  2336.                 init_game_screen();
  2337.                 last_drawn_cockpit = -1;
  2338.             }
  2339.  
  2340.             if ( (Function_mode != FMODE_GAME) && Auto_demo && (Newdemo_state != ND_STATE_NORMAL) )    {
  2341.                 int choice, fmode;
  2342.                 fmode = Function_mode;
  2343.                 Function_mode = FMODE_GAME;
  2344.                 choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_AUTODEMO );
  2345.                 Function_mode = fmode;
  2346.                 if (choice==0)    {
  2347.                     Auto_demo = 0;    
  2348.                     newdemo_stop_playback();
  2349.                     Function_mode = FMODE_MENU;
  2350.                 } else {
  2351.                     Function_mode = FMODE_GAME;
  2352.                 }
  2353.             }
  2354.     
  2355.             if ( (Function_mode != FMODE_GAME ) && (Newdemo_state != ND_STATE_PLAYBACK ) && (Function_mode!=FMODE_EDITOR) )        {
  2356.                 int choice, fmode;
  2357.                 fmode = Function_mode;
  2358.                 Function_mode = FMODE_GAME;
  2359.                 choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
  2360.                 Function_mode = fmode;
  2361.                 if (choice != 0)
  2362.                     Function_mode = FMODE_GAME;
  2363.             }
  2364.  
  2365.             if (Function_mode != FMODE_GAME)
  2366.                 longjmp(LeaveGame,0);
  2367.         }
  2368.     } 
  2369.  
  2370.     digi_stop_all();
  2371.  
  2372.     if ( (Newdemo_state == ND_STATE_RECORDING) || (Newdemo_state == ND_STATE_PAUSED) )
  2373.         newdemo_stop_recording();
  2374.  
  2375.     multi_leave_game();
  2376.  
  2377.     if ( Newdemo_state == ND_STATE_PLAYBACK )    
  2378.          newdemo_stop_playback();
  2379.  
  2380.     if (Function_mode != FMODE_EDITOR)
  2381.         gr_palette_fade_out(gr_palette,32,0);            // Fade out before going to menu
  2382.  
  2383.     //@@if ( (!demo_playing) && (!multi_game) && (Function_mode != FMODE_EDITOR) )    {
  2384.     //@@    scores_maybe_add_player(Game_aborted);
  2385.     //@@}
  2386.  
  2387. //    _MARK_("end of game");//Nuked to compile -KRB
  2388.  
  2389.     clear_warn_func(game_show_warning);     //don't use this func anymore
  2390.  
  2391. }
  2392.  
  2393. //called at the end of the program
  2394. void close_game() 
  2395. {
  2396.  
  2397.     gr_free_canvas(Canv_game_offscrn);
  2398.  
  2399.     close_gauge_canvases();
  2400.  
  2401.     restore_effect_bitmap_icons();
  2402.  
  2403.     Canv_3d_offscrn = NULL;
  2404.  
  2405.     if (Game_cockpit_copy_code)    {
  2406.         free(Game_cockpit_copy_code);
  2407.         Game_cockpit_copy_code = NULL;
  2408.     }
  2409.  
  2410.     #ifdef VFX
  2411.     if (Canv_vfx[0][0]) free( Canv_vfx[0][0] );
  2412.     if (Canv_vfx[0][1]) free( Canv_vfx[0][1] );
  2413.     if (Canv_vfx[1][0]) free( Canv_vfx[1][0] );
  2414.     if (Canv_vfx[1][1]) free( Canv_vfx[1][1] );
  2415.     #endif
  2416.  
  2417.     #ifdef VICTOR
  2418.     if (Canv_victor[0]) gr_free_canvas(Canv_victor[0]);
  2419.     if (Canv_victor[1]) gr_free_canvas(Canv_victor[1]);
  2420.     #endif
  2421.  
  2422.     if (background_bitmap.bm_data)
  2423.         free(background_bitmap.bm_data);
  2424.  
  2425.     clear_warn_func(game_show_warning);     //don't use this func anymore
  2426. }
  2427.  
  2428. grs_canvas * get_current_game_canvas()
  2429. {
  2430.     switch(Screen_mode)    {
  2431.     case SCREEN_VFX:
  2432.         vfx_set_page(vfx_page);
  2433.         return Canv_vfx[0][vfx_page];
  2434.     default:
  2435.         return Canv_game;
  2436.     }
  2437. }
  2438.  
  2439. ubyte exploding_flag = 0;
  2440.  
  2441. extern dump_used_textures_all();
  2442.  
  2443.  
  2444. void ReadControls()
  2445. {
  2446.     int key;
  2447.     fix key_time;
  2448.     static fix newdemo_single_frame_time;
  2449.  
  2450.         #ifdef ARCADE
  2451.         if (Arcade_mode)    {
  2452.             int coins;
  2453.             if (Newdemo_state!=ND_STATE_PLAYBACK)    {
  2454.                 Arcade_timer -= 2*FrameTime;
  2455.                 if ( Arcade_timer < (-F1_0*10) )    {
  2456.                     newdemo_toggle_playback();
  2457.                 }
  2458.             }
  2459.             coins = coindev_count(0);
  2460.             if (coins>0)    {
  2461.                 if ( Newdemo_state==ND_STATE_PLAYBACK )    {
  2462.                     newdemo_toggle_playback();
  2463.                     Arcade_timer = F1_0 * ARCADE_FIRST_SECONDS;        // Two minutes to play...
  2464.                     if (coins>1)
  2465.                         Arcade_timer += F1_0 * ARCADE_CONTINUE_SECONDS*(coins-1);        // Two minutes to play...
  2466.                     NewGame(1);
  2467.                 } else {
  2468.                     if (Arcade_timer < 0 )
  2469.                         Arcade_timer = 0;
  2470.                     Arcade_timer += F1_0 * ARCADE_CONTINUE_SECONDS*coins;        // Two minutes to play...
  2471.                 }
  2472.             }
  2473.         }
  2474.         #endif
  2475.  
  2476.         Player_fired_laser_this_frame=-1;
  2477.  
  2478. #ifndef NDEBUG
  2479.         if (Speedtest_on)
  2480.             speedtest_frame();
  2481. #endif
  2482.  
  2483.         if (!Endlevel_sequence && !Player_is_dead) {
  2484.  
  2485.             #ifdef ARCADE
  2486.             if (Arcade_mode)    {
  2487.                 if ( Arcade_timer > 0 )
  2488.                     if (Newdemo_state == ND_STATE_PLAYBACK )
  2489.                         memset( &Controls, 0, sizeof(control_info) );
  2490.                     else
  2491.                         controls_read_all();        //NOTE LINK TO ABOVE!!!
  2492.             } else
  2493.             #endiffo) );
  2494.                     else
  2495.                         controls_read_all();        //NOTE LINK TO ABOVE!!!
  2496.             } else
  2497.             #endif
  2498.                 if ( (Newdemo_state == ND_STATE_PLAYBACK) || multi_sending_message || multi_defining_message )
  2499.                     memset( &Controls, 0, sizeof(control_info) );
  2500.                 else
  2501.                     controls_read_all();        //NOTE LINK TO ABOVE!!!
  2502.  
  2503.             check_rear_view();
  2504.                         
  2505.             //    If automap key pressed, enable automap unless you are in network mode, control center destroyed and < 10 seconds left
  2506.             if ( Controls.automap_down_count && !((Game_mode & GM_MULTI) && Fuelcen_control_center_destroyed && (Fuelcen_seconds_left < 10)))
  2507.                 Automap_flag = 1;            
  2508.  
  2509.             if (Controls.fire_flare_down_count)
  2510.                 if (allowed_to_fire_flare())
  2511.                     Flare_create(ConsoleObject);
  2512.  
  2513.             if (allowed_to_fire_missile())
  2514.                 Global_missile_firing_count += Weapon_info[Secondary_weapon_to_weapon_info[Secondary_weapon]].fire_count * (Controls.fire_secondary_state || Controls.fire_secondary_down_count);
  2515.  
  2516.             if (Global_missile_firing_count) {
  2517.                 do_missile_firing();
  2518.                 Global_missile_firing_count--;
  2519.             }
  2520.  
  2521.             if (Global_missile_firing_count < 0)
  2522.                 Global_missile_firing_count = 0;
  2523.  
  2524.             //    Drop proximity bombs.
  2525.             if (Controls.drop_bomb_down_count) {
  2526.                 int    ssw_save = Secondary_weapon;
  2527.                 Secondary_weapon = PROXIMITY_INDEX;
  2528.                 while (Controls.drop_bomb_down_count--)
  2529.                     do_missile_firing();
  2530.                 Secondary_weapon = ssw_save;
  2531.             }
  2532.         }
  2533.  
  2534.         if (Player_exploded) { //Player_is_dead && (ConsoleObject->flags & OF_EXPLODING) ) {
  2535.             if (exploding_flag==0)    {
  2536.                 exploding_flag = 1;             // When player starts exploding, clear all input devices...
  2537.                 game_flush_inputs();
  2538.             } else {    
  2539.                 int i;
  2540.                 if (key_down_count(KEY_BACKSP))
  2541.                     Int3();
  2542.                 if (key_down_count(KEY_PRINT_SCREEN))
  2543.                     save_screen_shot(0);
  2544.                 for (i=0; i<4; i++ )    
  2545.                     if (joy_get_button_down_cnt(i)>0) Death_sequence_aborted = 1;
  2546.                 for (i=0; i<3; i++ )    
  2547.                     if (mouse_button_down_count(i)>0) Death_sequence_aborted = 1;
  2548.                 for (i=0; i<256; i++ )    
  2549.                     if (key_down_count(i)>0) Death_sequence_aborted = 1;
  2550.                 if (Death_sequence_aborted)
  2551.                     game_flush_inputs();
  2552.             }
  2553.         } else {
  2554.             exploding_flag=0;
  2555.         }
  2556.  
  2557.         if (Newdemo_state == ND_STATE_PLAYBACK )    {
  2558.             if ((keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) && keyd_pressed[KEY_RIGHT])
  2559.                 Newdemo_vcr_state = ND_STATE_FASTFORWARD;
  2560.             else if ((keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) && keyd_pressed[KEY_LEFT])
  2561.                 Newdemo_vcr_state = ND_STATE_REWINDING;
  2562.             else if (!(keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) && keyd_pressed[KEY_RIGHT] && ((timer_get_fixed_seconds() - newdemo_single_frame_time) >= F1_0))
  2563.                 Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD;
  2564.             else if (!(keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) && keyd_pressed[KEY_LEFT] && ((timer_get_fixed_seconds() - newdemo_single_frame_time) >= F1_0))
  2565.                 Newdemo_vcr_state = ND_STATE_ONEFRAMEBACKWARD;
  2566.             else if ((Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_REWINDING))
  2567.                 Newdemo_vcr_state = ND_STATE_PLAYBACK;
  2568.         }
  2569.  
  2570.         while ((key=key_inkey_time(&key_time)) != 0)    {
  2571.  
  2572.             if ( (Game_mode&GM_MULTI) && (multi_sending_message || multi_defining_message ))    {
  2573.                 multi_message_input_sub( key );
  2574.                 key = 0;        // Wipe out key!
  2575.             }
  2576.  
  2577.             if (!(Game_mode&GM_MULTI) && key == cheat_enable_keys[cheat_enable_index]) {
  2578.                 if (++cheat_enable_index == CHEAT_ENABLE_LENGTH) {
  2579.                     HUD_init_message(TXT_CHEATS_ENABLED);
  2580.                     digi_play_sample( SOUND_CHEATER, F1_0);
  2581.                     Cheats_enabled = 1;
  2582.                     Players[Player_num].score = 0;
  2583.                 }
  2584.             }
  2585.             else
  2586.                 cheat_enable_index = 0;
  2587.  
  2588.  
  2589. #ifdef FINAL_CHEATS
  2590.         if (Cheats_enabled) {
  2591.             if (!(Game_mode&GM_MULTI) && key == cheat_wowie[cheat_wowie_index]) {
  2592.                 if (++cheat_wowie_index == CHEAT_WOWIE_LENGTH) {
  2593.                         int i;
  2594.  
  2595.                         HUD_init_message(TXT_WOWIE_ZOWIE);
  2596.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2597.  
  2598.                         #ifndef SHAREWARE
  2599.                             Players[Player_num].primary_weapon_flags = 0xff;
  2600.                             Players[Player_num].secondary_weapon_flags = 0xff;
  2601.                         #else
  2602.                             Players[Player_num].primary_weapon_flags = 0xff ^ (HAS_PLASMA_FLAG | HAS_FUSION_FLAG);
  2603.                             Players[Player_num].secondary_weapon_flags = 0xff ^ (HAS_SMART_FLAG | HAS_MEGA_FLAG);
  2604.                         #endif
  2605.  
  2606.                         for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
  2607.                             Players[Player_num].primary_ammo[i] = Primary_ammo_max[i];
  2608.                         
  2609.                         for (i=0; i<MAX_SECONDARY_WEAPONS; i++)
  2610.                             Players[Player_num].secondary_ammo[i] = Secondary_ammo_max[i];
  2611.                         
  2612.                         if (Newdemo_state == ND_STATE_RECORDING)
  2613.                             newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
  2614.  
  2615.                         Players[Player_num].energy = MAX_ENERGY;
  2616.                         Players[Player_num].laser_level = MAX_LASER_LEVEL;
  2617.                         Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
  2618.                         update_laser_weapon_info();
  2619.                 }
  2620.             }
  2621.             else
  2622.                 cheat_wowie_index = 0;
  2623.  
  2624.             if (!(Game_mode&GM_MULTI) && key == cheat_allkeys[cheat_allkeys_index]) {
  2625.                 if (++cheat_allkeys_index == CHEAT_ALLKEYS_LENGTH) {
  2626.                         HUD_init_message(TXT_ALL_KEYS);
  2627.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2628.                         Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  2629.                 }
  2630.             }
  2631.             else
  2632.                 cheat_allkeys_index = 0;
  2633.  
  2634.  
  2635.             if (!(Game_mode&GM_MULTI) && key == cheat_invuln[cheat_invuln_index]) {
  2636.                 if (++cheat_invuln_index == CHEAT_INVULN_LENGTH) {
  2637.                         Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  2638.                         HUD_init_message("%s %s!", TXT_INVULNERABILITY, (Players[Player_num].flags&PLAYER_FLAGS_INVULNERABLE)?TXT_ON:TXT_OFF);
  2639.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2640.                         Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  2641.                 }
  2642.             }
  2643.             else
  2644.                 cheat_invuln_index = 0;
  2645.  
  2646.             if (!(Game_mode&GM_MULTI) && key == cheat_cloak[cheat_cloak_index]) {
  2647.                 if (++cheat_cloak_index == CHEAT_CLOAK_LENGTH) {
  2648.                         Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  2649.                         HUD_init_message("%s %s!", TXT_CLOAK, (Players[Player_num].flags&PLAYER_FLAGS_CLOAKED)?TXT_ON:TXT_OFF);
  2650.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2651.                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  2652.                             ai_do_cloak_stuff();
  2653.                             Players[Player_num].cloak_time = GameTime;
  2654.                         }
  2655.                 }
  2656.             }
  2657.             else
  2658.                 cheat_cloak_index = 0;
  2659.  
  2660.             if (!(Game_mode&GM_MULTI) && key == cheat_shield[cheat_shield_index]) {
  2661.                 if (++cheat_shield_index == CHEAT_SHIELD_LENGTH) {
  2662.                         HUD_init_message(TXT_FULL_SHIELDS);
  2663.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2664.                         Players[Player_num].shields = MAX_SHIELDS;
  2665.                 }
  2666.             }
  2667.             else
  2668.                 cheat_shield_index = 0;
  2669.  
  2670.             if (!(Game_mode&GM_MULTI) && key == cheat_warp[cheat_warp_index]) {
  2671.                 if (++cheat_warp_index == CHEAT_WARP_LENGTH) {
  2672.                         newmenu_item m;
  2673.                         char text[10]="";
  2674.                         int new_level_num;
  2675.                         int item;
  2676.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2677.                         m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
  2678.                         item = newmenu_do( NULL, TXT_WARP_TO_LEVEL, 1, &m, NULL );
  2679.                         if (item != -1) {
  2680.                             new_level_num = atoi(m.text);
  2681.                             if (new_level_num!=0 && new_level_num>=0 && new_level_num<=Last_level)
  2682.                                 StartNewLevel(new_level_num);
  2683.                         }
  2684.                 }
  2685.             }
  2686.             else
  2687.                 cheat_warp_index = 0;
  2688.  
  2689.             if (!(Game_mode&GM_MULTI) && key == cheat_turbomode[cheat_turbomode_index]) {
  2690.                 if (++cheat_turbomode_index == CHEAT_TURBOMODE_LENGTH) {
  2691.                         Game_turbo_mode ^= 1;
  2692.                         HUD_init_message("%s %s!", "Turbo mode", Game_turbo_mode?TXT_ON:TXT_OFF);
  2693.                         digi_play_sample( SOUND_CHEATER, F1_0);
  2694.                 }
  2695.             }
  2696.             else
  2697.                 cheat_turbomode_index = 0;
  2698.  
  2699.  
  2700.         }
  2701. #endif
  2702.  
  2703.             #ifndef RELEASE
  2704.             if ((key&KEY_DEBUGGED)&&(Game_mode&GM_MULTI))    {
  2705.                 Network_message_reciever = 100;        // Send to everyone...
  2706.                 sprintf( Network_message, "%s %s", TXT_I_AM_A, TXT_CHEATER);
  2707.             }
  2708.             #endif
  2709.     
  2710.             if (Endlevel_sequence) {
  2711.  
  2712.                   if (key==KEY_PRINT_SCREEN)
  2713.                     save_screen_shot(0);
  2714.  
  2715.                 if (key == KEY_PAUSE)
  2716.                     key = do_game_pause(0);        //so esc from pause will end level
  2717.  
  2718.                 if (key == KEY_ESC)    {
  2719.                     stop_endlevel_sequence();
  2720.                     last_drawn_cockpit=-1;
  2721.                     return;
  2722.                 }
  2723.  
  2724.                 if (key == KEY_BACKSP)
  2725.                     Int3();
  2726.  
  2727.                 break;        //don't process any other keys
  2728.             }
  2729.  
  2730.             if (Player_is_dead) {
  2731.  
  2732.                   if (key==KEY_PRINT_SCREEN)
  2733.                     save_screen_shot(0);
  2734.  
  2735.                 if (key == KEY_PAUSE)    {
  2736.                     key = do_game_pause(0);        //so esc from pause will end level
  2737.                     Death_sequence_aborted  = 0;        // Clear because code above sets this for any key.
  2738.                 }
  2739.                     
  2740.                 if (key == KEY_ESC) {
  2741.                     if (ConsoleObject->flags & OF_EXPLODING)    
  2742.                         Death_sequence_aborted = 1;
  2743.                 }
  2744.  
  2745.                 if (key == KEY_BACKSP)    {
  2746.                     Death_sequence_aborted  = 0;        // Clear because code above sets this for any key.
  2747.                     Int3();
  2748.                 }
  2749.  
  2750.                 break;        //don't process any other keys
  2751.             }
  2752.  
  2753.             //mprintf( 0, "Key %d pressed at %f\n", key, f2fl(key_time) );
  2754.  
  2755. //            #ifdef VFX
  2756. //            // Toggle VFX between lo and hi res. 1=low, 2=hi
  2757. //            if (key==KEY_F12)    {
  2758. //                if ( Game_vfx_flag == 1 )    {
  2759. //                    Game_vfx_flag = 2;
  2760. //                    init_game_screen();
  2761. //                } else if ( Game_vfx_flag==2 )    {
  2762. //                    Game_vfx_flag = 1;
  2763. //                    init_game_screen();
  2764. //                }
  2765. //                key=0;        // forget this key was pressed
  2766. //            }
  2767. //            #endif
  2768.  
  2769.             #ifdef ARCADE
  2770.             if (Arcade_mode && !keys_override)    {
  2771.                 if (key==KEY_ESC)    {
  2772.                     if (Newdemo_state!=ND_STATE_PLAYBACK)    {
  2773.                         newdemo_toggle_playback();    //turn on demo
  2774.                     } else {
  2775.                         newdemo_toggle_playback();    // turn off demo
  2776.                         // exit to dos
  2777.                         #ifdef EDITOR
  2778.                             if (! SafetyCheck()) break;
  2779.                             if (Screen_mode == SCREEN_EDITOR )
  2780.                                 close_editor_screen();
  2781.                         #endif
  2782.                         Function_mode=FMODE_EXIT;
  2783.                     }
  2784.                 } 
  2785.                 continue;
  2786.             }
  2787.             #endif
  2788.  
  2789.  
  2790.             if (Newdemo_state == ND_STATE_PLAYBACK )    {
  2791.                 switch (key) {
  2792.  
  2793.                 case KEY_DEBUGGED + KEY_I:    
  2794.                     Newdemo_do_interpolate = !Newdemo_do_interpolate;
  2795.                     if (Newdemo_do_interpolate)
  2796.                         mprintf ((0, "demo playback interpolation now on\n"));
  2797.                     else
  2798.                         mprintf ((0, "demo playback interpolation now off\n"));
  2799.                     break;
  2800.                 case KEY_F3:                toggle_cockpit();            break;
  2801.                 case KEY_SHIFTED+KEY_MINUS:
  2802.                 case KEY_MINUS:            shrink_window();            break;
  2803.                 case KEY_SHIFTED+KEY_EQUAL:
  2804.                 case KEY_EQUAL:            grow_window();                break;
  2805.                 case KEY_F2:                Config_menu_flag = 1;    break;
  2806.                 case KEY_F7:                
  2807.                     Show_kill_list = (Show_kill_list+1) % ((Newdemo_game_mode & GM_TEAM) ? 3 : 2);
  2808.                     break;
  2809.                 case KEY_BACKSP:
  2810.                     Int3();
  2811.                     break;
  2812.                 case KEY_ESC:                 
  2813.                     Function_mode = FMODE_MENU;
  2814.                     break;
  2815.                 case KEY_UP:
  2816.                     Newdemo_vcr_state = ND_STATE_PLAYBACK;
  2817.                     break;
  2818.                 case KEY_DOWN:
  2819.                     Newdemo_vcr_state = ND_STATE_PAUSED;
  2820.                     break;
  2821.                 case KEY_LEFT:
  2822.                     newdemo_single_frame_time = timer_get_fixed_seconds();
  2823.                     Newdemo_vcr_state = ND_STATE_ONEFRAMEBACKWARD;
  2824.                     break;
  2825.                 case KEY_RIGHT:
  2826.                     newdemo_single_frame_time = timer_get_fixed_seconds();
  2827.                     Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD;
  2828.                     break;
  2829.                 case KEY_CTRLED + KEY_RIGHT:
  2830.                     newdemo_goto_end();
  2831.                     break;
  2832.                 case KEY_CTRLED + KEY_LEFT:
  2833.                     newdemo_goto_beginning();
  2834.                     break;
  2835.                   case KEY_PRINT_SCREEN: {
  2836.                     int old_state;
  2837.             
  2838.                     old_state = Newdemo_vcr_state;
  2839.                     Newdemo_vcr_state = ND_STATE_PRINTSCREEN;
  2840.                     game_render_frame_mono();
  2841.                      save_screen_shot(0);
  2842.                     Newdemo_vcr_state = old_state;
  2843.                     break;
  2844.                     }
  2845.                 }
  2846.                 break;
  2847.               }
  2848.  
  2849.  
  2850. #ifndef FINAL_CHEATS
  2851.             //Here are the "legal" cheats
  2852.             if (Cheats_enabled && !(Game_mode&GM_MULTI))
  2853.                 switch (key) {
  2854.                     case KEY_ALTED+KEY_1: {
  2855.                         int i;
  2856.  
  2857.                         HUD_init_message(TXT_WOWIE_ZOWIE);
  2858.  
  2859.                         #ifndef SHAREWARE
  2860.                             Players[Player_num].primary_weapon_flags = 0xff;
  2861.                             Players[Player_num].secondary_weapon_flags = 0xff;
  2862.                         #else
  2863.                             Players[Player_num].primary_weapon_flags = 0xff ^ (HAS_PLASMA_FLAG | HAS_FUSION_FLAG);
  2864.                             Players[Player_num].secondary_weapon_flags = 0xff ^ (HAS_SMART_FLAG | HAS_MEGA_FLAG);
  2865.                         #endif
  2866.  
  2867.                         for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
  2868.                             Players[Player_num].primary_ammo[i] = Primary_ammo_max[i];
  2869.                         
  2870.                         for (i=0; i<MAX_SECONDARY_WEAPONS; i++)
  2871.                             Players[Player_num].secondary_ammo[i] = Secondary_ammo_max[i];
  2872.                         
  2873.                         if (Newdemo_state == ND_STATE_RECORDING)
  2874.                             newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
  2875.  
  2876.                         Players[Player_num].energy = MAX_ENERGY;
  2877.                         Players[Player_num].laser_level = MAX_LASER_LEVEL;
  2878.                         Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
  2879.                         update_laser_weapon_info();
  2880.  
  2881.                         break;
  2882.                     }
  2883.     
  2884.                     case KEY_ALTED+KEY_2:
  2885.                         HUD_init_message(TXT_ALL_KEYS);
  2886.                         Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  2887.                         break;
  2888.     
  2889.                     case KEY_ALTED+KEY_3:
  2890.                         Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  2891.                         HUD_init_message("%s %s!", TXT_INVULNERABILITY, (Players[Player_num].flags&PLAYER_FLAGS_INVULNERABLE)?TXT_ON:TXT_OFF);
  2892.                         Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  2893.                         break;
  2894.     
  2895.                     case KEY_ALTED+KEY_4:
  2896.                         Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  2897.                         HUD_init_message("%s %s!", TXT_CLOAK, (Players[Player_num].flags&PLAYER_FLAGS_CLOAKED)?TXT_ON:TXT_OFF);
  2898.                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  2899.                             ai_do_cloak_stuff();
  2900.                             Players[Player_num].cloak_time = GameTime;
  2901.                         }
  2902.                         break;
  2903.  
  2904.                     case KEY_ALTED+KEY_5:
  2905.                         HUD_init_message(TXT_FULL_SHIELDS);
  2906.                         Players[Player_num].shields = MAX_SHIELDS;
  2907.                         break;
  2908.  
  2909.                     case KEY_ALTED+KEY_6: {
  2910.                         newmenu_item m;
  2911.                         char text[10]="";
  2912.                         int new_level_num;
  2913.                         int item;
  2914.                         m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
  2915.                         item = newmenu_do( NULL, TXT_WARP_TO_LEVEL, 1, &m, NULL );
  2916.                         if (item != -1) {
  2917.                             new_level_num = atoi(m.text);
  2918.                             if (new_level_num!=0 && new_level_num>=0 && new_level_num<=LAST_LEVEL)
  2919.                                 StartNewLevel(new_level_num);
  2920.                         }
  2921.                         break;
  2922.  
  2923.                     }
  2924.                 }
  2925. #endif
  2926.  
  2927.             //--killed--Players[Player_num].flags &= ~PLAYER_FLAGS_AFTERBURNER;    //    Turn off, keypress might turn it on.
  2928.  
  2929.             switch (key) {
  2930.  
  2931.                 //    ================================================================================================
  2932.                 //FIRST ARE ALL THE REAL GAME KEYS.  PUT TEST AND DEBUG KEYS LATER.
  2933.  
  2934.                 //--killed--case KEY_SHIFTED+KEY_A:    toggle_afterburner_status();    break;
  2935.                 case KEY_ESC:
  2936.                     Game_aborted=1;                 
  2937.                     Function_mode = FMODE_MENU;
  2938.                     break;
  2939.                 case KEY_F1:                 do_show_help();            break;
  2940.                 case KEY_F2:                Config_menu_flag = 1;    break;
  2941.                 case KEY_F3:                toggle_cockpit();            break;
  2942.                 case KEY_F4:                palette_save(); joydefs_calibrate(); palette_restore(); break;
  2943.                 case KEY_F5:    
  2944.                         if ( Newdemo_state == ND_STATE_RECORDING )
  2945.                             newdemo_stop_recording();
  2946.                         else if ( Newdemo_state == ND_STATE_NORMAL )            
  2947.                             newdemo_start_recording();
  2948.                         break;
  2949.                 case KEY_F6:                
  2950.                     Show_reticle_name = (Show_reticle_name+1)%2;
  2951.                     break;    
  2952.                 case KEY_F7:                
  2953.                     Show_kill_list = (Show_kill_list+1) % ((Game_mode & GM_TEAM) ? 3 : 2);
  2954.                     break;
  2955.                 case KEY_F8:    
  2956.                     multi_send_message_start();
  2957.                     break;
  2958.                 case KEY_F9:
  2959.                 case KEY_F10:
  2960.                 case KEY_F11:
  2961.                 case KEY_F12:
  2962.                     multi_send_macro(key);
  2963.                     break;        // send taunt macros
  2964.     
  2965.                 case KEY_ALTED + KEY_F9:
  2966.                     multi_send_audio_taunt(0);
  2967.                     break;
  2968.                 case KEY_ALTED + KEY_F10:
  2969.                     multi_send_audio_taunt(1);
  2970.                     break;
  2971.                 case KEY_ALTED + KEY_F11:
  2972.                     multi_send_audio_taunt(2);
  2973.                     break;
  2974.                 case KEY_ALTED + KEY_F12:
  2975.                     multi_send_audio_taunt(3);
  2976.                     break;
  2977.  
  2978.                 case KEY_SHIFTED + KEY_F9:
  2979.                 case KEY_SHIFTED + KEY_F10:
  2980.                 case KEY_SHIFTED + KEY_F11:
  2981.                 case KEY_SHIFTED + KEY_F12:
  2982.                     multi_define_macro(key);
  2983.                     break;        // redefine taunt macros
  2984.  
  2985.                 case KEY_PAUSE:            do_game_pause(1);         break;
  2986.                   case KEY_PRINT_SCREEN:     save_screen_shot(0);        break;
  2987.  
  2988.                 case KEY_SHIFTED+KEY_MINUS:
  2989.                 case KEY_MINUS:            shrink_window();            break;
  2990.                 case KEY_SHIFTED+KEY_EQUAL:
  2991.                 case KEY_EQUAL:            grow_window();                break;
  2992.  
  2993.                 //    Select primary or secondary weapon.
  2994.                 case KEY_1:
  2995.                 case KEY_2:
  2996.                 case KEY_3:
  2997.                 case KEY_4:
  2998.                 case KEY_5:
  2999.  
  3000.                     do_weapon_select(key - KEY_1 , 0);
  3001.                     break;
  3002.  
  3003.                 case KEY_6:
  3004.                 case KEY_7:
  3005.                 case KEY_8:
  3006.                 case KEY_9:
  3007.                 case KEY_0:
  3008.  
  3009.                     do_weapon_select(key - KEY_6 , 1);
  3010.                     break;
  3011.  
  3012.                 case KEY_SHIFTED + KEY_ESC:    //quick exit
  3013.                     #ifdef EDITOR
  3014.                         if (! SafetyCheck()) break;
  3015.                         if (Screen_mode == SCREEN_EDITOR )
  3016.                             close_editor_screen();
  3017.                     #endif
  3018.  
  3019.                     Game_aborted=1;
  3020.                     Function_mode=FMODE_EXIT;
  3021.                     break;
  3022.  
  3023. #ifdef SHAREWARE
  3024.                 case KEY_ALTED+KEY_F2:
  3025.                 case KEY_ALTED+KEY_F3:
  3026.                     HUD_init_message( TXT_ONLY_REGISTERED );
  3027.                     digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  3028.                     break;
  3029. #else
  3030.                 case KEY_ALTED+KEY_F2:    state_save_all( 0 );        break;    // 0 means not between levels.
  3031.                 case KEY_ALTED+KEY_F3:    state_restore_all();        break;
  3032. #endif
  3033.  
  3034.                 //use function keys for window sizing
  3035.  
  3036.                 //    ================================================================================================
  3037.                 //ALL KEYS BELOW HERE GO AWAY IN RELEASE VERSION
  3038.  
  3039.             #ifndef RELEASE
  3040.     
  3041.                 case KEY_DEBUGGED+KEY_0:    show_weapon_status();    break;
  3042.  
  3043.                 case KEY_DEBUGGED+KEY_1:    create_special_path();    break;
  3044.  
  3045.                 case KEY_DEBUGGED+KEY_Y:
  3046.                     do_controlcen_destroyed_stuff(NULL);
  3047.                     break;
  3048.  
  3049. #ifndef SHAREWARE
  3050.                 case KEY_SHIFTED+KEY_F1:    multi_dump_robots();     break;
  3051. #endif
  3052.                 case KEY_BACKSP:
  3053.                 case KEY_CTRLED+KEY_BACKSP:
  3054.                 case KEY_ALTED+KEY_BACKSP:
  3055.                 case KEY_SHIFTED+KEY_BACKSP:
  3056.                 case KEY_SHIFTED+KEY_ALTED+KEY_BACKSP:
  3057.                 case KEY_CTRLED+KEY_ALTED+KEY_BACKSP:
  3058.                 case KEY_SHIFTED+KEY_CTRLED+KEY_BACKSP:
  3059.                 case KEY_SHIFTED+KEY_CTRLED+KEY_ALTED+KEY_BACKSP:
  3060.  
  3061.                          Int3(); break;
  3062.  
  3063.                 case KEY_DEBUGGED+KEY_S:            digi_reset(); break;
  3064.  
  3065.                 case KEY_DEBUGGED+KEY_P:
  3066.                      if (Game_suspended & SUSP_ROBOTS)
  3067.                          Game_suspended &= ~SUSP_ROBOTS;         //robots move
  3068.                      else
  3069.                          Game_suspended |= SUSP_ROBOTS;          //robots don't move
  3070.                     break;
  3071.     
  3072. #ifdef VICTOR
  3073.                 case KEY_V + KEY_ALTED:
  3074.                     victor_init_graphics();
  3075.                     break;
  3076.                 case KEY_SHIFTED+KEY_F6:
  3077.                     Victor_eye_switch = !Victor_eye_switch;
  3078.                     break;
  3079. #endif
  3080.     
  3081.     
  3082.                 case KEY_DEBUGGED+KEY_K:    Players[Player_num].shields = 1;    break;                        //    a virtual kill
  3083.                 case KEY_DEBUGGED+KEY_SHIFTED + KEY_K:    Players[Player_num].shields = -1;    break;    //    an actual kill
  3084.                 case KEY_DEBUGGED+KEY_X: Players[Player_num].lives++; break; // Extra life cheat key.
  3085.                 case KEY_DEBUGGED+KEY_H:
  3086. //                    if (!(Game_mode & GM_MULTI) )    {
  3087.                         Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  3088.                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  3089.                             if (Game_mode & GM_MULTI)
  3090.                                 multi_send_cloak();
  3091.                             ai_do_cloak_stuff();
  3092.                             Players[Player_num].cloak_time = GameTime;
  3093.                             mprintf((0, "You are cloaked!\n"));
  3094.                         } else
  3095.                             mprintf((0, "You are DE-cloaked!\n"));
  3096. //                    }
  3097.                     break;
  3098.  
  3099.  
  3100.                 case KEY_DEBUGGED+KEY_R:
  3101.                     Robot_firing_enabled = !Robot_firing_enabled;
  3102.                     break;
  3103.  
  3104.                 #ifdef EDITOR        //editor-specific functions
  3105.  
  3106.                     case KEY_E + KEY_DEBUGGED:
  3107.                             network_leave_game();
  3108.                             Function_mode = FMODE_EDITOR; 
  3109.                             break;
  3110.     
  3111.                     case KEY_C + KEY_SHIFTED + KEY_DEBUGGED: 
  3112.                         if (!( Game_mode & GM_MULTI ))
  3113.                             move_player_2_segment(Cursegp,Curside); 
  3114.                         break;   //move eye to curseg
  3115.     
  3116.                     case KEY_S + KEY_SHIFTED + KEY_DEBUGGED:    //toggle screen (between editor & game screens)
  3117.                         if (Screen_mode == SCREEN_EDITOR )      
  3118.                             close_editor_screen();
  3119.                         set_screen_mode(Screen_mode ^ (SCREEN_GAME^SCREEN_EDITOR));
  3120.                         break;
  3121.     
  3122.                     case KEY_DEBUGGED+KEY_W:    draw_world_from_game();    break;
  3123.  
  3124.                 #endif    //#ifdef EDITOR
  3125.     
  3126.                 //flythrough keys
  3127.                 // case KEY_DEBUGGED+KEY_SHIFTED+KEY_F:    toggle_flythrough(); break;
  3128.                 // case KEY_LEFT:          ft_preference=FP_LEFT; break;
  3129.                 // case KEY_RIGHT:             ft_preference=FP_RIGHT; break;
  3130.                 // case KEY_UP:            ft_preference=FP_UP; break;
  3131.                 // case KEY_DOWN:          ft_preference=FP_DOWN; break;
  3132.     
  3133.                 case KEY_DEBUGGED+KEY_LAPOSTRO: Show_view_text_timer = 0x30000; object_goto_next_viewer(); break;
  3134.                 case KEY_DEBUGGED+KEY_SHIFTED+KEY_LAPOSTRO: Viewer=ConsoleObject; break;
  3135.     
  3136. #ifndef NDEBUG
  3137.                   case KEY_DEBUGGED+KEY_O: toggle_outline_mode(); break;
  3138. #endif
  3139.                   case KEY_DEBUGGED+KEY_T:
  3140.                     *Toggle_var = !*Toggle_var;
  3141.                     mprintf((0, "Variable at %08x set to %i\n", Toggle_var, *Toggle_var));
  3142.                     break;
  3143.                   case KEY_DEBUGGED + KEY_L: 
  3144.                     if (++Lighting_on >= 2) Lighting_on = 0; break;
  3145.                   case KEY_DEBUGGED + KEY_SHIFTED + KEY_L: 
  3146.                     Beam_brightness=0x38000-Beam_brightness; break;
  3147.                   case KEY_PAD5: slew_stop(); break;
  3148.     
  3149.                   case KEY_DEBUGGED + KEY_F11: play_test_sound(); break;
  3150.                   case KEY_DEBUGGED + KEY_SHIFTED+KEY_F11: advance_sound(); play_test_sound(); break;
  3151.  
  3152.                 case KEY_DEBUGGED +KEY_F4: {
  3153.                     //fvi_info hit_data;
  3154.                     //vms_vector p0 = {-0x1d99a7,-0x1b20000,0x186ab7f};
  3155.                     //vms_vector p1 = {-0x217865,-0x1b20000,0x187de3e};
  3156.                     //find_vector_intersection(&hit_data,&p0,0x1b9,&p1,0x40000,0x0,NULL,-1);
  3157.                     break;
  3158.                 }
  3159.     
  3160.                 case KEY_DEBUGGED + KEY_M:
  3161.                     Debug_spew = !Debug_spew;
  3162.                     if (Debug_spew) {
  3163.                         mopen( 0, 8, 1, 78, 16, "Debug Spew");
  3164.                         HUD_init_message( "Debug Spew: ON" );
  3165.                     } else {
  3166.                         mclose( 0 );
  3167.                         HUD_init_message( "Debug Spew: OFF" );
  3168.                     }
  3169.                     break;        
  3170.     
  3171.                 case KEY_DEBUGGED + KEY_C:    
  3172.  
  3173.                         do_cheat_menu(); 
  3174.                         break;
  3175.                 case KEY_DEBUGGED + KEY_A:    {
  3176.                         do_megawow_powerup();
  3177. //                        if ( Game_mode & GM_MULTI )    {
  3178. //                            nm_messagebox( NULL, 1, "Damn", "CHEATER!\nYou cannot use the\nmega-thing in network mode." );
  3179. //                            Network_message_reciever = 100;        // Send to everyone...
  3180. //                            sprintf( Network_message, "%s cheated!", Players[Player_num].callsign);
  3181. //                        } else {
  3182. //                            do_megawow_powerup();
  3183. //                        }
  3184.                         break;
  3185.                 }
  3186.     
  3187.                  case KEY_DEBUGGED+KEY_F:    framerate_on = !framerate_on; break;
  3188.      
  3189.                  case KEY_DEBUGGED+KEY_SPACEBAR:              //KEY_F7:                       // Toggle physics flying
  3190.                      slew_stop();
  3191.                     game_flush_inputs();
  3192.                      if ( ConsoleObject->control_type != CT_FLYING ) {
  3193.                          fly_init(ConsoleObject);
  3194.                          Game_suspended &= ~SUSP_ROBOTS;         //robots move
  3195.                      } else {
  3196.                          slew_init(ConsoleObject);                                              //start player slewing
  3197.                          Game_suspended |= SUSP_ROBOTS;          //robots don't move
  3198.                     }
  3199.                     break;
  3200.         
  3201.                 case KEY_DEBUGGED+KEY_COMMA: Render_zoom = fixmul(Render_zoom,62259); break;
  3202.                 case KEY_DEBUGGED+KEY_PERIOD: Render_zoom = fixmul(Render_zoom,68985); break;
  3203.     
  3204.                 case KEY_DEBUGGED+KEY_P+KEY_SHIFTED: Debug_pause = 1; break;
  3205.     
  3206.                 //case KEY_F7: {
  3207.                 //    char mystr[30];
  3208.                 //    sprintf(mystr,"mark %i start",Mark_count);
  3209.                 //    _MARK_(mystr);
  3210.                 //    break;
  3211.                 //}
  3212.                 //case KEY_SHIFTED+KEY_F7: {
  3213.                 //    char mystr[30];
  3214.                 //    sprintf(mystr,"mark %i end",Mark_count);
  3215.                 //    Mark_count++;
  3216.                 //    _MARK_(mystr);
  3217.                 //    break;
  3218.                 //}
  3219.     
  3220.         
  3221. #ifndef NDEBUG
  3222.                 case KEY_DEBUGGED+KEY_F8: speedtest_init(); Speedtest_count = 1;    break;
  3223.                 case KEY_DEBUGGED+KEY_F9: speedtest_init(); Speedtest_count = 10;    break;
  3224.  
  3225.                 case KEY_DEBUGGED+KEY_D:
  3226.                     if ((Game_double_buffer = !Game_double_buffer)!=0)
  3227.                         init_game_screen();
  3228.                     break;
  3229. #endif
  3230.  
  3231. #ifdef EDITOR
  3232.                 case KEY_DEBUGGED+KEY_Q:
  3233.                     stop_time();
  3234.                     dump_used_textures_all();
  3235.                     start_time();
  3236.                     break;
  3237. #endif
  3238.  
  3239.                 #endif        //#ifndef RELEASE
  3240.  
  3241.                 default:        break;
  3242.  
  3243.             }       //switch (key)
  3244.         }
  3245.  
  3246.  
  3247.  
  3248.  
  3249. }
  3250.  
  3251. #ifndef    NDEBUG
  3252. int    Debug_slowdown=0;
  3253. #endif
  3254.  
  3255. #ifdef EDITOR
  3256. extern void player_follow_path(object *objp);
  3257. extern void check_create_player_path(void);
  3258.  
  3259. #endif
  3260.  
  3261. extern    int    Do_appearance_effect;
  3262.  
  3263. void GameLoop(int RenderFlag, int ReadControlsFlag )
  3264. {
  3265.     static int desc_dead_countdown=100;   /*  used if player shouldn't be playing */
  3266.  
  3267. #ifndef    NDEBUG
  3268.     //    Used to slow down frame rate for testing things.
  3269. //    RenderFlag = 1; // DEBUG
  3270.     if (Debug_slowdown) {
  3271.         int    h, i, j=0;
  3272.  
  3273.         for (h=0; h<Debug_slowdown; h++)
  3274.             for (i=0; i<1000; i++)
  3275.                 j += i;
  3276.     }
  3277. #endif
  3278.  
  3279.         if (desc_id_exit_num) {                 // are we supposed to be checking
  3280.             if (!(--desc_dead_countdown))  // if so, at zero, then pull the plug
  3281.                 Error ("Loading overlay -- error number: %d\n", (int)desc_id_exit_num);
  3282.         }
  3283.                 
  3284.         #ifndef RELEASE
  3285.         if (FindArg("-invulnerability"))
  3286.             Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
  3287.         #endif
  3288.  
  3289.         update_player_stats();
  3290.         diminish_palette_towards_normal();        //    Should leave palette effect up for as long as possible by putting right before render.
  3291.         //--killed--do_afterburner_stuff();
  3292.         do_cloak_stuff();
  3293.         do_invulnerable_stuff();
  3294.         remove_obsolete_stuck_objects();
  3295. #ifdef EDITOR
  3296. check_create_player_path();
  3297. player_follow_path(ConsoleObject);
  3298. #endif
  3299.         if (Game_mode & GM_MULTI)
  3300.             multi_do_frame();
  3301.     
  3302.         if (RenderFlag) {
  3303.             if (force_cockpit_redraw) {            //screen need redrawing?
  3304.                 init_game_screen();
  3305.                 force_cockpit_redraw=0;
  3306.             }
  3307.             game_render_frame();
  3308.         }
  3309.  
  3310. //        mprintf(0,"Velocity %2.2f\n", f2fl(vm_vec_mag(&ConsoleObject->phys_info.velocity)));
  3311.  
  3312.         calc_frame_time();
  3313.  
  3314.         dead_player_frame();
  3315.         if (Newdemo_state != ND_STATE_PLAYBACK)
  3316.             do_controlcen_dead_frame();
  3317.  
  3318.         if (ReadControlsFlag)
  3319.             ReadControls();
  3320.         else
  3321.             memset(&Controls, 0, sizeof(Controls));
  3322.  
  3323.         GameTime += FrameTime;
  3324.  
  3325.         digi_sync_sounds();
  3326.  
  3327.         if (Endlevel_sequence) {
  3328.             do_endlevel_frame();
  3329.             powerup_grab_cheat_all();
  3330.             do_special_effects();
  3331.             return;                    //skip everything else
  3332.         }
  3333.  
  3334.         #ifdef ARCADE
  3335.         if (Arcade_mode && (Arcade_timer<0) && (Newdemo_state != ND_STATE_PLAYBACK) )    {
  3336.             memset( &Controls, 0, sizeof(Controls) );
  3337.             continue;
  3338.         }
  3339.         #endif
  3340.  
  3341.         if (Newdemo_state != ND_STATE_PLAYBACK)
  3342.             do_exploding_wall_frame();
  3343.         if ((Newdemo_state != ND_STATE_PLAYBACK) || (Newdemo_vcr_state != ND_STATE_PAUSED)) {
  3344.             do_special_effects();
  3345.             wall_frame_process();
  3346.             triggers_frame_process();
  3347.         }
  3348.  
  3349.  
  3350.         if (Fuelcen_control_center_destroyed)    {
  3351.             if (Newdemo_state==ND_STATE_RECORDING )
  3352.                 newdemo_record_control_center_destroyed();
  3353.             flash_frame();
  3354.         }
  3355.         
  3356.         if ( Newdemo_state == ND_STATE_PLAYBACK )    {
  3357.             newdemo_playback_one_frame();
  3358.             if ( Newdemo_state != ND_STATE_PLAYBACK )        {
  3359. //                  gr_palette_fade_out( gr_palette, 32, 0 );
  3360. //                show_title_screen( "descent.pcx", 1 );
  3361. //                Screen_mode=-1; set_screen_mode(SCREEN_GAME);
  3362. //                clear_palette();
  3363. //                init_game_screen();
  3364. //                last_cockpit_drawn = -1;
  3365. //                #ifdef ARCADE
  3366. //                if ( Arcade_timer > 0 ) {
  3367. //                    NewGame(1);
  3368. //                } else
  3369. //                #endif
  3370. //                    newdemo_toggle_playback();            //NOTE LINK TO ABOVE!
  3371.                 longjmp( LeaveGame, 0 );        // Go back to menu
  3372.             }
  3373.         } else    
  3374.         { // Note the link to above!
  3375.  
  3376.             Players[Player_num].homing_object_dist = -1;        //    Assume not being tracked.  Laser_do_weapon_sequence modifies this.
  3377.  
  3378.             object_move_all();    
  3379.             powerup_grab_cheat_all();
  3380.  
  3381.             if (Endlevel_sequence)    //might have been started during move
  3382.                 return;
  3383.  
  3384.             fuelcen_update_all();
  3385.  
  3386.             do_ai_frame_all();
  3387.  
  3388.             if (allowed_to_fire_laser()) {
  3389.                 Global_laser_firing_count += Weapon_info[Primary_weapon_to_weapon_info[Primary_weapon]].fire_count * (Controls.fire_primary_state || Controls.fire_primary_down_count);
  3390.                 if ((Primary_weapon == FUSION_INDEX) && (Global_laser_firing_count)) {
  3391.                     if ((Players[Player_num].energy < F1_0*5) && (Auto_fire_fusion_cannon_time == 0)) {
  3392.                         Global_laser_firing_count = 0;
  3393.                     } else {
  3394.                         if (Fusion_charge == 0)
  3395.                             Players[Player_num].energy -= F1_0*5;
  3396.  
  3397.                         Fusion_charge += FrameTime;
  3398.                         Players[Player_num].energy -= FrameTime*4;
  3399.  
  3400.                         if (Players[Player_num].energy <= 0) {
  3401.                             Players[Player_num].energy = 0;
  3402.                             Auto_fire_fusion_cannon_time = GameTime -1;                //    Fire now!
  3403.                         } else
  3404.                             Auto_fire_fusion_cannon_time = GameTime + FrameTime/2 + 1;        //    Fire the fusion cannon at this time in the future.
  3405.  
  3406.                         if (Fusion_charge < F1_0*2)
  3407.                             PALETTE_FLASH_ADD(Fusion_charge >> 11, 0, Fusion_charge >> 11);
  3408.                         else
  3409.                             PALETTE_FLASH_ADD(Fusion_charge >> 11, Fusion_charge >> 11, 0);
  3410.  
  3411.                         if (Fusion_next_sound_time < GameTime) {
  3412.                             if (Fusion_charge > F1_0*2) {
  3413.                                 digi_play_sample( 11, F1_0 );
  3414.                                 apply_damage_to_player(ConsoleObject, ConsoleObject, rand() * 4);
  3415.                             } else {
  3416.                                 digi_play_sample( SOUND_FUSION_WARMUP, F1_0 );
  3417.                                 if (Game_mode & GM_MULTI)
  3418.                                     multi_send_play_sound(SOUND_FUSION_WARMUP, F1_0);
  3419.                             }
  3420.                             Fusion_next_sound_time = GameTime + F1_0/8 + rand()/4;
  3421.                         }
  3422.                     }
  3423.                 }
  3424.             }
  3425.  
  3426.             if (Auto_fire_fusion_cannon_time) {
  3427.                 if (Primary_weapon != FUSION_INDEX)
  3428.                     Auto_fire_fusion_cannon_time = 0;
  3429.                 else if (GameTime + FrameTime/2 >= Auto_fire_fusion_cannon_time) {
  3430.                     Auto_fire_fusion_cannon_time = 0;
  3431.                     Global_laser_firing_count = 1;
  3432.                 } else {
  3433.                     vms_vector    rand_vec;
  3434.                     fix            bump_amount;
  3435.  
  3436.                     Global_laser_firing_count = 0;
  3437.  
  3438.                     ConsoleObject->phys_info.rotvel.x += (rand() - 16384)/8;
  3439.                     ConsoleObject->phys_info.rotvel.z += (rand() - 16384)/8;
  3440.                     make_random_vector(&rand_vec);
  3441.  
  3442.                     bump_amount = F1_0*4;
  3443.  
  3444.                     if (Fusion_charge > F1_0*2)
  3445.                         bump_amount = Fusion_charge*4;
  3446.  
  3447.                     bump_one_object(ConsoleObject, &rand_vec, bump_amount);
  3448.                 }
  3449.             }
  3450.  
  3451.             if (Global_laser_firing_count) {
  3452.                 if (Fusion_charge > F1_0*2)
  3453.                     Fusion_charge = F1_0*2;
  3454.                 Global_laser_firing_count -= do_laser_firing_player();    //do_laser_firing(Players[Player_num].objnum, Primary_weapon);
  3455.             }
  3456.  
  3457.             if (Global_laser_firing_count < 0)
  3458.                 Global_laser_firing_count = 0;
  3459.         }
  3460.  
  3461.     if (Do_appearance_effect) {
  3462.         create_player_appearance_effect(ConsoleObject);
  3463.         Do_appearance_effect = 0;
  3464.     }
  3465.  
  3466. }
  3467.  
  3468. //    -------------------------------------------------------------------------------------------------------
  3469. //    If player is close enough to objnum, which ought to be a powerup, pick it up!
  3470. //    This could easily be made difficulty level dependent.
  3471. void powerup_grab_cheat(object *player, int objnum)
  3472. {
  3473.     fix    powerup_size;
  3474.     fix    player_size;
  3475.     fix    dist;
  3476.  
  3477.     Assert(Objects[objnum].type == OBJ_POWERUP);
  3478.  
  3479.     powerup_size = Objects[objnum].size;
  3480.     player_size = player->size;
  3481.  
  3482.     dist = vm_vec_dist_quick(&Objects[objnum].pos, &player->pos);
  3483.  
  3484.     if ((dist < 2*(powerup_size + player_size)) && !(Objects[objnum].flags & OF_SHOULD_BE_DEAD)) {
  3485.         vms_vector    collision_point;
  3486.  
  3487.         vm_vec_avg(&collision_point, &Objects[objnum].pos, &player->pos);
  3488.         collide_player_and_powerup(player, &Objects[objnum], &collision_point);
  3489.     }
  3490. }
  3491.  
  3492. //    -------------------------------------------------------------------------------------------------------
  3493. //    Make it easier to pick up powerups.
  3494. //    For all powerups in this segment, pick them up at up to twice pickuppable distance based on dot product
  3495. //    from player to powerup and player's forward vector.
  3496. //    This has the effect of picking them up more easily left/right and up/down, but not making them disappear
  3497. //    way before the player gets there.
  3498. void powerup_grab_cheat_all(void)
  3499. {
  3500.     segment    *segp;
  3501.     int        objnum;
  3502.  
  3503.     segp = &Segments[ConsoleObject->segnum];
  3504.     objnum = segp->objects;
  3505.  
  3506.     while (
  3507. 
  3508.