home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / game.c < prev    next >
Text File  |  1998-06-08  |  131KB  |  4,391 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/game.c $
  15.  * $Revision: 2.36 $
  16.  * $Author: john $
  17.  * $Date: 1996/01/05 16:52:05 $
  18.  *
  19.  * Game loop for Inferno
  20.  *
  21.  * $Log: game.c $
  22.  * Revision 2.36  1996/01/05  16:52:05  john
  23.  * Improved 3d stuff.
  24.  * 
  25.  * Revision 2.35  1995/10/09  22:17:10  john
  26.  * Took out the page flipping in set_screen_mode, which shouldn't
  27.  * be there.  This was hosing the modex stuff.
  28.  * 
  29.  * Revision 2.34  1995/10/09  19:46:34  john
  30.  * Fixed bug with modex paging with lcdbios.
  31.  * 
  32.  * Revision 2.33  1995/10/08  11:46:09  john
  33.  * Fixed bug with 2d offset in interlaced mode in low res.
  34.  * Made LCDBIOS with pageflipping using VESA set start
  35.  * Address function.  X=CRTC offset, Y=0.
  36.  * 
  37.  * Revision 2.32  1995/10/07  13:20:51  john
  38.  * Added new modes for LCDBIOS, also added support for -JoyNice,
  39.  * and added Shift+F1-F4 to controls various stereoscopic params.
  40.  * 
  41.  * Revision 2.31  1995/05/31  14:34:43  unknown
  42.  * fixed warnings.
  43.  * 
  44.  * Revision 2.30  1995/05/08  11:23:45  john
  45.  * Made 3dmax work like Kasan wants it to.
  46.  * 
  47.  * Revision 2.29  1995/04/06  13:47:39  yuan
  48.  * Restored rear view to original.
  49.  * 
  50.  * Revision 2.28  1995/04/06  12:13:07  john
  51.  * Fixed some bugs with 3dmax.
  52.  * 
  53.  * Revision 2.27  1995/04/05  13:18:18  mike
  54.  * decrease energy usage on fusion cannon
  55.  * 
  56.  * Revision 2.26  1995/03/30  16:36:32  mike
  57.  * text localization.
  58.  * 
  59.  * Revision 2.25  1995/03/27  16:45:26  john
  60.  * Fixed some cheat bugs.  Added astral cheat.
  61.  * 
  62.  * Revision 2.24  1995/03/27  15:37:11  mike
  63.  * boost fusion cannon for non-multiplayer modes.
  64.  * 
  65.  * Revision 2.23  1995/03/24  17:48:04  john
  66.  * Fixed bug with menus and 320x100.
  67.  * 
  68.  * Revision 2.22  1995/03/24  15:34:02  mike
  69.  * cheats.
  70.  * 
  71.  * Revision 2.21  1995/03/24  13:11:39  john
  72.  * Added save game during briefing screens.
  73.  * 
  74.  * Revision 2.20  1995/03/21  14:40:50  john
  75.  * Ifdef'd out the NETWORK code.
  76.  * 
  77.  * Revision 2.19  1995/03/16  22:07:16  john
  78.  * Made so only for screen can be used for anything other
  79.  * than mode 13.
  80.  * 
  81.  * Revision 2.18  1995/03/16  21:45:35  john
  82.  * Made all paged modes have incompatible menus!
  83.  * 
  84.  * Revision 2.17  1995/03/16  18:30:35  john
  85.  * Made wider than 320 screens not have
  86.  * a status bar mode.
  87.  * 
  88.  * Revision 2.16  1995/03/16  10:53:34  john
  89.  * Move VFX center to Shift+Z instead of Enter because
  90.  * it conflicted with toggling HUD on/off.
  91.  * 
  92.  * Revision 2.15  1995/03/16  10:18:33  john
  93.  * Fixed bug with VFX mode not working. also made warning
  94.  * when it can't set VESA mode.
  95.  * 
  96.  * Revision 2.14  1995/03/14  16:22:39  john
  97.  * Added cdrom alternate directory stuff.
  98.  * 
  99.  * Revision 2.13  1995/03/14  12:14:17  john
  100.  * Made VR helmets have 4 resolutions to choose from.
  101.  * 
  102.  * Revision 2.12  1995/03/10  13:47:33  john
  103.  * Added head tracking sensitivity.
  104.  * 
  105.  * Revision 2.11  1995/03/10  13:13:47  john
  106.  * Added code to show T-xx on iglasses.
  107.  * 
  108.  * Revision 2.10  1995/03/09  18:07:29  john
  109.  * Fixed bug with iglasses tracking not "centering" right.
  110.  * Made VFX have bright headlight lighting.
  111.  * 
  112.  * Revision 2.9  1995/03/09  11:48:02  john
  113.  * Added HUD for VR helmets.
  114.  * 
  115.  * Revision 2.8  1995/03/07  15:12:53  john
  116.  * Fixed VFX,3dmax support.
  117.  * 
  118.  * Revision 2.7  1995/03/07  11:35:03  john
  119.  * Fixed bug with cockpit in rear view.
  120.  * 
  121.  * Revision 2.6  1995/03/06  18:40:17  john
  122.  * Added some ifdef EDITOR stuff.
  123.  * 
  124.  * Revision 2.5  1995/03/06  18:31:21  john
  125.  * Fixed bug with nmenu popping up on editor screen.
  126.  * 
  127.  * Revision 2.4  1995/03/06  17:28:33  john
  128.  * Fixed but with cockpit toggling wrong.
  129.  * 
  130.  * Revision 2.3  1995/03/06  16:08:10  mike
  131.  * Fix compile errors if building without editor.
  132.  * 
  133.  * Revision 2.2  1995/03/06  15:24:10  john
  134.  * New screen techniques.
  135.  * 
  136.  * Revision 2.1  1995/02/27  13:41:03  john
  137.  * Removed floating point from frame rate calculations.
  138.  * 
  139.  * Revision 2.0  1995/02/27  11:31:54  john
  140.  * New version 2.0, which has no anonymous unions, builds with
  141.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  142.  * 
  143.  * Revision 1.770  1995/02/22  12:45:15  allender
  144.  * remove anonymous unions from object structure
  145.  * 
  146.  * Revision 1.769  1995/02/15  10:06:25  allender
  147.  * make pause pause game during demo playback
  148.  * 
  149.  * Revision 1.768  1995/02/13  20:35:11  john
  150.  * Lintized
  151.  * 
  152.  * Revision 1.767  1995/02/13  19:40:29  allender
  153.  * added place to demo record restoration from rear view in place that
  154.  * I forgot before
  155.  * 
  156.  * Revision 1.766  1995/02/13  10:29:27  john
  157.  * Fixed bug with cheats not restoreing across save games.
  158.  * 
  159.  * Revision 1.765  1995/02/11  22:54:33  john
  160.  * Made loading for pig not show up for demos.
  161.  * 
  162.  * Revision 1.764  1995/02/11  17:30:08  allender
  163.  * ifndef NDEBUG around strip frame stuff
  164.  * 
  165.  * Revision 1.763  1995/02/11  17:13:01  rob
  166.  * Took out modem.c code fille stuff.
  167.  * 
  168.  * Revision 1.762  1995/02/11  16:36:47  allender
  169.  * debug key to strip frames from end of demo
  170.  * 
  171.  * Revision 1.761  1995/02/11  14:29:16  john
  172.  * Turned off cheats when going into game.
  173.  * 
  174.  * Revision 1.760  1995/02/11  13:46:54  mike
  175.  * fix cheats.
  176.  * 
  177.  * Revision 1.759  1995/02/11  12:36:09  matt
  178.  * Cleaned up cheats
  179.  * 
  180.  * Revision 1.758  1995/02/11  12:27:04  mike
  181.  * fix path-to-exit cheat.
  182.  * 
  183.  * Revision 1.757  1995/02/11  01:56:24  mike
  184.  * robots don't fire cheat.
  185.  * 
  186.  * Revision 1.756  1995/02/10  16:38:40  mike
  187.  * illuminate path to exit cheat.
  188.  * 
  189.  * Revision 1.755  1995/02/10  16:19:40  mike
  190.  * new show-path-to-exit system, still buggy, compiled out.
  191.  * 
  192.  * Revision 1.754  1995/02/10  15:54:46  matt
  193.  * Added new cheats
  194.  * 
  195.  * Revision 1.753  1995/02/09  12:25:42  matt
  196.  * Made mem_fill() test routines not be called if RELEASE
  197.  * 
  198.  * Revision 1.752  1995/02/09  08:49:32  mike
  199.  * change fill opcode value to 0xcc, int 3 value.
  200.  * 
  201.  * 
  202.  * Revision 1.751  1995/02/09  02:59:26  mike
  203.  * check code for 00066xxx bugs.
  204.  * 
  205.  * Revision 1.750  1995/02/08  17:10:02  mike
  206.  * add, but don't call, debug code.
  207.  * 
  208.  * Revision 1.749  1995/02/07  11:07:27  john
  209.  * Added hooks for confirm on game state restore.
  210.  * 
  211.  * Revision 1.748  1995/02/06  15:52:45  mike
  212.  * add mini megawow powerup for giving reasonable weapons.
  213.  * 
  214.  * Revision 1.747  1995/02/06  12:53:35  allender
  215.  * force endlevel_sequence to 0 to fix weird bug
  216.  * 
  217.  * Revision 1.746  1995/02/04  10:03:30  mike
  218.  * Fly to exit cheat.
  219.  * 
  220.  * Revision 1.745  1995/02/02  15:57:52  john
  221.  * Added turbo mode cheat.
  222.  * 
  223.  * Revision 1.744  1995/02/02  14:43:39  john
  224.  * Uppped frametime limit to 150 Hz.
  225.  * 
  226.  * Revision 1.743  1995/02/02  13:37:16  mike
  227.  * move T-?? message down in certain modes.
  228.  * 
  229.  * Revision 1.742  1995/02/02  01:26:59  john
  230.  * Took out no key repeating.
  231.  * 
  232.  * Revision 1.741  1995/01/29  21:36:44  mike
  233.  * make fusion cannon not make pitching slow.
  234.  * 
  235.  * Revision 1.740  1995/01/28  15:57:57  john
  236.  * Made joystick calibration be only when wrong detected in
  237.  * menu or joystick axis changed.
  238.  * 
  239.  * Revision 1.739  1995/01/28  15:21:03  yuan
  240.  * Added X-tra life cheat.
  241.  * 
  242.  * Revision 1.738  1995/01/27  14:08:31  rob
  243.  * Fixed a bug.
  244.  * 
  245.  * Revision 1.737  1995/01/27  14:04:59  rob
  246.  * Its not my fault, Mark told me to do it!
  247.  * 
  248.  * Revision 1.736  1995/01/27  13:12:18  rob
  249.  * Added charging noises to play across net.
  250.  * 
  251.  * Revision 1.735  1995/01/27  11:48:28  allender
  252.  * check for newdemo_state to be paused and stop recording.  We might be
  253.  * in between levels
  254.  * 
  255.  * Revision 1.734  1995/01/26  22:11:41  mike
  256.  * Purple chromo-blaster (ie, fusion cannon) spruce up (chromification)
  257.  * 
  258.  * Revision 1.733  1995/01/26  17:03:04  mike
  259.  * make fusion cannon have more chrome, make fusion, mega rock you!
  260.  * 
  261.  * Revision 1.732  1995/01/25  14:37:25  john
  262.  * Made joystick only prompt for calibration once...
  263.  * 
  264.  * Revision 1.731  1995/01/24  15:49:14  john
  265.  * Made typeing in long net messages wrap on 
  266.  * small screen sizes.
  267.  * 
  268.  * Revision 1.730  1995/01/24  15:23:42  mike
  269.  * network message tweaking.
  270.  * 
  271.  * Revision 1.729  1995/01/24  12:00:47  john
  272.  * Fixed bug with defing macro passing keys to controls.
  273.  * 
  274.  * Revision 1.728  1995/01/24  11:53:35  john
  275.  * Added better macro defining code.
  276.  * 
  277.  * Revision 1.727  1995/01/23  22:17:15  john
  278.  * Fixed bug with not clearing key buffer when leaving f8.
  279.  * 
  280.  * Revision 1.726  1995/01/23  22:07:09  john
  281.  * Added flush to game inputs during F8.
  282.  *
  283.  */
  284.  
  285. #pragma off (unreferenced)
  286. static char rcsid[] = "$Id: game.c 2.36 1996/01/05 16:52:05 john Exp $";
  287. #pragma on (unreferenced)
  288.  
  289. #include <stdio.h>
  290. #include <malloc.h>
  291. #include <stdlib.h>
  292. #include <string.h>
  293. #include <conio.h>
  294. #include <stdarg.h>
  295. #include <dos.h>
  296.  
  297. #include "inferno.h"
  298. #include "game.h"
  299. #include "key.h"
  300. #include "object.h"
  301. #include "physics.h"
  302. #include "error.h"
  303. #include "joy.h"
  304. #include "mono.h"
  305. #include "iff.h"
  306. #include "pcx.h"
  307. #include "timer.h"
  308. #include "render.h"
  309. #include "laser.h"
  310. #include "screens.h"
  311. #include "textures.h"
  312. #include "slew.h"
  313. #include "gauges.h"
  314. #include "texmap.h"
  315. #include "3d.h"
  316. #include "effects.h"
  317. #include "effect2d.h"
  318. #include "menu.h"
  319. #include "gameseg.h"
  320. #include "wall.h"
  321. #include "ai.h"
  322. #include "hostage.h"
  323. #include "fuelcen.h"
  324. #include "switch.h"
  325. #include "digi.h"
  326. #include "gamesave.h"
  327. #include "scores.h"
  328. #include "ibitblt.h"
  329. #include "mem.h"
  330. #include "palette.h"
  331. #include "morph.h"
  332. #include "lighting.h"
  333. #include "newdemo.h"
  334. #include "titles.h"
  335. #include "collide.h"
  336. #include "weapon.h"
  337. #include "sounds.h"
  338. #include "args.h"
  339. #include "gameseq.h"
  340. #include "automap.h"
  341. #include "text.h"
  342. #include "powerup.h"
  343. #include "fireball.h"
  344. #include "controls.h"
  345. #include "newmenu.h"
  346. #include "network.h"
  347. #include "gamefont.h"
  348. #include "endlevel.h"
  349. #include "joydefs.h"
  350. #include "kconfig.h"
  351. #include "mouse.h"
  352. #include "coindev.h"
  353. #include "multi.h"
  354. #include "desc_id.h"
  355. #include "cntrlcen.h"
  356. #include "pcx.h"
  357. #include "dpmi.h"
  358. #include "state.h"
  359. #include "piggy.h"
  360. #include "multibot.h"
  361. #include "ai.h"
  362.  
  363. //#define TEST_TIMER    1        //if this is set, do checking on timer
  364.  
  365. #define    SHOW_EXIT_PATH    1
  366. #define FINAL_CHEATS 1
  367.  
  368. #ifdef ARCADE
  369. #include "arcade.h"
  370. #else
  371. #define Arcade_mode 0
  372. #endif
  373.  
  374. #include "victor.h"
  375.  
  376. #include "vfx.h"
  377.  
  378. #ifdef EDITOR
  379. #include "editor\editor.h"
  380. #endif
  381.  
  382. //#define _MARK_ON 1
  383. //#include <wsample.h>            //should come after inferno.h to get mark setting
  384. //Above file is missing in the release version of the source. -KRB
  385.  
  386. int    Speedtest_on = 0;
  387.  
  388. #ifndef NDEBUG
  389. int    Mark_count = 0;                 // number of debugging marks set
  390. int    Speedtest_start_time;
  391. int    Speedtest_segnum;
  392. int    Speedtest_sidenum;
  393. int    Speedtest_frame_start;
  394. int    Speedtest_count=0;                //    number of times to do the debug test.
  395. #endif
  396.  
  397. static fix last_timer_value=0;
  398.  
  399. #if defined(TIMER_TEST) && !defined(NDEBUG)
  400. fix _timer_value,actual_last_timer_value,_last_frametime;
  401. int stop_count,start_count;
  402. int time_stopped,time_started;
  403. #endif
  404.  
  405. ubyte * Game_cockpit_copy_code = NULL;
  406.  
  407. ubyte new_cheats[]= {KEY_B^0xaa, KEY_B^0xaa, KEY_B^0xaa, KEY_F^0xaa, KEY_A^0xaa,
  408.                             KEY_U^0xaa, KEY_I^0xaa, KEY_R^0xaa, KEY_L^0xaa, KEY_H^0xaa,
  409.                             KEY_G^0xaa, KEY_G^0xaa, KEY_U^0xaa, KEY_A^0xaa, KEY_I^0xaa,
  410.                             KEY_G^0xaa, KEY_R^0xaa, KEY_I^0xaa, KEY_S^0xaa, KEY_M^0xaa,
  411.                             KEY_I^0xaa, KEY_E^0xaa, KEY_N^0xaa, KEY_H^0xaa, KEY_S^0xaa,
  412.                             KEY_N^0xaa, KEY_D^0xaa, KEY_X^0xaa, KEY_X^0xaa, KEY_A^0xaa };
  413.  
  414. ubyte            VR_use_paging        = 0;
  415. ubyte            VR_current_page    = 0;
  416. ubyte            VR_switch_eyes        = 0;
  417. fix            VR_eye_width        = F1_0;
  418. int            VR_eye_offset        = 0;
  419. int            VR_eye_offset_changed    = 0;
  420. int            VR_screen_mode        = 0;
  421. int            VR_render_width    = 0;
  422. int            VR_render_height    = 0;
  423. int            VR_render_mode        = VR_NONE;
  424. int            VR_compatible_menus    = 0;
  425. int            VR_low_res             = 3;                // Default to low res
  426. int             VR_show_hud = 1;
  427. int            VR_sensitivity     = 1;        // 0 - 2
  428. grs_canvas  *VR_offscreen_buffer    = NULL;        // The offscreen data buffer
  429. grs_canvas    VR_render_buffer[2];                    //  Two offscreen buffers for left/right eyes.
  430. grs_canvas    VR_render_sub_buffer[2];            //  Two sub buffers for left/right eyes.
  431. grs_canvas    VR_screen_pages[2];                    //  Two pages of VRAM if paging is available
  432. grs_canvas    VR_editor_canvas;                        //  The canvas that the editor writes to.
  433.  
  434. int Debug_pause=0;                //John's debugging pause system
  435.  
  436. int Cockpit_mode=CM_FULL_COCKPIT;        //set game.h for values
  437. int old_cockpit_mode=-1;
  438. int force_cockpit_redraw=0;
  439.  
  440. int framerate_on=0;
  441.  
  442. int PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd;
  443.  
  444. //    Toggle_var points at a variable which gets !ed on ctrl-alt-T press.
  445. int    Dummy_var;
  446. int    *Toggle_var = &Dummy_var;
  447.  
  448. #ifdef EDITOR
  449. //flag for whether initial fade-in has been done
  450. char faded_in;
  451. #endif
  452.  
  453. #ifndef NDEBUG                          //these only exist if debugging
  454.  
  455. int Game_double_buffer = 1;     //double buffer by default
  456. fix fixed_frametime=0;          //if non-zero, set frametime to this
  457.  
  458. #endif
  459.  
  460. int Game_suspended=0;           //if non-zero, nothing moves but player
  461.  
  462. int Game_vfx_flag = 0;
  463. int Game_victor_flag = 0;
  464. int Game_vio_flag = 0;
  465. int Game_3dmax_flag = 0;
  466.  
  467.  
  468. #define VR_SEPARATION F1_0*7/10
  469. #define VR_PIXEL_SHIFT -6
  470. #define VR_DEFAULT_OFFSET_RATIO F1_0
  471. #define VR_MIN_SEPARATION F1_0/20
  472. #define VR_MAX_SEPARATION F1_0*2
  473. #define VR_DEFAULT_OFFSET_RATIO F1_0
  474. #define VR_MIN_OFFSET_RATIO F1_0/5
  475. #define VR_MAX_OFFSET_RATIO F1_0*2
  476.  
  477.             // basically, if pixel-shift equals -6, this adjustment factor
  478.             //      equals 7/6 (fixed-point);
  479. #define VR_ADJUST_OFFSET_RATIO (F1_0*(VR_PIXEL_SHIFT-1)/VR_PIXEL_SHIFT)
  480.  
  481. int simuleyes_offset_ratio = VR_DEFAULT_OFFSET_RATIO;
  482. int simuleyes_adjusted_offset_ratio;
  483. int simuleyes_right_eye_view;
  484. int Game_simuleyes_flag = 0;
  485.  
  486. int svr_black = 0x00;
  487. int svr_white = 0xFF;
  488.  
  489. void vr_reset_display();
  490.  
  491. fix     RealFrameTime;
  492. fix    Auto_fire_fusion_cannon_time = 0;
  493. fix    Fusion_charge = 0;
  494. fix    Fusion_next_sound_time = 0;
  495.  
  496. int Debug_spew = 1;
  497. int Game_turbo_mode = 0;
  498.  
  499. int Game_mode = GM_GAME_OVER;
  500.  
  501. int    Global_laser_firing_count = 0;
  502. int    Global_missile_firing_count = 0;
  503.  
  504. grs_bitmap background_bitmap;
  505.  
  506. int Game_aborted;
  507.  
  508. extern void newdemo_strip_frames(char *, int);
  509.  
  510. #define BACKGROUND_NAME "statback.pcx"
  511.  
  512. //    ==============================================================================================
  513.  
  514. #ifndef NDEBUG
  515. void speedtest_init(void)
  516. {
  517.     Speedtest_start_time = timer_get_fixed_seconds();
  518.     Speedtest_on = 1;
  519.     Speedtest_segnum = 0;
  520.     Speedtest_sidenum = 0;
  521.     Speedtest_frame_start = FrameCount;
  522.  
  523.     mprintf((0, "Starting speedtest.  Will be %i frames.  Each . = 10 frames.\n", Highest_segment_index+1));
  524. }
  525.  
  526. void speedtest_frame(void)
  527. {
  528.     vms_vector    view_dir, center_point;
  529.  
  530.     Speedtest_sidenum=Speedtest_segnum % MAX_SIDES_PER_SEGMENT;
  531.  
  532.     compute_segment_center(&Viewer->pos, &Segments[Speedtest_segnum]);
  533.     Viewer->pos.x += 0x10;        Viewer->pos.y -= 0x10;        Viewer->pos.z += 0x17;
  534.  
  535.     obj_relink(Viewer-Objects, Speedtest_segnum);
  536.     compute_center_point_on_side(¢er_point, &Segments[Speedtest_segnum], Speedtest_sidenum);
  537.     vm_vec_normalized_dir_quick(&view_dir, ¢er_point, &Viewer->pos);
  538.     vm_vector_2_matrix(&Viewer->orient, &view_dir, NULL, NULL);
  539.  
  540.     if (((FrameCount - Speedtest_frame_start) % 10) == 0)
  541.         mprintf((0, "."));
  542.  
  543.     Speedtest_segnum++;
  544.  
  545.     if (Speedtest_segnum > Highest_segment_index) {
  546.         mprintf((0, "\nSpeedtest done:  %i frames, %7.3f seconds, %7.3f frames/second.\n", 
  547.             FrameCount-Speedtest_frame_start,
  548.             f2fl(timer_get_fixed_seconds() - Speedtest_start_time),
  549.             (float) (FrameCount-Speedtest_frame_start) / f2fl(timer_get_fixed_seconds() - Speedtest_start_time)));
  550.         Speedtest_count--;
  551.         if (Speedtest_count == 0)
  552.             Speedtest_on = 0;
  553.         else
  554.             speedtest_init();
  555.     }                
  556.  
  557. }
  558.  
  559. #endif
  560.  
  561. //this is called once per game
  562. void init_game()
  563. {
  564.     ubyte pal[256*3];
  565.     int pcx_error;
  566.  
  567.     atexit(close_game);             //for cleanup
  568.  
  569.     init_objects();
  570.  
  571.     hostage_init();
  572.  
  573.     init_special_effects();
  574.  
  575.     init_ai_system();
  576.  
  577.     init_gauge_canvases();
  578.  
  579.     init_exploding_walls();
  580.  
  581.     background_bitmap.bm_data=NULL;
  582.     pcx_error = pcx_read_bitmap(BACKGROUND_NAME,&background_bitmap,BM_LINEAR,pal);
  583.     if (pcx_error != PCX_ERROR_NONE)
  584.         Error("File %s - PCX error: %s",BACKGROUND_NAME,pcx_errormsg(pcx_error));
  585.     gr_remap_bitmap_good( &background_bitmap, pal, -1, -1 );
  586.  
  587.     Clear_window = 2;        //    do portal only window clear.
  588. }
  589.  
  590.  
  591. void reset_palette_add()
  592. {
  593.     PaletteRedAdd         = 0;
  594.     PaletteGreenAdd    = 0;
  595.     PaletteBlueAdd        = 0;
  596.     //gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  597. }
  598.  
  599.  
  600. game_show_warning(char *s)
  601. {
  602.  
  603.     if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  604.         stop_time();
  605.  
  606.     nm_messagebox( TXT_WARNING, 1, TXT_OK, s );
  607.  
  608.     if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  609.         start_time();
  610. }
  611.  
  612.  
  613. //these should be in gr.h 
  614. #define cv_w  cv_bitmap.bm_w
  615. #define cv_h  cv_bitmap.bm_h
  616.  
  617. #define LETTERBOX_HEIGHT 140
  618.  
  619. int Game_window_w = 0;
  620. int Game_window_h = 0;
  621. int max_window_h = 0;
  622.  
  623. int last_drawn_cockpit[2] = { -1, -1 };
  624.  
  625. extern int Rear_view;
  626.  
  627. // This actually renders the new cockpit onto the screen.
  628. void update_cockpits(int force_redraw)
  629. {
  630.     int x, y, w, h;
  631.  
  632.     if (Cockpit_mode != last_drawn_cockpit[VR_current_page] || force_redraw )
  633.         last_drawn_cockpit[VR_current_page] = Cockpit_mode;
  634.     else
  635.         return;
  636.  
  637.     //Redraw the on-screen cockpit bitmaps
  638.     if (VR_render_mode != VR_NONE )    return;
  639.  
  640.     switch( Cockpit_mode )    {
  641.     case CM_FULL_COCKPIT:
  642.     case CM_REAR_VIEW:
  643.         gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  644.         PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode]);
  645.         gr_ubitmapm(0,0, &GameBitmaps[cockpit_bitmap[Cockpit_mode].index]);    
  646.         break;
  647.     case CM_FULL_SCREEN:
  648.         break;
  649.     case CM_STATUS_BAR:
  650.         gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  651.         PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode]);
  652.         gr_ubitmapm(0,max_window_h,&GameBitmaps[cockpit_bitmap[Cockpit_mode].index]);
  653.         w = Game_window_w;
  654.         h = Game_window_h;
  655.         x = (VR_render_width - w)/2;
  656.         y = (max_window_h - h)/2;
  657.         fill_background(x,y,w,h,x,y);
  658.         break;
  659.     case CM_LETTERBOX:
  660.         gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  661.         gr_clear_canvas( BM_XRGB(0,0,0) );
  662.         break;
  663.     }
  664.  
  665.     gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  666.     
  667.     if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR)
  668.         init_gauges();
  669.  
  670. }
  671.  
  672. //initialize the various canvases on the game screen
  673. //called every time the screen mode or cockpit changes
  674. void init_cockpit()
  675. {
  676.     int minx, maxx, miny, maxy;
  677.  
  678.     //Initialize the on-screen canvases
  679.  
  680.     if ( VR_render_mode != VR_NONE )
  681.         Cockpit_mode = CM_FULL_SCREEN;
  682.  
  683.     if ( VR_screen_mode != SM_320x200C )    {        // This really should be 'if VR_screen_mode isn't linear'
  684.         // We can only use cockpit or rearview mode in mode 13h
  685.         //if ( (Cockpit_mode==CM_FULL_COCKPIT) || (Cockpit_mode==CM_REAR_VIEW) )    {
  686.         //    if (Game_window_h > max_window_h)            //too big for scalable
  687.         //        Cockpit_mode = CM_FULL_SCREEN;
  688.         //    else
  689.         //        Cockpit_mode = CM_STATUS_BAR;
  690.         //}
  691.         //if ( (grd_curscreen->sc_w > 320) || (VR_use_paging) )
  692.         //        Cockpit_mode = CM_FULL_SCREEN;
  693.         Cockpit_mode = CM_FULL_SCREEN;
  694.     }
  695.  
  696.     if ( Screen_mode == SCREEN_EDITOR )
  697.         Cockpit_mode = CM_FULL_SCREEN;
  698.  
  699.     gr_set_curfont( GAME_FONT );
  700.  
  701.     if (Game_cockpit_copy_code)
  702.         free(Game_cockpit_copy_code);
  703.     Game_cockpit_copy_code  = NULL;
  704.  
  705.     switch( Cockpit_mode )    {
  706.     case CM_FULL_COCKPIT:
  707.     case CM_REAR_VIEW:        {
  708.         grs_bitmap *bm = &GameBitmaps[cockpit_bitmap[Cockpit_mode].index];
  709.  
  710.         PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode]);
  711.         gr_set_current_canvas(VR_offscreen_buffer);
  712.         gr_bitmap( 0, 0, bm );
  713.         bm = &VR_offscreen_buffer->cv_bitmap;
  714.         bm->bm_flags = BM_FLAG_TRANSPARENT;
  715.         gr_ibitblt_find_hole_size ( bm, &minx, &miny, &maxx, &maxy );
  716.         Game_cockpit_copy_code  = gr_ibitblt_create_mask( bm, minx, miny, maxx-minx+1, maxy-miny+1, VR_offscreen_buffer->cv_bitmap.bm_rowsize );
  717.         bm->bm_flags = 0;        // Clear all flags for offscreen canvas
  718.         game_init_render_sub_buffers( 0, 0, maxx-minx+1, maxy-miny+1 );
  719.         break;
  720.         }
  721.     case CM_FULL_SCREEN:
  722.         game_init_render_sub_buffers( 0, 0, VR_render_width, VR_render_height );
  723.         break;
  724.  
  725.     case CM_STATUS_BAR:    {
  726.         int x,y;
  727.  
  728.         if (Game_window_h > max_window_h) {
  729.             Game_window_w = VR_render_width;
  730.             Game_window_h = max_window_h;
  731.         }
  732.  
  733.         x = (VR_render_width - Game_window_w)/2;
  734.         y = (max_window_h - Game_window_h)/2;
  735.  
  736.         game_init_render_sub_buffers( x, y, Game_window_w, Game_window_h );
  737.         break;
  738.         }
  739.     case CM_LETTERBOX:    {
  740.         int x,y,w,h;
  741.             
  742.         x = 0; w = VR_render_width;
  743.         h = LETTERBOX_HEIGHT;
  744.         y = (VR_render_height-h)/2;
  745.             
  746.         game_init_render_sub_buffers( x, y, w, h );
  747.         break;
  748.         }
  749.     }
  750.     gr_set_current_canvas(NULL);
  751. }
  752.  
  753. //selects a given cockpit (or lack of one).  See types in game.h
  754. void select_cockpit(int mode)
  755. {
  756.     if (mode != Cockpit_mode) {        //new mode
  757.         Cockpit_mode=mode;
  758.         init_cockpit();
  759.     }
  760. }
  761.  
  762. //force cockpit redraw next time. call this if you've trashed the screen
  763. void reset_cockpit()
  764. {
  765.     force_cockpit_redraw=1;
  766.     last_drawn_cockpit[0] = -1;
  767.     last_drawn_cockpit[1] = -1;
  768. }
  769.  
  770. void HUD_clear_messages();
  771.  
  772. toggle_cockpit()
  773. {
  774.     int new_mode;
  775.  
  776.     switch (Cockpit_mode) {
  777.  
  778.         case CM_FULL_COCKPIT:
  779.             if (Game_window_h > max_window_h)            //too big for scalable
  780.                 new_mode = CM_FULL_SCREEN;
  781.             else
  782.                 new_mode = CM_STATUS_BAR;
  783.             break;
  784.  
  785.         case CM_STATUS_BAR:
  786.         case CM_FULL_SCREEN:
  787.             if (Rear_view)
  788.                 return;
  789.             new_mode = CM_FULL_COCKPIT;
  790.             break;
  791.  
  792.         case CM_REAR_VIEW:
  793.         case CM_LETTERBOX:
  794.             return;            //do nothing
  795.             break;
  796.  
  797.     }
  798.  
  799.     select_cockpit(new_mode);
  800.     HUD_clear_messages();
  801. }
  802.  
  803. #define WINDOW_W_DELTA 24    //20
  804. #define WINDOW_H_DELTA 12    //10
  805.  
  806. #define WINDOW_MIN_W        160
  807.  
  808. grow_window()
  809. {
  810.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  811.         Game_window_h = max_window_h;
  812.         Game_window_w = VR_render_width;
  813.         toggle_cockpit();
  814.         grow_window();
  815.         HUD_init_message("Press F3 to return to Cockpit mode");
  816.         return;
  817.     }
  818.  
  819.     if (Cockpit_mode != CM_STATUS_BAR)
  820.         return;
  821.  
  822.     if (Game_window_h >= max_window_h) {
  823.         Game_window_w = VR_render_width;
  824.         Game_window_h = VR_render_height;
  825.         select_cockpit(CM_FULL_SCREEN);
  826.     } else {
  827.         int x,y;
  828.  
  829.         Game_window_w += WINDOW_W_DELTA;
  830.         Game_window_h += WINDOW_H_DELTA;
  831.  
  832.         if (Game_window_h > max_window_h)
  833.             Game_window_h = max_window_h;
  834.  
  835.         if (Game_window_w > VR_render_width)
  836.             Game_window_w = VR_render_width;
  837.  
  838.         if (Game_window_h > VR_render_height)
  839.             Game_window_h = VR_render_height;
  840.  
  841.         x = (VR_render_width - Game_window_w)/2;
  842.         y = (max_window_h - Game_window_h)/2;
  843.  
  844.         game_init_render_sub_buffers( x, y, Game_window_w, Game_window_h );
  845.     }
  846.  
  847.     HUD_clear_messages();    //    @mk, 11/11/94
  848. }
  849.  
  850. grs_bitmap background_bitmap;
  851.  
  852. copy_background_rect(int left,int top,int right,int bot)
  853. {
  854.     grs_bitmap *bm = &background_bitmap;
  855.     int x,y;
  856.     int tile_left,tile_right,tile_top,tile_bot;
  857.     int ofs_x,ofs_y;
  858.     int dest_x,dest_y;
  859.  
  860.     tile_left = left / bm->bm_w;
  861.     tile_right = right / bm->bm_w;
  862.     tile_top = top / bm->bm_h;
  863.     tile_bot = bot / bm->bm_h;
  864.  
  865.     ofs_y = top % bm->bm_h;
  866.     dest_y = top;
  867.  
  868.     for (y=tile_top;y<=tile_bot;y++) {
  869.         int w,h;
  870.  
  871.         ofs_x = left % bm->bm_w;
  872.         dest_x = left;
  873.  
  874.         //h = (bot < dest_y+bm->bm_h)?(bot-dest_y+1):(bm->bm_h-ofs_y);
  875.         h = min(bot-dest_y+1,bm->bm_h-ofs_y);
  876.  
  877.         for (x=tile_left;x<=tile_right;x++) {
  878.  
  879.             //w = (right < dest_x+bm->bm_w)?(right-dest_x+1):(bm->bm_w-ofs_x);
  880.             w = min(right-dest_x+1,bm->bm_w-ofs_x);
  881.         
  882.             gr_bm_ubitblt(w,h,dest_x,dest_y,ofs_x,ofs_y,
  883.                     &background_bitmap,&grd_curcanv->cv_bitmap);
  884.  
  885.             ofs_x = 0;
  886.             dest_x += w;
  887.         }
  888.  
  889.         ofs_y = 0;
  890.         dest_y += h;
  891.     }
  892.  
  893.  
  894. }
  895.  
  896. fill_background(int x,int y,int w,int h,int dx,int dy)
  897. {
  898.     gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  899.     copy_background_rect(x-dx,y-dy,x-1,y+h+dy-1);
  900.     copy_background_rect(x+w,y-dy,x+w+dx-1,y+h+dy-1);
  901.     copy_background_rect(x,y-dy,x+w-1,y-1);
  902.     copy_background_rect(x,y+h,x+w-1,y+h+dy-1);
  903. }
  904.  
  905. shrink_window()
  906. {
  907.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  908.         Game_window_h = max_window_h;
  909.         Game_window_w = VR_render_width;
  910.         toggle_cockpit();
  911. //        shrink_window();
  912. //        shrink_window();
  913.         HUD_init_message("Press F3 to return to Cockpit mode");
  914.         return;
  915.     }
  916.  
  917.     if (Cockpit_mode == CM_FULL_SCREEN )    {
  918.         Game_window_h = max_window_h;
  919.         select_cockpit(CM_STATUS_BAR);
  920.         return;
  921.     }
  922.  
  923.     if (Cockpit_mode != CM_STATUS_BAR)
  924.         return;
  925.  
  926.     if (Game_window_w > WINDOW_MIN_W) {
  927.         int x,y;
  928.  
  929.         Game_window_w -= WINDOW_W_DELTA;
  930.         Game_window_h -= WINDOW_H_DELTA;
  931.  
  932.         if ( Game_window_w < WINDOW_MIN_W )
  933.             Game_window_w = WINDOW_MIN_W;
  934.  
  935.         x = (VR_render_width - Game_window_w)/2;
  936.         y = (max_window_h - Game_window_h)/2;
  937.  
  938.         fill_background(x,y,Game_window_w,Game_window_h,WINDOW_W_DELTA/2,WINDOW_H_DELTA/2);
  939.  
  940.         game_init_render_sub_buffers( x, y, Game_window_w, Game_window_h );
  941.     }
  942.  
  943.     HUD_clear_messages();
  944.  
  945. }
  946.  
  947. void game_init_render_sub_buffers( int x, int y, int w, int h )
  948. {
  949.     gr_init_sub_canvas( &VR_render_sub_buffer[0], &VR_render_buffer[0], x, y, w, h );
  950.     gr_init_sub_canvas( &VR_render_sub_buffer[1], &VR_render_buffer[1], x, y, w, h );
  951. }
  952.  
  953.  
  954. // Sets up the canvases we will be rendering to
  955. void game_init_render_buffers(int screen_mode, int render_w, int render_h, int use_paging, int render_method, int compatible_menus )
  956. {
  957.     if (!VR_offscreen_buffer)    {
  958.         VR_use_paging         = use_paging;
  959.         VR_switch_eyes        = 0;
  960.  
  961.         VR_eye_width        = VR_SEPARATION;    // 11/9/95
  962.         VR_eye_offset = VR_PIXEL_SHIFT;           // 11/9/95
  963.         simuleyes_adjusted_offset_ratio = fixdiv (VR_DEFAULT_OFFSET_RATIO *
  964.                     VR_PIXEL_SHIFT, VR_SEPARATION); // 11/10/95
  965.  
  966.         VR_screen_mode        = screen_mode;
  967.         VR_render_mode     = render_method;
  968.         VR_render_width    = render_w;
  969.         VR_render_height    = render_h;
  970.         VR_compatible_menus = compatible_menus;
  971.     
  972.         Game_window_w         = render_w;
  973.         Game_window_h        = render_h;
  974.  
  975.         if ( (VR_render_mode==VR_AREA_DET) || (VR_render_mode==VR_INTERLACED ) )    {
  976.             if ( render_h*2 < 200 )
  977.                 VR_offscreen_buffer = gr_create_canvas( render_w, 200 );
  978.             else
  979.                 VR_offscreen_buffer = gr_create_canvas( render_w, render_h*2 );
  980.             gr_init_sub_canvas( &VR_render_buffer[0], VR_offscreen_buffer, 0, 0, render_w, render_h );
  981.             gr_init_sub_canvas( &VR_render_buffer[1], VR_offscreen_buffer, 0, render_h, render_w, render_h );
  982.         } else {
  983.             if ( render_h < 200 )
  984.                 VR_offscreen_buffer = gr_create_canvas( render_w, 200 );
  985.             else
  986.                 VR_offscreen_buffer = gr_create_canvas( render_w, render_h );
  987.             gr_init_sub_canvas( &VR_render_buffer[0], VR_offscreen_buffer, 0, 0, render_w, render_h );
  988.             gr_init_sub_canvas( &VR_render_buffer[1], VR_offscreen_buffer, 0, 0, render_w, render_h );
  989.         }
  990.         game_init_render_sub_buffers( 0, 0, render_w, render_h );
  991.     }
  992. }
  993.  
  994. void game_3dmax_off()
  995. {
  996.     union REGS regs;
  997.  
  998. //    memset(®s,0,sizeof(regs));
  999. //    regs.w.ax = 0x4fd0;
  1000. //    regs.w.bx =    0x3d08;        // I
  1001. //    int386 (0x10, ®s, ®s);
  1002.  
  1003.     memset(®s,0,sizeof(regs));
  1004.     regs.w.ax = 0x4fd0;
  1005.     regs.w.bx =    0x3d00;        // Interlace off
  1006.     int386 (0x10, ®s, ®s);
  1007.  
  1008.     memset(®s,0,sizeof(regs));
  1009.     regs.w.ax = 0x4fd0;
  1010.     regs.w.bx =    0x3d02;        // Glasses off
  1011.     int386 (0x10, ®s, ®s);
  1012.  
  1013.     mprintf(( 0, "3dmax off\n" ));
  1014.     return;
  1015. }
  1016.  
  1017. void game_3dmax_on()
  1018. {
  1019.     union REGS regs;
  1020.  
  1021. //    memset(®s,0,sizeof(regs));
  1022. //    regs.w.ax = 0x4fd0;
  1023. // regs.w.bx =    0x3d09;        // Glasses on
  1024. //    int386 (0x10, ®s, ®s);
  1025.  
  1026.     memset(®s,0,sizeof(regs));
  1027.     regs.w.ax = 0x4fd0;
  1028.    regs.w.bx =    0x3d01;        // Interlace on
  1029.     int386 (0x10, ®s, ®s);
  1030.  
  1031.     memset(®s,0,sizeof(regs));
  1032.     regs.w.ax = 0x4fd0;
  1033.     regs.w.bx =    0x3d03;        // Glasses on
  1034.     int386 (0x10, ®s, ®s);
  1035.  
  1036.     mprintf(( 0, "3dmax on\n" ));
  1037.     return;
  1038. }
  1039.  
  1040.  
  1041.  
  1042.  
  1043. //called to change the screen mode. Parameter sm is the new mode, one of
  1044. //SMODE_GAME or SMODE_EDITOR. returns mode acutally set (could be other
  1045. //mode if cannot init requested mode)
  1046. int set_screen_mode(int sm)
  1047. {
  1048.     if ( (sm==SCREEN_MENU) && (Screen_mode==SCREEN_GAME) && VR_compatible_menus )    {
  1049.         sm = SCREEN_GAME;
  1050.     }
  1051.  
  1052. #ifdef EDITOR
  1053.     if ( (sm==SCREEN_MENU) && (Screen_mode==SCREEN_EDITOR) )    {
  1054.         gr_set_current_canvas( Canv_editor );
  1055.         return 1;
  1056.     }
  1057. #endif
  1058.  
  1059.     if ( Screen_mode == sm ) {
  1060.         gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
  1061. //        if ( VR_use_paging )    gr_show_canvas( &VR_screen_pages[VR_current_page] );
  1062.         return 1;
  1063.     }
  1064.  
  1065.     Screen_mode = sm;
  1066.  
  1067. #ifdef EDITOR
  1068.     Canv_editor = NULL;
  1069. #endif
  1070.  
  1071.     switch( Screen_mode )    {
  1072.     case SCREEN_MENU:
  1073.  
  1074.         if (grd_curscreen->sc_mode != SM_320x200C)    {
  1075.             if (gr_set_mode(SM_320x200C)) Error("Cannot set screen mode for game!");
  1076.              gr_palette_load( gr_palette );
  1077.         }
  1078.  
  1079.         if ( Game_3dmax_flag )
  1080.             game_3dmax_off();
  1081.  
  1082.         if ( Game_vfx_flag )
  1083.             vfx_close_graphics();
  1084.  
  1085.         gr_init_sub_canvas( &VR_screen_pages[0], &grd_curscreen->sc_canvas, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1086.         gr_init_sub_canvas( &VR_screen_pages[1], &grd_curscreen->sc_canvas, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1087.         break;
  1088.     case SCREEN_GAME:
  1089.         if (grd_curscreen->sc_mode != VR_screen_mode)    
  1090.             if (gr_set_mode(VR_screen_mode))    {
  1091.                 if ( VR_screen_mode != SM_640x480V )    
  1092.                     Error("Cannot set screen mode for game!");
  1093.                 else
  1094.                     Error( "Cannot set screen mode for game!\nMake sure that you have a VESA driver loaded\nthat can display 640x480 in 256 colors.\n" );
  1095.             }
  1096.  
  1097.         if ( Game_3dmax_flag )
  1098.             game_3dmax_on();
  1099.  
  1100.         if ( Game_vfx_flag )        {
  1101.             vfx_init_graphics();
  1102.             Beam_brightness=0x38000;
  1103.         }
  1104.  
  1105.         if ( VR_render_mode == VR_NONE )    {
  1106.             if ( max_window_h == 0 )    {
  1107.                 max_window_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR].index].bm_h;
  1108.                 Game_window_h = max_window_h;
  1109.             } else {
  1110.                 max_window_h = grd_curscreen->sc_h - GameBitmaps[cockpit_bitmap[CM_STATUS_BAR].index].bm_h;
  1111.             }
  1112.         } else {
  1113.             Cockpit_mode = CM_FULL_SCREEN;
  1114.         }        
  1115.         gr_init_sub_canvas( &VR_screen_pages[0], &grd_curscreen->sc_canvas, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1116.         if ( VR_use_paging )
  1117.             gr_init_sub_canvas( &VR_screen_pages[1], &grd_curscreen->sc_canvas, 0, grd_curscreen->sc_h, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1118.         else
  1119.             gr_init_sub_canvas( &VR_screen_pages[1], &grd_curscreen->sc_canvas, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1120.         break;
  1121.     #ifdef EDITOR
  1122.     case SCREEN_EDITOR:
  1123.         if (grd_curscreen->sc_mode != SM_800x600V)    {
  1124.             int gr_error;
  1125.             if ((gr_error=gr_set_mode(SM_800x600V))!=0) { //force into game scrren
  1126.                 Warning("Cannot init editor screen (error=%d)",gr_error);
  1127.                 return 0;
  1128.             }
  1129.         }
  1130.         gr_palette_load( gr_palette );
  1131.  
  1132.         gr_init_sub_canvas( &VR_editor_canvas, &grd_curscreen->sc_canvas, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h );
  1133.         Canv_editor = &VR_editor_canvas;
  1134.         gr_init_sub_canvas( &VR_screen_pages[0], Canv_editor, 0, 0, Canv_editor->cv_w, Canv_editor->cv_h );
  1135.         gr_init_sub_canvas( &VR_screen_pages[1], Canv_editor, 0, 0, Canv_editor->cv_w, Canv_editor->cv_h );
  1136.         gr_set_current_canvas( Canv_editor );
  1137.         init_editor_screen();   //setup other editor stuff
  1138.         break;
  1139.     #endif
  1140.     default:
  1141.         Error("Invalid screen mode %d",sm);
  1142.     }
  1143.  
  1144.     VR_current_page = 0;
  1145.  
  1146.     init_cockpit();
  1147.     
  1148.     gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
  1149.     if ( VR_use_paging )    gr_show_canvas( &VR_screen_pages[VR_current_page] );
  1150.  
  1151.     return 1;
  1152. }
  1153.  
  1154. #ifndef RELEASE
  1155. fix frame_time_list[8] = {0,0,0,0,0,0,0,0};
  1156. fix frame_time_total=0;
  1157. int frame_time_cntr=0;
  1158.  
  1159. void ftoa(char *string, fix f)
  1160. {
  1161.     int decimal, fractional;
  1162.     
  1163.     decimal = f2i(f);
  1164.     fractional = ((f & 0xffff)*100)/65536;
  1165.     if (fractional < 0 )
  1166.         fractional *= -1;
  1167.     if (fractional > 99 ) fractional = 99;
  1168.     sprintf( string, "%d.%02d", decimal, fractional );
  1169. }
  1170.  
  1171. show_framerate()
  1172. {
  1173.     char temp[50];
  1174.     fix rate;
  1175.  
  1176.     frame_time_total += RealFrameTime - frame_time_list[frame_time_cntr];
  1177.     frame_time_list[frame_time_cntr] = RealFrameTime;
  1178.     frame_time_cntr = (frame_time_cntr+1)%8;
  1179.  
  1180.     rate = fixdiv(f1_0*8,frame_time_total);
  1181.  
  1182.     gr_set_curfont( GAME_FONT );    
  1183.     gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  1184.  
  1185.     ftoa( temp, rate );    // Convert fixed to string
  1186.     gr_printf(grd_curcanv->cv_w-50,grd_curcanv->cv_h-20,"FPS: %s ", temp );
  1187. }
  1188. #endif
  1189.  
  1190. static timer_paused=0;        
  1191.  
  1192. void stop_time()
  1193. {
  1194.     if (timer_paused==0) {
  1195.         fix time;
  1196.         time = timer_get_fixed_seconds();
  1197.         last_timer_value = time - last_timer_value;
  1198.         if (last_timer_value < 0) {
  1199.             #if defined(TIMER_TEST) && !defined(NDEBUG)
  1200.             Int3();        //get Matt!!!!
  1201.             #endif
  1202.             last_timer_value = 0;
  1203.         }
  1204.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1205.         time_stopped = time;
  1206.         #endif
  1207.     }
  1208.     timer_paused++;
  1209.  
  1210.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1211.     stop_count++;
  1212.     #endif
  1213. }
  1214.  
  1215. void start_time()
  1216. {
  1217.     timer_paused--;
  1218.     Assert(timer_paused >= 0);
  1219.     if (timer_paused==0) {
  1220.         fix time;
  1221.         time = timer_get_fixed_seconds();
  1222.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1223.         if (last_timer_value < 0)
  1224.             Int3();        //get Matt!!!!
  1225.         }
  1226.         #endif
  1227.         last_timer_value = time - last_timer_value;
  1228.         #if defined(TIMER_TEST) && !defined(NDEBUG)
  1229.         time_started = time;
  1230.         #endif
  1231.     }
  1232.  
  1233.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1234.     start_count++;
  1235.     #endif
  1236. }
  1237.  
  1238. void game_flush_inputs()
  1239. {
  1240.     int dx,dy;
  1241.     key_flush();
  1242.     joy_flush();            
  1243.     mouse_flush();
  1244.     mouse_get_delta( &dx, &dy );    // Read mouse
  1245.     memset(&Controls,0,sizeof(control_info));
  1246. }
  1247.  
  1248. void reset_time()
  1249. {
  1250.     last_timer_value = timer_get_fixed_seconds();
  1251.  
  1252. }
  1253.  
  1254. void calc_frame_time()
  1255. {
  1256.     fix timer_value,last_frametime = FrameTime;
  1257.  
  1258.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1259.     _last_frametime = last_frametime;
  1260.     #endif
  1261.  
  1262.     timer_value = timer_get_fixed_seconds();
  1263.     FrameTime = timer_value - last_timer_value;
  1264.  
  1265.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1266.     _timer_value = timer_value;
  1267.     #endif
  1268.     
  1269.     #ifndef NDEBUG
  1270.     if (!(((FrameTime > 0) && (FrameTime <= F1_0)) || (Function_mode == FMODE_EDITOR) || (Newdemo_state == ND_STATE_PLAYBACK))) {
  1271.         mprintf((1,"Bad FrameTime - value = %x\n",FrameTime));
  1272.         if (FrameTime == 0)
  1273.             Int3();    //    Call Mike or Matt or John!  Your interrupts are probably trashed!
  1274. //        if ( !dpmi_virtual_memory )
  1275. //            Int3();        //Get MATT if hit this!
  1276.     }
  1277.     #endif
  1278.  
  1279.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1280.     actual_last_timer_value = last_timer_value;
  1281.     #endif
  1282.  
  1283.     if ( Game_turbo_mode )
  1284.         FrameTime *= 2;
  1285.  
  1286.     // Limit frametime to be between 5 and 150 fps.
  1287.     RealFrameTime = FrameTime;
  1288.     if ( FrameTime < F1_0/150 ) FrameTime = F1_0/150;
  1289.     if ( FrameTime > F1_0/5 ) FrameTime = F1_0/5;
  1290.  
  1291.     last_timer_value = timer_value;
  1292.  
  1293.     if (FrameTime < 0)                        //if bogus frametime...
  1294.         FrameTime = last_frametime;        //...then use time from last frame
  1295.  
  1296.     #ifndef NDEBUG
  1297.     if (fixed_frametime) FrameTime = fixed_frametime;
  1298.     #endif
  1299.  
  1300.     #ifndef NDEBUG
  1301.     // Pause here!!!
  1302.     if ( Debug_pause )      {
  1303.         int c;
  1304.         c = 0;
  1305.         while( c==0 )
  1306.             c = key_peekkey();
  1307.             
  1308.         if ( c == KEY_P )       {
  1309.             Debug_pause = 0;
  1310.             c = key_inkey();
  1311.         }
  1312.         last_timer_value = timer_get_fixed_seconds();
  1313.     }
  1314.     #endif
  1315.  
  1316.     #if Arcade_mode
  1317.         FrameTime /= 2;
  1318.     #endif
  1319.  
  1320.     #if defined(TIMER_TEST) && !defined(NDEBUG)
  1321.     stop_count = start_count = 0;
  1322.     #endif
  1323.  
  1324.     //    Set value to determine whether homing missile can see target.
  1325.     //    The lower frametime is, the more likely that it can see its target.
  1326.     if (FrameTime <= F1_0/16)
  1327.         Min_trackable_dot = 3*(F1_0 - MIN_TRACKABLE_DOT)/4 + MIN_TRACKABLE_DOT;
  1328.     else if (FrameTime < F1_0/4)
  1329.         Min_trackable_dot = fixmul(F1_0 - MIN_TRACKABLE_DOT, F1_0-4*FrameTime) + MIN_TRACKABLE_DOT;
  1330.     else
  1331.         Min_trackable_dot = MIN_TRACKABLE_DOT;
  1332.  
  1333. }
  1334.  
  1335. //--unused-- int Auto_flythrough=0;  //if set, start flythough automatically
  1336.  
  1337. void move_player_2_segment(segment *seg,int side)
  1338. {
  1339.     vms_vector vp;
  1340.  
  1341.     compute_segment_center(&ConsoleObject->pos,seg);
  1342.     compute_center_point_on_side(&vp,seg,side);
  1343.     vm_vec_sub2(&vp,&ConsoleObject->pos);
  1344.     vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
  1345.  
  1346.     obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
  1347.     
  1348. }
  1349.  
  1350. fix Show_view_text_timer = -1;
  1351.  
  1352. #ifndef NDEBUG
  1353.  
  1354. draw_window_label()
  1355. {
  1356.     if ( Show_view_text_timer > 0 )
  1357.     {
  1358.         char *viewer_name,*control_name;
  1359.  
  1360.         Show_view_text_timer -= FrameTime;
  1361.         gr_set_curfont( GAME_FONT );
  1362.  
  1363.         switch( Viewer->type )
  1364.         {
  1365.             case OBJ_FIREBALL:    viewer_name = "Fireball"; break;
  1366.             case OBJ_ROBOT:        viewer_name = "Robot"; break;
  1367.             case OBJ_HOSTAGE:        viewer_name = "Hostage"; break;
  1368.             case OBJ_PLAYER:        viewer_name = "Player"; break;
  1369.             case OBJ_WEAPON:        viewer_name = "Weapon"; break;
  1370.             case OBJ_CAMERA:        viewer_name = "Camera"; break;
  1371.             case OBJ_POWERUP:        viewer_name = "Powerup"; break;
  1372.             case OBJ_DEBRIS:        viewer_name = "Debris"; break;
  1373.             case OBJ_CNTRLCEN:    viewer_name = "Control Center"; break;
  1374.             default:                    viewer_name = "Unknown"; break;
  1375.         }
  1376.  
  1377.         switch ( Viewer->control_type) {
  1378.             case CT_NONE:            control_name = "Stopped"; break;
  1379.             case CT_AI:                control_name = "AI"; break;
  1380.             case CT_FLYING:        control_name = "Flying"; break;
  1381.             case CT_SLEW:            control_name = "Slew"; break;
  1382.             case CT_FLYTHROUGH:    control_name = "Flythrough"; break;
  1383.             case CT_MORPH:            control_name = "Morphing"; break;
  1384.             default:                    control_name = "Unknown"; break;
  1385.         }
  1386.  
  1387.         gr_set_fontcolor( gr_getcolor(31, 0, 0), -1 );
  1388.         gr_printf( 0x8000, 45, "%s View - %s",viewer_name,control_name );
  1389.  
  1390.     }
  1391. }
  1392. #endif
  1393.  
  1394.  
  1395. void render_countdown_gauge()
  1396. {
  1397.     if (!Endlevel_sequence && Fuelcen_control_center_destroyed  && (Fuelcen_seconds_left>-1) && (Fuelcen_seconds_left<127))    {
  1398.         int    y;
  1399.         gr_set_curfont( Gamefonts[4] );    //GAME_FONT );
  1400.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1401.         y = 20;
  1402.         if (!((Cockpit_mode == CM_STATUS_BAR) && (Game_window_w >= 19)))
  1403.             y += 5;
  1404.  
  1405.         gr_printf(0x8000, y, "T-%d s", Fuelcen_seconds_left );
  1406.     }
  1407. }
  1408.  
  1409. #ifdef NETWORK
  1410. void game_draw_multi_message()
  1411. {
  1412.     char temp_string[MAX_MULTI_MESSAGE_LEN+25];
  1413.  
  1414.     if ( (Game_mode&GM_MULTI) && (multi_sending_message))    {
  1415.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1416.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1417.         sprintf( temp_string, "%s: %s_", TXT_MESSAGE, Network_message );
  1418.         draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
  1419.  
  1420.     }
  1421.  
  1422.     if ( (Game_mode&GM_MULTI) && (multi_defining_message))    {
  1423.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1424.         gr_set_fontcolor(gr_getcolor(0,63,0), -1 );
  1425.         sprintf( temp_string, "%s #%d: %s_", TXT_MACRO, multi_defining_message, Network_message );
  1426.         draw_centered_text(grd_curcanv->cv_bitmap.bm_h/2-16, temp_string );
  1427.     }
  1428. }
  1429. #endif
  1430.  
  1431. // Returns the length of the first 'n' characters of a string.
  1432. int string_width( char * s, int n )
  1433. {
  1434.     int w,h,aw;
  1435.     char p;
  1436.     p = s[n];
  1437.     s[n] = 0;
  1438.     gr_get_string_size( s, &w, &h, &aw );
  1439.     s[n] = p;
  1440.     return w;
  1441. }
  1442.  
  1443. // Draw string 's' centered on a canvas... if wider than
  1444. // canvas, then wrap it.
  1445. void draw_centered_text( int y, char * s )
  1446. {
  1447.     int i, l;
  1448.     char p;
  1449.  
  1450.  
  1451.     l = strlen(s);
  1452.  
  1453.     if ( string_width( s, l ) < grd_curcanv->cv_bitmap.bm_w )    {
  1454.         gr_string( 0x8000, y, s );
  1455.         return;
  1456.     }
  1457.  
  1458.     for (i=0; i<l; i++ )    {
  1459.         if ( string_width(s,i) > (grd_curcanv->cv_bitmap.bm_w - 16) )    {
  1460.             p = s[i];
  1461.             s[i] = 0;
  1462.             gr_string( 0x8000, y, s );
  1463.             s[i] = p;
  1464.             gr_string( 0x8000, y+grd_curcanv->cv_font->ft_h+1, &s[i] );
  1465.             return;
  1466.         }
  1467.     }
  1468. }
  1469.  
  1470. extern fix Cruise_speed;
  1471.  
  1472. void game_draw_hud_stuff()
  1473. {
  1474.  
  1475.     #ifndef NDEBUG
  1476.     if (Debug_pause) {
  1477.         gr_set_curfont( HELP_FONT );
  1478.         gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 ); // gr_getcolor(31,0,0));
  1479.         gr_ustring( 0x8000, 85/2, "Debug Pause - Press P to exit" );
  1480.     }
  1481.     #endif
  1482.  
  1483.     #ifdef CROSSHAIR
  1484.     if ( Viewer->type == OBJ_PLAYER )
  1485.         laser_do_crosshair(Viewer);
  1486.     #endif
  1487.     
  1488.     #ifndef NDEBUG
  1489.     draw_window_label();
  1490.     #endif
  1491.  
  1492.     #ifdef NETWORK
  1493.     game_draw_multi_message();
  1494.     #endif
  1495.  
  1496.     if ((Newdemo_state == ND_STATE_PLAYBACK) || (Newdemo_state == ND_STATE_RECORDING)) {
  1497.         char message[128];
  1498.         int h,w,aw;
  1499.  
  1500.         if (Newdemo_state == ND_STATE_PLAYBACK) {
  1501.             if (Newdemo_vcr_state != ND_STATE_PRINTSCREEN) {
  1502.                   sprintf(message, "%s (%d%%%% %s)", TXT_DEMO_PLAYBACK, newdemo_get_percent_done(), TXT_DONE);
  1503.             } else {
  1504.                 sprintf (message, "");
  1505.             }
  1506.         } else 
  1507.             sprintf (message, TXT_DEMO_RECORDING);
  1508.  
  1509.         gr_set_curfont( GAME_FONT );    //GAME_FONT );
  1510.         gr_set_fontcolor(gr_getcolor(27,0,0), -1 );
  1511.  
  1512.         gr_get_string_size(message, &w, &h, &aw );
  1513.         if (Cockpit_mode == CM_FULL_COCKPIT)
  1514.             h += 15;
  1515.         else if ( Cockpit_mode == CM_LETTERBOX )
  1516.             h += 7;
  1517.  
  1518.         if (Cockpit_mode != CM_REAR_VIEW)
  1519.             gr_printf((grd_curcanv->cv_bitmap.bm_w-w)/2, grd_curcanv->cv_bitmap.bm_h - h - 2, message );
  1520.     }
  1521.  
  1522.     render_countdown_gauge();
  1523.  
  1524.     if ( Player_num > -1 && Viewer->type==OBJ_PLAYER && Viewer->id==Player_num )    {
  1525.         int    x = 3;
  1526.         int    y = grd_curcanv->cv_bitmap.bm_h;
  1527.  
  1528.         gr_set_curfont( GAME_FONT );
  1529.         gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
  1530.         if (Cruise_speed > 0)
  1531.             if (Cockpit_mode==CM_FULL_SCREEN) {
  1532.                 if (Game_mode & GM_MULTI)
  1533.                     y -= 64;
  1534.                 else
  1535.                     y -= 24;
  1536.             } else if (Cockpit_mode == CM_STATUS_BAR) {
  1537.                 if (Game_mode & GM_MULTI)
  1538.                     y -= 48;
  1539.                 else
  1540.                     y -= 24;
  1541.             } else {
  1542.                 y = 12;
  1543.                 x = 20;
  1544.             }
  1545.  
  1546.             gr_printf( x, y, "%s %2d%%", TXT_CRUISE, f2i(Cruise_speed) );
  1547.  
  1548.     }
  1549.  
  1550.     #ifdef ARCADE
  1551.     arcade_frame_info();
  1552.     #endif
  1553.  
  1554. #ifndef RELEASE
  1555.     if (framerate_on)
  1556.         show_framerate();
  1557. #endif
  1558.  
  1559. #ifndef SHAREWARE
  1560.     if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1561.         Game_mode = Newdemo_game_mode;
  1562. #endif
  1563.  
  1564.     draw_hud();
  1565.  
  1566. #ifndef SHAREWARE
  1567.     if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1568.         Game_mode = GM_NORMAL;
  1569. #endif
  1570.  
  1571.     if ( Player_is_dead )
  1572.         player_dead_message();
  1573. }
  1574.  
  1575. extern int gr_bitblt_dest_step_shift;
  1576. extern int gr_wait_for_retrace;
  1577. extern int gr_bitblt_double;
  1578.  
  1579. //render a frame for the game in stereo
  1580. game_render_frame_stereo_vfx()
  1581. {
  1582.     int dw,dh,sw,sh;
  1583.     fix save_aspect;
  1584.     grs_canvas RenderCanvas[2];
  1585.  
  1586.     save_aspect = grd_curscreen->sc_aspect;
  1587.  
  1588.     sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
  1589.     sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
  1590.  
  1591.     if (VR_low_res & 1)    {
  1592.         sh /= 2;                
  1593.         grd_curscreen->sc_aspect *= 2;  //Muck with aspect ratio                            
  1594.     }
  1595.     if (VR_low_res & 2)    {
  1596.         sw /= 2;                
  1597.         grd_curscreen->sc_aspect /= 2;  //Muck with aspect ratio                            
  1598.     }
  1599.  
  1600.     gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
  1601.     gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
  1602.  
  1603.     // Draw the left eye's view
  1604.     if (VR_switch_eyes)    
  1605.         gr_set_current_canvas(&RenderCanvas[1]);
  1606.     else
  1607.         gr_set_current_canvas(&RenderCanvas[0]);
  1608.     render_frame(-VR_eye_width);        // Left eye
  1609.     if ( VR_show_hud )
  1610.         game_draw_hud_stuff();
  1611.  
  1612.     // Draw the right eye's view
  1613.     if (VR_switch_eyes)    
  1614.         gr_set_current_canvas(&RenderCanvas[0]);
  1615.     else
  1616.         gr_set_current_canvas(&RenderCanvas[1]);
  1617.     render_frame(VR_eye_width);        // Right eye
  1618.  
  1619.     // Copy left eye, then right eye
  1620.     VR_current_page = !VR_current_page;
  1621.     gr_bitblt_dest_step_shift = 1;        // Skip every other scanline.
  1622.  
  1623.     if ( VR_low_res & 2 )        // Horizontal stretch
  1624.         gr_bitblt_double = 1;
  1625.  
  1626.     if ( VR_low_res & 1 )    {
  1627.         gr_bitblt_dest_step_shift = 2;            // Vertical stretch
  1628.         gr_bm_ubitblt( dw, sh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1629.         gr_bm_ubitblt( dw, sh, 0, VR_current_page+2, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1630.         gr_bm_ubitblt( dw, sh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1631.         gr_bm_ubitblt( dw, sh, dw, VR_current_page+2, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1632.     } else {
  1633.         gr_bm_ubitblt( dw, sh, 0, VR_current_page, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1634.         gr_bm_ubitblt( dw, sh, dw, VR_current_page, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[0].cv_bitmap);
  1635.     }
  1636.  
  1637.     gr_bitblt_double = 0;
  1638.     gr_bitblt_dest_step_shift = 0;
  1639.  
  1640.     if ( Game_vfx_flag )
  1641.         vfx_set_page(VR_current_page);        // 0 or 1
  1642.  
  1643.     grd_curscreen->sc_aspect = save_aspect; //restore aspect
  1644. }
  1645.  
  1646.  
  1647.  
  1648. //render a frame for the game in stereo
  1649. game_render_frame_stereo_interlaced()
  1650. {
  1651.     int dw,dh,sw,sh;
  1652.     fix save_aspect;
  1653.     grs_canvas RenderCanvas[2];
  1654.  
  1655.     save_aspect = grd_curscreen->sc_aspect;
  1656.     grd_curscreen->sc_aspect *= 2;    //Muck with aspect ratio
  1657.  
  1658.     sw = dw = VR_render_buffer[0].cv_bitmap.bm_w;
  1659.     sh = dh = VR_render_buffer[0].cv_bitmap.bm_h;
  1660.  
  1661.     if (VR_low_res & 1)    {
  1662.         sh /= 2;                
  1663.         grd_curscreen->sc_aspect *= 2;  //Muck with aspect ratio                            
  1664.     }
  1665.     if (VR_low_res & 2)    {
  1666.         sw /= 2;                
  1667.         grd_curscreen->sc_aspect /= 2;  //Muck with aspect ratio                            
  1668.     }
  1669.  
  1670.     gr_init_sub_canvas( &RenderCanvas[0], &VR_render_buffer[0], 0, 0, sw, sh );
  1671.     gr_init_sub_canvas( &RenderCanvas[1], &VR_render_buffer[1], 0, 0, sw, sh );
  1672.  
  1673.     // Draw the left eye's view
  1674.     if (VR_switch_eyes)    
  1675.         gr_set_current_canvas(&RenderCanvas[1]);
  1676.     else
  1677.         gr_set_current_canvas(&RenderCanvas[0]);
  1678.  
  1679.     if (Rear_view)
  1680.         render_frame(VR_eye_width);    // switch eye positions for rear view
  1681.     else
  1682.         render_frame(-VR_eye_width);        // Left eye
  1683.  
  1684.     if (VR_eye_offset > 0 ) {
  1685.         gr_setcolor( gr_getcolor(0,0,0) );
  1686.         gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(VR_eye_offset)*2, 0, 
  1687.                grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
  1688.     } else if (VR_eye_offset < 0 ) {
  1689.         gr_setcolor( gr_getcolor(0,0,0) );
  1690.         gr_rect( 0, 0, labs(VR_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
  1691.     }
  1692.  
  1693.     if ( VR_show_hud )    {
  1694.         grs_canvas tmp;
  1695.         if (VR_eye_offset < 0 ) {
  1696.             gr_init_sub_canvas( &tmp, grd_curcanv, labs(VR_eye_offset*2), 0, grd_curcanv->cv_bitmap.bm_w-(labs(VR_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
  1697.         } else {
  1698.             gr_init_sub_canvas( &tmp, grd_curcanv, 0, 0, grd_curcanv->cv_bitmap.bm_w-(labs(VR_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
  1699.         }
  1700.         gr_set_current_canvas( &tmp );
  1701.         game_draw_hud_stuff();
  1702.     }
  1703.  
  1704.  
  1705.     // Draw the right eye's view
  1706.     if (VR_switch_eyes)    
  1707.         gr_set_current_canvas(&RenderCanvas[0]);
  1708.     else
  1709.         gr_set_current_canvas(&RenderCanvas[1]);
  1710.  
  1711.     if (Rear_view)
  1712.         render_frame(-VR_eye_width);    // switch eye positions for rear view
  1713.     else
  1714.         render_frame(VR_eye_width);        // Right eye
  1715.  
  1716.     if (VR_eye_offset>0) {
  1717.         gr_setcolor( gr_getcolor(0,0,0) );
  1718.         gr_rect( 0, 0, labs(VR_eye_offset)*2-1, grd_curcanv->cv_bitmap.bm_h );
  1719.     } else if ( VR_eye_offset < 0 )    {
  1720.         gr_setcolor( gr_getcolor(0,0,0) );
  1721.         gr_rect( grd_curcanv->cv_bitmap.bm_w-labs(VR_eye_offset)*2, 0, 
  1722.                grd_curcanv->cv_bitmap.bm_w-1, grd_curcanv->cv_bitmap.bm_h );
  1723.     }
  1724.  
  1725.     if ( VR_show_hud )    {
  1726.         grs_canvas tmp;
  1727.         if (VR_eye_offset > 0 ) {
  1728.             gr_init_sub_canvas( &tmp, grd_curcanv, labs(VR_eye_offset*2), 0, grd_curcanv->cv_bitmap.bm_w-(labs(VR_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
  1729.         } else {
  1730.             gr_init_sub_canvas( &tmp, grd_curcanv, 0, 0, grd_curcanv->cv_bitmap.bm_w-(labs(VR_eye_offset)*2), grd_curcanv->cv_bitmap.bm_h );
  1731.         }
  1732.         gr_set_current_canvas( &tmp );
  1733.         game_draw_hud_stuff();
  1734.     }
  1735.  
  1736.  
  1737.     // Draws white and black registration encoding lines
  1738.     // and Accounts for pixel-shift adjustment in upcoming bitblts
  1739.     if (Game_simuleyes_flag)    {
  1740.         int width, height, quarter, nibble;
  1741.         void *pixptr, *drawptr;
  1742.  
  1743.         width = RenderCanvas[0].cv_bitmap.bm_w;
  1744.         height = RenderCanvas[0].cv_bitmap.bm_h;
  1745.         pixptr = RenderCanvas[0].cv_bitmap.bm_data;
  1746.         quarter = width / 4;
  1747.         nibble = labs(VR_eye_offset); // pixel-shift amount
  1748.  
  1749.         // black out left-hand side of left page
  1750.  
  1751.         // draw registration code for left eye
  1752.         drawptr = (void*)((int)pixptr + width*(height-1) - VR_eye_offset);
  1753.         memset(drawptr, svr_white, quarter);
  1754.         drawptr = (void*)((int)drawptr + quarter);
  1755.         if (VR_eye_offset < 0) // stay within buffer limit
  1756.             memset(drawptr, svr_black, 3*quarter - nibble);
  1757.         else
  1758.             memset(drawptr, svr_black, 3*quarter);
  1759.  
  1760.         // black out right-hand side of right page
  1761.         pixptr = RenderCanvas[1].cv_bitmap.bm_data;
  1762.  
  1763.  
  1764.         // draw registration code for right eye
  1765.         drawptr = (void*)((int)pixptr + width*(height-1) + VR_eye_offset);
  1766.         memset(drawptr, svr_white, 3*quarter);
  1767.         drawptr = (void*)((int)drawptr + 3*quarter);
  1768.         if (VR_eye_offset > 0) // stay within buffer limit
  1769.             memset(drawptr, svr_black, quarter - nibble);
  1770.         else
  1771.             memset(drawptr, svr_black, quarter);
  1772.    }
  1773.  
  1774.         // Copy left eye, then right eye
  1775.     if (  VR_use_paging   )
  1776.         VR_current_page = !VR_current_page;
  1777.     else 
  1778.         VR_current_page = 0;
  1779.     gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
  1780.  
  1781.     if ( VR_eye_offset_changed > 0 )    {
  1782.         VR_eye_offset_changed--;
  1783.         gr_clear_canvas(0);
  1784.     }
  1785.  
  1786.     if ( VR_low_res & 2 )        // Horizontal stretch
  1787.         gr_bitblt_double = 1;
  1788.  
  1789.     // Copy left eye, then right eye
  1790.     if ( VR_low_res & 1 )    {
  1791.         gr_bitblt_dest_step_shift = 2;    // Skip every 4 scanlines.
  1792.         if ( VR_eye_offset > 0 )    {
  1793.             int xoff = labs(VR_eye_offset);
  1794.             gr_bm_ubitblt( dw-xoff, dh/2, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1795.             gr_bm_ubitblt( dw-xoff, dh/2, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1796.             gr_bm_ubitblt( dw-xoff, dh/2, xoff, 2, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1797.             gr_bm_ubitblt( dw-xoff, dh/2, 0, 3, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1798.         } else if ( VR_eye_offset < 0 )    {
  1799.             int xoff = labs(VR_eye_offset);
  1800.             gr_bm_ubitblt( dw-xoff, dh/2, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1801.             gr_bm_ubitblt( dw-xoff, dh/2, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1802.             gr_bm_ubitblt( dw-xoff, dh/2, 0, 2, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1803.             gr_bm_ubitblt( dw-xoff, dh/2, xoff, 3, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1804.         } else {
  1805.             gr_bm_ubitblt( dw, dh/2, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1806.             gr_bm_ubitblt( dw, dh/2, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1807.             gr_bm_ubitblt( dw, dh/2, 0, 2, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1808.             gr_bm_ubitblt( dw, dh/2, 0, 3, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1809.         }
  1810.     } else {
  1811.         gr_bitblt_dest_step_shift = 1;        // Skip every other scanline.
  1812.         if ( VR_eye_offset > 0 )    {
  1813.             int xoff = labs(VR_eye_offset);
  1814.             gr_bm_ubitblt( dw-xoff, dh, xoff, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1815.             gr_bm_ubitblt( dw-xoff, dh, 0, 1, xoff, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1816.         } else if ( VR_eye_offset < 0 )    {
  1817.             int xoff = labs(VR_eye_offset);
  1818.             gr_bm_ubitblt( dw-xoff, dh, 0, 0, xoff, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1819.             gr_bm_ubitblt( dw-xoff, dh, xoff, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1820.         } else {
  1821.             gr_bm_ubitblt( dw, dh, 0, 0, 0, 0, &RenderCanvas[0].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1822.             gr_bm_ubitblt( dw, dh, 0, 1, 0, 0, &RenderCanvas[1].cv_bitmap, &VR_screen_pages[VR_current_page].cv_bitmap);
  1823.         }
  1824.     }
  1825.  
  1826.     gr_bitblt_double = 0;
  1827.     gr_bitblt_dest_step_shift = 0;
  1828.  
  1829.     if (  VR_use_paging  )    {
  1830.         gr_wait_for_retrace = 0;
  1831.  
  1832.         if ( (VR_screen_pages[VR_current_page].cv_bitmap.bm_type == BM_MODEX) && (Game_3dmax_flag==3) )    {
  1833.             int old_x, old_y, new_x;
  1834.             old_x = VR_screen_pages[VR_current_page].cv_bitmap.bm_x;
  1835.             old_y = VR_screen_pages[VR_current_page].cv_bitmap.bm_y;
  1836.             new_x = old_y*VR_screen_pages[VR_current_page].cv_bitmap.bm_rowsize;
  1837.             new_x += old_x/4;
  1838.             VR_screen_pages[VR_current_page].cv_bitmap.bm_x = new_x;
  1839.             VR_screen_pages[VR_current_page].cv_bitmap.bm_y = 0;
  1840.             VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_SVGA;
  1841.             gr_show_canvas( &VR_screen_pages[VR_current_page] );
  1842.             VR_screen_pages[VR_current_page].cv_bitmap.bm_type = BM_MODEX;
  1843.             VR_screen_pages[VR_current_page].cv_bitmap.bm_x = old_x;
  1844.             VR_screen_pages[VR_current_page].cv_bitmap.bm_y = old_y;
  1845.         } else {
  1846.             gr_show_canvas( &VR_screen_pages[VR_current_page] );
  1847.         }
  1848.         gr_wait_for_retrace = 1;
  1849.     }
  1850.     grd_curscreen->sc_aspect=save_aspect;
  1851. }
  1852.  
  1853.  
  1854.  
  1855. //render a frame for the game
  1856. void game_render_frame_mono(void)
  1857. {
  1858.     grs_canvas Screen_3d_window;
  1859.  
  1860.     gr_init_sub_canvas( &Screen_3d_window, &VR_screen_pages[0],
  1861.             VR_render_sub_buffer[0].cv_bitmap.bm_x, VR_render_sub_buffer[0].
  1862.             cv_bitmap.bm_y, VR_render_sub_buffer[0].cv_bitmap.bm_w,
  1863.             VR_render_sub_buffer[0].cv_bitmap.bm_h);
  1864.  
  1865.     if ( Game_double_buffer )    
  1866.         gr_set_current_canvas(&VR_render_sub_buffer[0]);
  1867.     else    {
  1868.         gr_set_current_canvas(&Screen_3d_window);
  1869.     }
  1870.  
  1871.     render_frame(0);
  1872.  
  1873.     game_draw_hud_stuff();
  1874.  
  1875.     if ( Game_double_buffer ) {        //copy to visible screen
  1876.         if ( Game_cockpit_copy_code==NULL )    {
  1877.             if ( VR_use_paging )    {        
  1878.                 VR_current_page = !VR_current_page;
  1879.                 gr_set_current_canvas( &VR_screen_pages[VR_current_page] );
  1880.                 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w,
  1881.                       VR_render_sub_buffer[0].cv_h, VR_render_sub_buffer[0].
  1882.                       cv_bitmap.bm_x, VR_render_sub_buffer[0].cv_bitmap.bm_y,
  1883.                       0, 0, &VR_render_sub_buffer[0].cv_bitmap,
  1884.                       &VR_screen_pages[VR_current_page].cv_bitmap );
  1885.                 gr_wait_for_retrace = 0;
  1886.                 gr_show_canvas( &VR_screen_pages[VR_current_page] );
  1887.                 gr_wait_for_retrace = 1;
  1888.             } else {
  1889.                 gr_bm_ubitblt( VR_render_sub_buffer[0].cv_w, VR_render_sub_buffer[0].cv_h, VR_render_sub_buffer[0].cv_bitmap.bm_x, VR_render_sub_buffer[0].cv_bitmap.bm_y, 0, 0, &VR_render_sub_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap );
  1890.             }
  1891.         } else    {
  1892.             gr_ibitblt( &VR_render_buffer[0].cv_bitmap, &VR_screen_pages[0].cv_bitmap, Game_cockpit_copy_code );
  1893.         }
  1894.     }
  1895.  
  1896.     if (Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR) {
  1897.  
  1898. #ifndef SHAREWARE
  1899.         if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1900.             Game_mode = Newdemo_game_mode;
  1901. #endif
  1902.  
  1903.         render_gauges();
  1904.  
  1905. #ifndef SHAREWARE
  1906.         if ( (Newdemo_state == ND_STATE_PLAYBACK) )
  1907.             Game_mode = GM_NORMAL;
  1908. #endif
  1909.     }
  1910.  
  1911. }
  1912.  
  1913. void game_render_frame()
  1914. {
  1915.     set_screen_mode( SCREEN_GAME );
  1916.  
  1917.     update_cockpits(0);
  1918.  
  1919.     play_homing_warning();
  1920.  
  1921.     if (VR_render_mode == VR_INTERLACED )
  1922.         game_render_frame_stereo_interlaced();
  1923.     else if (VR_render_mode == VR_AREA_DET)
  1924.         game_render_frame_stereo_vfx();
  1925.     else if (VR_render_mode == VR_NONE )
  1926.         game_render_frame_mono();        
  1927.  
  1928.     // Make sure palette is faded in
  1929.     stop_time();
  1930.     gr_palette_fade_in( gr_palette, 32, 0 );
  1931.     start_time();
  1932.  
  1933. }
  1934.  
  1935. void do_photos();
  1936. void level_with_floor();
  1937.  
  1938. void save_screen_shot(int automap_flag)
  1939. {
  1940.     fix t1;
  1941.     char message[100];
  1942.     grs_canvas *screen_canv=&grd_curscreen->sc_canvas;
  1943.     grs_font *save_font;
  1944.     static savenum=0;
  1945.     grs_canvas *temp_canv,*save_canv;
  1946.     char savename[13];
  1947.     ubyte pal[768];
  1948.     int w,h,aw,x,y;
  1949.  
  1950.     // Can't do screen shots in VR modes.
  1951.     if ( VR_render_mode != VR_NONE )
  1952.         return;
  1953.  
  1954.     stop_time();
  1955.  
  1956.     save_canv = grd_curcanv;
  1957.     temp_canv = gr_create_canvas(screen_canv->cv_bitmap.bm_w,screen_canv->cv_bitmap.bm_h);
  1958.     gr_set_current_canvas(temp_canv);
  1959.     gr_ubitmap(0,0,&screen_canv->cv_bitmap);
  1960.  
  1961.     if ( savenum > 99 ) savenum = 0;
  1962.     sprintf(savename,"screen%02d.pcx",savenum++);
  1963.     sprintf( message, "%s '%s'", TXT_DUMPING_SCREEN, savename );
  1964.  
  1965.     gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  1966.     save_font = grd_curcanv->cv_font;
  1967.     gr_set_curfont(GAME_FONT);
  1968.     gr_set_fontcolor(gr_find_closest_color_current(0,31,0),-1);
  1969.     gr_get_string_size(message,&w,&h,&aw);
  1970.     x = (VR_screen_pages[VR_current_page].cv_w-w)/2;
  1971.     y = (VR_screen_pages[VR_current_page].cv_h-h)/2;
  1972.  
  1973.     if (automap_flag) {
  1974.         modex_print_message(32, y, message);
  1975.     } else {
  1976.         gr_setcolor(gr_find_closest_color_current(0,0,0));
  1977.         gr_rect(x-2,y-2,x+w+2,y+h+2);
  1978.         gr_printf(x,y,message);
  1979.         gr_set_curfont(save_font);
  1980.     }
  1981.     t1 = timer_get_fixed_seconds() + F1_0;
  1982.  
  1983.     gr_palette_read(pal);        //get actual palette from the hardware
  1984.     pcx_write_bitmap(savename,&temp_canv->cv_bitmap,pal);
  1985.  
  1986.     while ( timer_get_fixed_seconds() < t1 );        // Wait so that messag stays up at least 1 second.
  1987.  
  1988.     gr_set_current_canvas(screen_canv);
  1989.  
  1990.     if (!automap_flag)
  1991.         gr_ubitmap(0,0,&temp_canv->cv_bitmap);
  1992.  
  1993.     gr_free_canvas(temp_canv);
  1994.  
  1995.     gr_set_current_canvas(save_canv);
  1996.     key_flush();
  1997.     start_time();
  1998. }
  1999.  
  2000. //initialize flying
  2001. fly_init(object *obj)
  2002. {
  2003.     obj->control_type = CT_FLYING;
  2004.     obj->movement_type = MT_PHYSICS;
  2005.  
  2006.     vm_vec_zero(&obj->mtype.phys_info.velocity);
  2007.     vm_vec_zero(&obj->mtype.phys_info.thrust);
  2008.     vm_vec_zero(&obj->mtype.phys_info.rotvel);
  2009.     vm_vec_zero(&obj->mtype.phys_info.rotthrust);
  2010. }
  2011.     
  2012. //void morph_test(), morph_step();
  2013.  
  2014. 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};
  2015.  
  2016. #define N_TEST_SOUNDS (sizeof(sound_nums) / sizeof(*sound_nums))
  2017.  
  2018. int test_sound_num=0;
  2019.  
  2020. play_test_sound()
  2021. {
  2022.  
  2023.     digi_play_sample(sound_nums[test_sound_num], F1_0);
  2024. }
  2025.  
  2026. //    ------------------------------------------------------------------------------------
  2027. advance_sound()
  2028. {
  2029.     if (++test_sound_num == N_TEST_SOUNDS)
  2030.         test_sound_num=0;
  2031.  
  2032. }
  2033.  
  2034. test_anim_states();
  2035.  
  2036. #include "fvi.h"
  2037.  
  2038. //put up the help message
  2039. void do_show_help()
  2040. {
  2041. //    if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  2042. //        stop_time();
  2043.  
  2044.     show_help();
  2045.  
  2046. //    if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME)))
  2047. //        start_time();
  2048.  
  2049. }
  2050.  
  2051. //--unused-- int save_newdemo_state;
  2052.  
  2053. extern int been_in_editor;
  2054.  
  2055. //--killed--//    ------------------------------------------------------------------------------------
  2056. //--killed--//    Return 1 if toggled, else return 0.
  2057. //--killed--//    Might not be able to toggle if off and not allowed to turn on.
  2058. //--killed--int toggle_afterburner_status(void)
  2059. //--killed--{
  2060. //--killed--    player    *pp = &Players[Player_num];
  2061. //--killed--
  2062. //--killed--    if (!(pp->flags & PLAYER_FLAGS_AFTERBURNER)) {
  2063. //--killed--        //    Was off, try to turn on.
  2064. //--killed--        if ((pp->afterburner_time > AFTERBURNER_MAX_TIME/4) && (pp->energy > 0)) {
  2065. //--killed--            pp->flags |= PLAYER_FLAGS_AFTERBURNER;
  2066. //--killed--        } else {
  2067. //--killed--            mprintf(0, "Cannot turn on afterburner due to energy or recharge.\n");
  2068. //--killed--            return 0;
  2069. //--killed--        }
  2070. //--killed--        return 1;
  2071. //--killed--    } else {
  2072. //--killed--        pp->flags ^= PLAYER_FLAGS_AFTERBURNER;
  2073. //--killed--        return 1;
  2074. //--killed--    }
  2075. //--killed--}
  2076.  
  2077. //    ------------------------------------------------------------------------------------
  2078. void do_cloak_stuff(void)
  2079. {
  2080.     int i;
  2081.     for (i = 0; i < N_players; i++)
  2082.         if (Players[i].flags & PLAYER_FLAGS_CLOAKED) {
  2083.             // mprintf(0, "Cloak time left: %7.3f\n", f2fl(CLOAK_TIME_MAX - (GameTime - Players[Player_num].cloak_time)));
  2084.             if (GameTime - Players[i].cloak_time > CLOAK_TIME_MAX) {
  2085.                 Players[i].flags &= ~PLAYER_FLAGS_CLOAKED;
  2086.                 if (i == Player_num) {
  2087.                     digi_play_sample( SOUND_CLOAK_OFF, F1_0);
  2088.                     #ifdef NETWORK
  2089.                     if (Game_mode & GM_MULTI)
  2090.                         multi_send_play_sound(SOUND_CLOAK_OFF, F1_0);
  2091.                     maybe_drop_net_powerup(POW_CLOAK);
  2092.                     multi_send_decloak(); // For demo recording
  2093.                     #endif
  2094. //                    mprintf((0, " --- You have been DE-CLOAKED! ---\n"));
  2095.                 }
  2096.             }
  2097.         }
  2098. }
  2099.  
  2100. //    ------------------------------------------------------------------------------------
  2101. void do_invulnerable_stuff(void)
  2102. {
  2103.     if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
  2104.         if (GameTime - Players[Player_num].invulnerable_time > INVULNERABLE_TIME_MAX) {
  2105.             Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  2106.             #ifdef NETWORK
  2107.             maybe_drop_net_powerup(POW_INVULNERABILITY);
  2108.             #endif
  2109.             digi_play_sample( SOUND_INVULNERABILITY_OFF, F1_0);
  2110.             #ifdef NETWORK
  2111.             if (Game_mode & GM_MULTI)
  2112.                 multi_send_play_sound(SOUND_INVULNERABILITY_OFF, F1_0);
  2113.             #endif
  2114.             mprintf((0, " --- You have been DE-INVULNERABLEIZED! ---\n"));
  2115.         }
  2116.     }
  2117. }
  2118.     
  2119. //--killed--//    ------------------------------------------------------------------------------------
  2120. //--killed--void do_afterburner_stuff(void)
  2121. //--killed--{
  2122. //--killed--    player    *pp = &Players[Player_num];
  2123. //--killed--
  2124. //--killed--//    mprintf(0, "[Afterburner] Time: %7.3f, status = %i\n", f2fl(pp->afterburner_time), pp->flags & PLAYER_FLAGS_AFTERBURNER);
  2125. //--killed--
  2126. //--killed--    if (pp->flags & PLAYER_FLAGS_AFTERBURNER) {
  2127. //--killed--        if (pp->afterburner_time > 0) {
  2128. //--killed--            pp->afterburner_time -= FrameTime;
  2129. //--killed--            pp->energy -= FrameTime/2;
  2130. //--killed--            if (pp->afterburner_time <= 0) {
  2131. //--killed--                pp->afterburner_time = 0;
  2132. //--killed--                pp->flags &= ~PLAYER_FLAGS_AFTERBURNER;
  2133. //--killed--                say_afterburner_status();
  2134. //--killed--            }
  2135. //--killed--            if (pp->energy <= 0) {
  2136. //--killed--                pp->energy = 0;
  2137. //--killed--                pp->flags &= ~PLAYER_FLAGS_AFTERBURNER;
  2138. //--killed--                say_afterburner_status();
  2139. //--killed--            }
  2140. //--killed--        }
  2141. //--killed--    } else {
  2142. //--killed--        //    Since afterburner is probably almost always max, do the check, we save time.
  2143. //--killed--        if (pp->afterburner_time < AFTERBURNER_MAX_TIME) {
  2144. //--killed--            pp->afterburner_time += FrameTime/2;
  2145. //--killed--            if (pp->afterburner_time > AFTERBURNER_MAX_TIME)
  2146. //--killed--                pp->afterburner_time = AFTERBURNER_MAX_TIME;
  2147. //--killed--        }
  2148. //--killed--    }
  2149. //--killed--
  2150. //--killed--}
  2151.  
  2152. //    Amount to diminish guns towards normal, per second.
  2153. #define    DIMINISH_RATE    16        //    gots to be a power of 2, else change the code in diminish_palette_towards_normal
  2154.  
  2155. //    ------------------------------------------------------------------------------------
  2156. //    Diminish palette effects towards normal.
  2157. void diminish_palette_towards_normal(void)
  2158. {
  2159.     int    dec_amount = 0;
  2160.  
  2161.     //    Diminish at DIMINISH_RATE units/second.
  2162.     //    For frame rates > DIMINISH_RATE Hz, use randomness to achieve this.
  2163.     if (FrameTime < F1_0/DIMINISH_RATE) {
  2164.         if (rand() < FrameTime*DIMINISH_RATE/2)    //    Note: rand() is in 0..32767, and 8 Hz means decrement every frame
  2165.             dec_amount = 1;
  2166.     } else {
  2167.         dec_amount = f2i(FrameTime*DIMINISH_RATE);        // one second = DIMINISH_RATE counts
  2168.         if (dec_amount == 0)
  2169.             dec_amount++;                        // make sure we decrement by something
  2170.     }
  2171.  
  2172.     if (PaletteRedAdd > 0 ) { PaletteRedAdd -= dec_amount; if (PaletteRedAdd < 0 ) PaletteRedAdd = 0; }
  2173.     if (PaletteRedAdd < 0 ) { PaletteRedAdd += dec_amount; if (PaletteRedAdd > 0 ) PaletteRedAdd = 0; }
  2174.  
  2175.     if (PaletteGreenAdd > 0 ) { PaletteGreenAdd -= dec_amount; if (PaletteGreenAdd < 0 ) PaletteGreenAdd = 0; }
  2176.     if (PaletteGreenAdd < 0 ) { PaletteGreenAdd += dec_amount; if (PaletteGreenAdd > 0 ) PaletteGreenAdd = 0; }
  2177.  
  2178.     if (PaletteBlueAdd > 0 ) { PaletteBlueAdd -= dec_amount; if (PaletteBlueAdd < 0 ) PaletteBlueAdd = 0; }
  2179.     if (PaletteBlueAdd < 0 ) { PaletteBlueAdd += dec_amount; if (PaletteBlueAdd > 0 ) PaletteBlueAdd = 0; }
  2180.  
  2181.     if ( (Newdemo_state==ND_STATE_RECORDING) && (PaletteRedAdd || PaletteGreenAdd || PaletteBlueAdd) )
  2182.         newdemo_record_palette_effect(PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd);
  2183.  
  2184.     gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  2185.  
  2186.     //mprintf(0, "%2i %2i %2i\n", PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd);
  2187.  
  2188.     // need to reset black and white palette colors for SVR registration
  2189.     if (Game_simuleyes_flag)  {
  2190.         // make black be black        
  2191.         outp( 0x3c6, 0xff );
  2192.         outp( 0x3c8, svr_black );
  2193.         outp( 0x3c9, 0 );
  2194.         outp( 0x3c9, 0 );
  2195.         outp( 0x3c9, 0 );
  2196.         // make white be white
  2197.         outp( 0x3c6, 0xff );
  2198.         outp( 0x3c8, svr_white );
  2199.         outp( 0x3c9, 63 );
  2200.         outp( 0x3c9, 63 );
  2201.         outp( 0x3c9, 63 );
  2202.     }
  2203. }
  2204.  
  2205. int    Redsave, Bluesave, Greensave;
  2206.  
  2207. void palette_save(void)
  2208. {
  2209.     Redsave = PaletteRedAdd; Bluesave = PaletteBlueAdd; Greensave = PaletteGreenAdd;
  2210. }
  2211.  
  2212. void palette_restore(void)
  2213. {
  2214.     PaletteRedAdd = Redsave; PaletteBlueAdd = Bluesave; PaletteGreenAdd = Greensave;
  2215.     gr_palette_step_up( PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd );
  2216. }
  2217.  
  2218. extern void dead_player_frame(void);
  2219.  
  2220. #ifndef RELEASE
  2221. do_cheat_menu()
  2222. {
  2223.     int mmn;
  2224.     newmenu_item mm[16];
  2225.     char score_text[21];
  2226.  
  2227.     sprintf( score_text, "%d", Players[Player_num].score );
  2228.  
  2229.     mm[0].type=NM_TYPE_CHECK; mm[0].value=Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE; mm[0].text="Invulnerability";
  2230.     mm[1].type=NM_TYPE_CHECK; mm[1].value=Players[Player_num].flags & PLAYER_FLAGS_IMMATERIAL; mm[1].text="Immaterial";
  2231.     mm[2].type=NM_TYPE_CHECK; mm[2].value=0; mm[2].text="All keys";
  2232.     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;
  2233.     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;
  2234.     mm[5].type=NM_TYPE_TEXT; mm[5].text = "Score:";
  2235.     mm[6].type=NM_TYPE_INPUT; mm[6].text_len = 10; mm[6].text = score_text;
  2236.     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";
  2237.     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";
  2238.     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";
  2239.     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";
  2240.     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;
  2241.  
  2242.     mmn = newmenu_do("Wimp Menu",NULL,12, mm, NULL );
  2243.  
  2244.     if (mmn > -1 )    {
  2245.         if ( mm[0].value )  {
  2246.             Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
  2247.             Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  2248.         } else
  2249.             Players[Player_num].flags &= ~PLAYER_FLAGS_INVULNERABLE;
  2250.         if ( mm[1].value ) 
  2251.             Players[Player_num].flags |= PLAYER_FLAGS_IMMATERIAL;
  2252.         else
  2253.             Players[Player_num].flags &= ~PLAYER_FLAGS_IMMATERIAL;
  2254.         if (mm[2].value) Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  2255.         Players[Player_num].energy=i2f(mm[3].value);
  2256.         Players[Player_num].shields=i2f(mm[4].value);
  2257.         Players[Player_num].score = atoi(mm[6].text);
  2258.         if (mm[7].value) Players[Player_num].laser_level=0;
  2259.         if (mm[8].value) Players[Player_num].laser_level=1;
  2260.         if (mm[9].value) Players[Player_num].laser_level=2;
  2261.         if (mm[10].value) Players[Player_num].laser_level=3;
  2262.         Players[Player_num].secondary_ammo[CONCUSSION_INDEX] = mm[11].value;
  2263.         init_gauges();
  2264.     }
  2265. }
  2266. #endif
  2267.  
  2268. //    --------------------------------------------------------------------------------------------------
  2269. int allowed_to_fire_laser(void)
  2270. {
  2271.     if (Player_is_dead) {
  2272.         Global_missile_firing_count = 0;
  2273.         return 0;
  2274.     }
  2275.  
  2276.     //    Make sure enough time has elapsed to fire laser, but if it looks like it will
  2277.     //    be a long while before laser can be fired, then there must be some mistake!
  2278.     if (Next_laser_fire_time > GameTime)
  2279.         if (Next_laser_fire_time < GameTime + 2*F1_0)
  2280.             return 0;
  2281.  
  2282.     return 1;
  2283. }
  2284.  
  2285. fix    Next_flare_fire_time = 0;
  2286.  
  2287. int allowed_to_fire_flare(void)
  2288. {
  2289.     if (Next_flare_fire_time > GameTime)
  2290.         if (Next_flare_fire_time < GameTime + F1_0)    //    In case time is bogus, never wait > 1 second.
  2291.             return 0;
  2292.  
  2293.     Next_flare_fire_time = GameTime + F1_0/4;
  2294.  
  2295.     return 1;
  2296. }
  2297.  
  2298. int allowed_to_fire_missile(void)
  2299. {
  2300. // mprintf(0, "Next fire = %7.3f, Cur time = %7.3f\n", f2fl(Next_missile_fire_time), f2fl(GameTime));
  2301.     //    Make sure enough time has elapsed to fire missile, but if it looks like it will
  2302.     //    be a long while before missile can be fired, then there must be some mistake!
  2303.     if (Next_missile_fire_time > GameTime)
  2304.         if (Next_missile_fire_time < GameTime + 5*F1_0)
  2305.             return 0;
  2306.  
  2307.     return 1;
  2308. }
  2309.  
  2310. typedef struct bkg {
  2311.     short x, y, w, h;            // The location of the menu.
  2312.     grs_bitmap * bmp;            // The background under the menu.
  2313. } bkg;
  2314.  
  2315. bkg bg = {0,0,0,0,NULL};
  2316.  
  2317. //show a message in a nice little box
  2318. show_boxed_message(char *msg)
  2319. {    
  2320.     int w,h,aw;
  2321.     int x,y;
  2322.  
  2323.     gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
  2324.     gr_set_curfont( HELP_FONT );
  2325.  
  2326.     gr_get_string_size(msg,&w,&h,&aw);
  2327.  
  2328.     x = (grd_curscreen->sc_w-w)/2;
  2329.     y = (grd_curscreen->sc_h-h)/2;
  2330.  
  2331.     if (bg.bmp) {
  2332.         gr_free_bitmap(bg.bmp);
  2333.         bg.bmp = NULL;
  2334.     }
  2335.  
  2336.     // Save the background of the display
  2337.     bg.x=x; bg.y=y; bg.w=w; bg.h=h;
  2338.  
  2339.     bg.bmp = gr_create_bitmap( w+30, h+30 );
  2340.     gr_bm_ubitblt(w+30, h+30, 0, 0, x-15, y-15, &(grd_curscreen->sc_canvas.cv_bitmap), bg.bmp );
  2341.  
  2342.     nm_draw_background(x-15,y-15,x+w+15-1,y+h+15-1);
  2343.  
  2344.     gr_set_fontcolor( gr_getcolor(31, 31, 31), -1 );
  2345.     gr_ustring( 0x8000, y, msg );
  2346.  
  2347. }
  2348.  
  2349. clear_boxed_message()
  2350. {
  2351.  
  2352.     if (bg.bmp) {
  2353.  
  2354.         gr_bitmap(bg.x-15, bg.y-15, bg.bmp);
  2355.  
  2356.         gr_free_bitmap(bg.bmp);
  2357.  
  2358.         bg.bmp = NULL;
  2359.     }
  2360. }
  2361.  
  2362. extern int Death_sequence_aborted;
  2363.  
  2364. //Process selected keys until game unpaused. returns key that left pause (p or esc)
  2365. int do_game_pause(int allow_menu)
  2366. {
  2367.     int paused;
  2368.     int key;
  2369.  
  2370.     if (Game_mode & GM_MULTI)
  2371.     {
  2372.         HUD_init_message(TXT_CANT_PAUSE);
  2373.         return(KEY_PAUSE);
  2374.     }
  2375.  
  2376.     digi_pause_all();
  2377.     stop_time();
  2378.  
  2379.     palette_save();
  2380.     reset_palette_add();
  2381.  
  2382.     game_flush_inputs();
  2383.  
  2384.     paused=1;
  2385.     
  2386.     set_screen_mode( SCREEN_MENU );
  2387.     gr_palette_load( gr_palette );
  2388.  
  2389.     show_boxed_message(TXT_PAUSE);
  2390.  
  2391.     while (paused) {
  2392.  
  2393.         key = key_getch();
  2394.  
  2395.         switch (key) {
  2396.             case 0:
  2397.                 break;
  2398.  
  2399.             case KEY_ESC:
  2400.                 if (allow_menu)
  2401.                     Function_mode = FMODE_MENU;
  2402.                 clear_boxed_message();
  2403.                 paused=0;
  2404.                 break;
  2405.  
  2406.             case KEY_F1:
  2407.                  clear_boxed_message();
  2408.                 do_show_help();
  2409.                 show_boxed_message(TXT_PAUSE);
  2410.                 break;
  2411.  
  2412.             case KEY_PRINT_SCREEN:
  2413.                 save_screen_shot(0);
  2414.                 break;
  2415.  
  2416.             #ifndef RELEASE
  2417.             case KEY_BACKSP: Int3(); break;
  2418.             #endif
  2419.  
  2420.             default:
  2421.                 clear_boxed_message();
  2422.                 paused=0;
  2423.                 break;
  2424.  
  2425.         }
  2426.  
  2427.     }
  2428.  
  2429.     game_flush_inputs();
  2430.  
  2431.     palette_restore();
  2432.  
  2433.     start_time();
  2434.     digi_resume_all();
  2435.  
  2436.     return key;
  2437. }
  2438.  
  2439.  
  2440. void show_help()
  2441. {
  2442.     newmenu_item m[14];
  2443.  
  2444.     if ( VR_render_mode != VR_NONE )    {
  2445.         m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_HELP_ESC;
  2446.         m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_HELP_ALT_F2;
  2447.         m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_HELP_ALT_F3;
  2448.         m[ 3].type = NM_TYPE_TEXT; m[ 3].text = TXT_HELP_F2;
  2449.         m[ 4].type = NM_TYPE_TEXT; m[ 4].text = TXT_HELP_F4;
  2450.         m[ 5].type = NM_TYPE_TEXT; m[ 5].text = TXT_HELP_F5;
  2451.         m[ 6].type = NM_TYPE_TEXT; m[ 6].text = TXT_HELP_PAUSE;
  2452.         m[ 7].type = NM_TYPE_TEXT; m[ 7].text = TXT_HELP_1TO5;
  2453.         m[ 8].type = NM_TYPE_TEXT; m[ 8].text = TXT_HELP_6TO10;
  2454.         m[ 9].type = NM_TYPE_TEXT; m[ 9].text = "";
  2455.         m[10].type = NM_TYPE_TEXT; m[10].text = TXT_HELP_TO_VIEW;
  2456.         newmenu_do( NULL, TXT_KEYS, 11, m, NULL );
  2457.     } else {
  2458.         m[ 0].type = NM_TYPE_TEXT; m[ 0].text = TXT_HELP_ESC;
  2459.         m[ 1].type = NM_TYPE_TEXT; m[ 1].text = TXT_HELP_ALT_F2;
  2460.         m[ 2].type = NM_TYPE_TEXT; m[ 2].text = TXT_HELP_ALT_F3;
  2461.         m[ 3].type = NM_TYPE_TEXT; m[ 3].text = TXT_HELP_F2;
  2462.         m[ 4].type = NM_TYPE_TEXT; m[ 4].text = TXT_HELP_F3;
  2463.         m[ 5].type = NM_TYPE_TEXT; m[ 5].text = TXT_HELP_F4;
  2464.         m[ 6].type = NM_TYPE_TEXT; m[ 6].text = TXT_HELP_F5;
  2465.         m[ 7].type = NM_TYPE_TEXT; m[ 7].text = TXT_HELP_PAUSE;
  2466.         m[ 8].type = NM_TYPE_TEXT; m[ 8].text = TXT_HELP_MINUSPLUS;
  2467.         m[ 9].type = NM_TYPE_TEXT; m[ 9].text = TXT_HELP_PRTSCN;
  2468.         m[10].type = NM_TYPE_TEXT; m[10].text = TXT_HELP_1TO5;
  2469.         m[11].type = NM_TYPE_TEXT; m[11].text = TXT_HELP_6TO10;
  2470.         m[12].type = NM_TYPE_TEXT; m[12].text = "";
  2471.         m[13].type = NM_TYPE_TEXT; m[13].text = TXT_HELP_TO_VIEW;
  2472.         newmenu_do( NULL, TXT_KEYS, 14, m, NULL );
  2473.     }
  2474.  
  2475. }
  2476.  
  2477.  
  2478. #ifdef ARCADE
  2479. void arcade_frame_info()
  2480. {
  2481.     if (!Arcade_mode) return;
  2482.  
  2483.     if ( Newdemo_state == ND_STATE_PLAYBACK )    {
  2484.         gr_set_curfont( GAME_FONT );    //game_font );
  2485.         gr_set_fontcolor(gr_getcolor(0,31,0), -1 );
  2486.         gr_printf(0x8000, 5, "Insert Coins to Play" );
  2487.         return;
  2488.     } 
  2489.  
  2490.     if (Arcade_timer > 0 )    {
  2491.         gr_set_curfont( GAME_FONT );
  2492.         gr_set_fontcolor( gr_getcolor(0, 31, 0), -1 );
  2493.         gr_printf( 0x8000, 5, "%d seconds left", f2i(Arcade_timer) );
  2494.      } else {
  2495.         gr_set_curfont( Gamefonts[GFONT_BIG_1] );    //GAME_FONT );
  2496.         gr_printf(0x8000, 40, "Game Over" );
  2497.     
  2498.         gr_set_curfont( Gamefonts[GFONT_MEDIUM_2] );    //GAME_FONT );
  2499.         gr_printf(0x8000, 60, "Insert Coins to Continue" );
  2500.         gr_printf(0x8000, 75, "%d", f2i(Arcade_timer)+10 );
  2501.     }    
  2502. }
  2503. #endif
  2504.  
  2505. //temp function until Matt cleans up game sequencing
  2506. extern void temp_reset_stuff_on_level();
  2507.  
  2508. //deal with rear view - switch it on, or off, or whatever
  2509. check_rear_view()
  2510. {
  2511.  
  2512.     #define LEAVE_TIME 0x4000        //how long until we decide key is down    (Used to be 0x4000)
  2513.  
  2514.     static int leave_mode;
  2515.     static fix entry_time;
  2516.  
  2517.     if ( Controls.rear_view_down_count )    {        //key/button has gone down
  2518.  
  2519.         if (Rear_view) {
  2520.             Rear_view = 0;
  2521.             if (Cockpit_mode==CM_REAR_VIEW) {
  2522.                 select_cockpit(old_cockpit_mode);
  2523.             }
  2524.             if (Newdemo_state == ND_STATE_RECORDING)
  2525.                 newdemo_record_restore_rearview();
  2526.         }
  2527.         else {
  2528.             Rear_view = 1;
  2529.             leave_mode = 0;        //means wait for another key
  2530.             entry_time = timer_get_fixed_seconds();
  2531.             if (Cockpit_mode == CM_FULL_COCKPIT) {
  2532.                 old_cockpit_mode = Cockpit_mode;
  2533.                 select_cockpit(CM_REAR_VIEW);
  2534.             }
  2535.             if (Newdemo_state == ND_STATE_RECORDING)
  2536.                 newdemo_record_rearview();
  2537.         }
  2538.     }
  2539.     else
  2540.         if (Controls.rear_view_down_state) {
  2541.  
  2542.             if (leave_mode==0 && (timer_get_fixed_seconds()-entry_time)>LEAVE_TIME)
  2543.                 leave_mode = 1;
  2544.         }
  2545.         else {
  2546.  
  2547.             //@@if (leave_mode==1 && Cockpit_mode==CM_REAR_VIEW) {
  2548.  
  2549.             if (leave_mode==1 && Rear_view) {
  2550.                 Rear_view = 0;
  2551.                 if (Cockpit_mode==CM_REAR_VIEW) {
  2552.                     select_cockpit(old_cockpit_mode); 
  2553.                 }
  2554.                 if (Newdemo_state == ND_STATE_RECORDING)
  2555.                     newdemo_record_restore_rearview();
  2556.             }
  2557.         }
  2558. }
  2559.  
  2560. void reset_rear_view(void)
  2561. {
  2562.     if (Rear_view) {
  2563.         if (Newdemo_state == ND_STATE_RECORDING)
  2564.             newdemo_record_restore_rearview();
  2565.     }
  2566.  
  2567.     Rear_view = 0;
  2568.  
  2569.     if (Cockpit_mode == CM_REAR_VIEW)
  2570.         select_cockpit(old_cockpit_mode);
  2571.  
  2572. }
  2573.  
  2574. #ifdef ARCADE
  2575. int keys_override;
  2576. #endif
  2577.  
  2578. int Automap_flag;
  2579. int Config_menu_flag;
  2580.  
  2581. jmp_buf LeaveGame;
  2582.  
  2583.  
  2584. #ifndef FINAL_CHEATS
  2585. 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};
  2586. #endif
  2587.  
  2588. byte    Enable_john_cheat_1, Enable_john_cheat_2, Enable_john_cheat_3, Enable_john_cheat_4;
  2589.  
  2590. int cheat_enable_index;
  2591. #define CHEAT_ENABLE_LENGTH (sizeof(cheat_enable_keys) / sizeof(*cheat_enable_keys))
  2592.  
  2593. #ifdef FINAL_CHEATS
  2594. 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};
  2595.  
  2596. ubyte cheat_wowie[] = {KEY_S,KEY_C,KEY_O,KEY_U,KEY_R,KEY_G,KEY_E};
  2597. ubyte cheat_allkeys[] = {KEY_M,KEY_I,KEY_T,KEY_Z,KEY_I};
  2598. ubyte cheat_invuln[] = {KEY_R,KEY_A,KEY_C,KEY_E,KEY_R,KEY_X};
  2599. ubyte cheat_cloak[] = {KEY_G,KEY_U,KEY_I,KEY_L,KEY_E};
  2600. ubyte cheat_shield[] = {KEY_T,KEY_W,KEY_I,KEY_L,KEY_I,KEY_G,KEY_H,KEY_T};
  2601. ubyte cheat_warp[] = {KEY_F,KEY_A,KEY_R,KEY_M,KEY_E,KEY_R,KEY_J,KEY_O,KEY_E};
  2602. ubyte cheat_astral[] = {KEY_A,KEY_S,KEY_T,KEY_R,KEY_A,KEY_L};
  2603.  
  2604. #define NUM_NEW_CHEATS 5
  2605.  
  2606. #define CHEAT_WOWIE_LENGTH (sizeof(cheat_wowie) / sizeof(*cheat_wowie))
  2607. #define CHEAT_ALLKEYS_LENGTH (sizeof(cheat_allkeys) / sizeof(*cheat_allkeys))
  2608. #define CHEAT_INVULN_LENGTH (sizeof(cheat_invuln) / sizeof(*cheat_invuln))
  2609. #define CHEAT_CLOAK_LENGTH (sizeof(cheat_cloak) / sizeof(*cheat_cloak))
  2610. #define CHEAT_SHIELD_LENGTH (sizeof(cheat_shield) / sizeof(*cheat_shield))
  2611. #define CHEAT_WARP_LENGTH (sizeof(cheat_warp) / sizeof(*cheat_warp))
  2612. #define CHEAT_ASTRAL_LENGTH (sizeof(cheat_astral) / sizeof(*cheat_astral))
  2613.  
  2614. #define CHEAT_TURBOMODE_OFS    0
  2615. #define CHEAT_WOWIE2_OFS        1
  2616. #define CHEAT_NEWLIFE_OFS        2
  2617. #define CHEAT_EXITPATH_OFS        3
  2618. #define CHEAT_ROBOTPAUSE_OFS    4
  2619.  
  2620. #define CHEAT_TURBOMODE_LENGTH    6
  2621. #define CHEAT_WOWIE2_LENGTH        6
  2622. #define CHEAT_NEWLIFE_LENGTH        5
  2623. #define CHEAT_EXITPATH_LENGTH        5
  2624. #define CHEAT_ROBOTPAUSE_LENGTH    6
  2625.  
  2626. int cheat_wowie_index;
  2627. int cheat_allkeys_index;
  2628. int cheat_invuln_index;
  2629. int cheat_cloak_index;
  2630. int cheat_shield_index;
  2631. int cheat_warp_index;
  2632. int cheat_astral_index;
  2633. int cheat_turbomode_index;
  2634. int cheat_wowie2_index;
  2635. int cheat_newlife_index;
  2636. int cheat_exitpath_index;
  2637. int cheat_robotpause_index;
  2638.  
  2639. #endif
  2640.  
  2641. int Cheats_enabled=0;
  2642.  
  2643. extern int Laser_rapid_fire, Ugly_robot_cheat;
  2644. extern void do_lunacy_on(), do_lunacy_off();
  2645.  
  2646. extern int Physics_cheat_flag;
  2647.  
  2648. void game_disable_cheats()
  2649. {
  2650.     Game_turbo_mode = 0;
  2651.     Cheats_enabled=0;
  2652.     do_lunacy_off();
  2653.     Laser_rapid_fire = 0;
  2654.     Ugly_robot_cheat = 0;
  2655.     Physics_cheat_flag = 0;
  2656. }
  2657.  
  2658. //    ------------------------------------------------------------------------------------
  2659. //this function is the game.  called when game mode selected.  runs until
  2660. //editor mode or exit selected
  2661. void game()
  2662. {
  2663.     //@@int demo_playing=0;
  2664.     //@@int multi_game=0;
  2665.  
  2666.     do_lunacy_on();        //    Copy values for insane into copy buffer in ai.c
  2667.     do_lunacy_off();        //    Restore true insane mode.
  2668.  
  2669.     Game_aborted = 0;
  2670.     last_drawn_cockpit[0] = -1;                // Force cockpit to redraw next time a frame renders.
  2671.     last_drawn_cockpit[1] = -1;                // Force cockpit to redraw next time a frame renders.
  2672.     Endlevel_sequence = 0;
  2673.  
  2674.     cheat_enable_index = 0;
  2675.  
  2676. #ifdef FINAL_CHEATS
  2677.     cheat_wowie_index = cheat_allkeys_index = cheat_invuln_index = cheat_cloak_index = cheat_shield_index = cheat_warp_index = cheat_astral_index = 0;
  2678.     cheat_turbomode_index = cheat_wowie2_index = 0;
  2679. #endif
  2680.  
  2681.     //@@if ( Newdemo_state == ND_STATE_PLAYBACK )
  2682.     //@@    demo_playing = 1;
  2683.     //@@if ( Game_mode & GM_MULTI )
  2684.     //@@    multi_game = 1;
  2685.  
  2686.     set_screen_mode(SCREEN_GAME);
  2687.     reset_palette_add();
  2688.  
  2689.     #ifdef ARCADE
  2690.     keys_override = FindArg("-keys");
  2691.     #endif
  2692.  
  2693.     set_warn_func(game_show_warning);
  2694.  
  2695.     init_cockpit();
  2696.     init_gauges();
  2697.     //digi_init_sounds();
  2698.  
  2699.     //keyd_repeat = 0;                // Don't allow repeat in game
  2700.     keyd_repeat = 1;                // Do allow repeat in game
  2701.  
  2702.     //_MARK_("start of game");Commented out -KRB
  2703.  
  2704.     #ifdef EDITOR
  2705.         if (Segments[ConsoleObject->segnum].segnum == -1)      //segment no longer exists
  2706.             obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(Cursegp) );
  2707.  
  2708.         if (!check_obj_seg(ConsoleObject))
  2709.             move_player_2_segment(Cursegp,Curside);
  2710.     #endif
  2711.  
  2712.     Viewer = ConsoleObject;
  2713.     fly_init(ConsoleObject);
  2714.  
  2715.     Game_suspended = 0;
  2716.  
  2717.     #ifdef ARCADE
  2718.     if (Arcade_mode)    {
  2719.         NewGame(1);
  2720.         newdemo_start_playback(NULL);
  2721.     }
  2722.     #endif
  2723.  
  2724.     reset_time();
  2725.     FrameTime = 0;            //make first frame zero
  2726.  
  2727.     #ifdef EDITOR
  2728.     if (Current_level_num == 0) {            //not a real level
  2729.         init_player_stats_game();
  2730.         init_ai_objects();
  2731.     }
  2732.     #endif
  2733.  
  2734.     fix_object_segs();
  2735.  
  2736.     game_flush_inputs();
  2737.  
  2738.     if ( setjmp(LeaveGame)==0 )    {
  2739.  
  2740.         if (VR_screen_mode != SCREEN_MENU)
  2741.             vr_reset_display();
  2742.  
  2743.         while (1) {
  2744.             // GAME LOOP!
  2745.             Automap_flag = 0;
  2746.             Config_menu_flag = 0;
  2747.  
  2748.             Assert( ConsoleObject == &Objects[Players[Player_num].objnum] );
  2749.  
  2750.             GameLoop( 1, 1 );        // Do game loop with rendering and reading controls.
  2751.  
  2752.             if (Config_menu_flag)    {
  2753.                 if (!(Game_mode&GM_MULTI)) palette_save();
  2754.                 do_options_menu();
  2755.                 if (!(Game_mode&GM_MULTI)) palette_restore();        
  2756.             }
  2757.  
  2758.             if (Automap_flag) {
  2759.                 int save_w=Game_window_w,save_h=Game_window_h;
  2760.                 if ( Game_3dmax_flag )
  2761.                     game_3dmax_off();
  2762.                 do_automap(0);
  2763.                 Screen_mode=-1; set_screen_mode(SCREEN_GAME);
  2764.                 Game_window_w=save_w; Game_window_h=save_h;
  2765.                 init_cockpit();
  2766.                 last_drawn_cockpit[0] = -1;
  2767.                 last_drawn_cockpit[1] = -1;
  2768.                 if ( Game_3dmax_flag )
  2769.                     game_3dmax_on();
  2770.  
  2771.                 if (VR_screen_mode != SCREEN_MENU)
  2772.                     vr_reset_display();
  2773.             }
  2774.  
  2775.             if ( (Function_mode != FMODE_GAME) && Auto_demo && (Newdemo_state != ND_STATE_NORMAL) )    {
  2776.                 int choice, fmode;
  2777.                 fmode = Function_mode;
  2778.                 Function_mode = FMODE_GAME;
  2779.                 choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_AUTODEMO );
  2780.                 Function_mode = fmode;
  2781.                 if (choice==0)    {
  2782.                     Auto_demo = 0;    
  2783.                     newdemo_stop_playback();
  2784.                     Function_mode = FMODE_MENU;
  2785.                 } else {
  2786.                     Function_mode = FMODE_GAME;
  2787.                 }
  2788.             }
  2789.     
  2790.             if ( (Function_mode != FMODE_GAME ) && (Newdemo_state != ND_STATE_PLAYBACK ) && (Function_mode!=FMODE_EDITOR) )        {
  2791.                 int choice, fmode;
  2792.                 fmode = Function_mode;
  2793.                 Function_mode = FMODE_GAME;
  2794.                 choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
  2795.                 Function_mode = fmode;
  2796.                 if (choice != 0)
  2797.                     Function_mode = FMODE_GAME;
  2798.             }
  2799.  
  2800.             if (Function_mode != FMODE_GAME)
  2801.                 longjmp(LeaveGame,0);
  2802.         }
  2803.     } 
  2804.  
  2805.     digi_stop_all();
  2806.  
  2807.     if ( (Newdemo_state == ND_STATE_RECORDING) || (Newdemo_state == ND_STATE_PAUSED) )
  2808.         newdemo_stop_recording();
  2809.  
  2810.     #ifdef NETWORK
  2811.     multi_leave_game();
  2812.     #endif
  2813.  
  2814.     if ( Newdemo_state == ND_STATE_PLAYBACK )    
  2815.          newdemo_stop_playback();
  2816.  
  2817.     if (Function_mode != FMODE_EDITOR)
  2818.         gr_palette_fade_out(gr_palette,32,0);            // Fade out before going to menu
  2819.  
  2820.     //@@if ( (!demo_playing) && (!multi_game) && (Function_mode != FMODE_EDITOR) )    {
  2821.     //@@    scores_maybe_add_player(Game_aborted);
  2822.     //@@}
  2823.  
  2824.     //_MARK_("end of game");//Commented out -KRB
  2825.  
  2826.     clear_warn_func(game_show_warning);     //don't use this func anymore
  2827.  
  2828.     game_disable_cheats();
  2829. }
  2830.  
  2831. extern void john_cheat_func_1(int);
  2832. extern void john_cheat_func_2(int);
  2833. extern void john_cheat_func_3(int);
  2834. extern void john_cheat_func_4(int);
  2835.  
  2836. //called at the end of the program
  2837. void close_game() 
  2838. {
  2839.     if (VR_offscreen_buffer)    {
  2840.         gr_free_canvas(VR_offscreen_buffer);            
  2841.         VR_offscreen_buffer = NULL;
  2842.     }
  2843.  
  2844.     close_gauge_canvases();
  2845.  
  2846.     restore_effect_bitmap_icons();
  2847.  
  2848.     if (Game_cockpit_copy_code)    {
  2849.         free(Game_cockpit_copy_code);
  2850.         Game_cockpit_copy_code = NULL;
  2851.     }
  2852.  
  2853.     if (background_bitmap.bm_data)
  2854.         free(background_bitmap.bm_data);
  2855.  
  2856.     clear_warn_func(game_show_warning);     //don't use this func anymore
  2857. }
  2858.  
  2859. grs_canvas * get_current_game_screen()
  2860. {
  2861.     return &VR_screen_pages[VR_current_page];
  2862. }
  2863.  
  2864. ubyte exploding_flag = 0;
  2865.  
  2866. extern dump_used_textures_all();
  2867. extern kconfig_center_headset();
  2868.  
  2869. void ReadControls()
  2870. {
  2871.     int key;
  2872.     fix key_time;
  2873.     static fix newdemo_single_frame_time;
  2874.  
  2875.         #ifdef ARCADE
  2876.         if (Arcade_mode)    {
  2877.             int coins;
  2878.             if (Newdemo_state!=ND_STATE_PLAYBACK)    {
  2879.                 Arcade_timer -= 2*FrameTime;
  2880.                 if ( Arcade_timer < (-F1_0*10) )    {
  2881.                     newdemo_toggle_playback();
  2882.                 }
  2883.             }
  2884.             coins = coindev_count(0);
  2885.             if (coins>0)    {
  2886.                 if ( Newdemo_state==ND_STATE_PLAYBACK )    {
  2887.                     newdemo_toggle_playback();
  2888.                     Arcade_timer = F1_0 * ARCADE_FIRST_SECONDS;        // Two minutes to play...
  2889.                     if (coins>1)
  2890.                         Arcade_timer += F1_0 * ARCADE_CONTINUE_SECONDS*(coins-1);        // Two minutes to play...
  2891.                     NewGame(1);
  2892.                 } else {
  2893.                     if (Arcade_timer < 0 )
  2894.                         Arcade_timer = 0;
  2895.                     Arcade_timer += F1_0 * ARCADE_CONTINUE_SECONDS*coins;        // Two minutes to play...
  2896.                 }
  2897.             }
  2898.         }
  2899.         #endif
  2900.  
  2901.         Player_fired_laser_this_frame=-1;
  2902.  
  2903. #ifndef NDEBUG
  2904.         if (Speedtest_on)
  2905.             speedtest_frame();
  2906. #endif
  2907.  
  2908.         if (!Endlevel_sequence && !Player_is_dead) {
  2909.  
  2910.             #ifdef ARCADE
  2911.             if (Arcade_mode)    {
  2912.                 if ( Arcade_timer > 0 )
  2913.                     if (Newdemo_state == ND_STATE_PLAYBACK )
  2914.                         memset( &Controls, 0, sizeof(control_info) );
  2915.                     else
  2916.                         controls_read_all();        //NOTE LINK TO ABOVE!!!
  2917.             } else
  2918.             #endif
  2919.                 if ( (Newdemo_state == ND_STATE_PLAYBACK) 
  2920.                     #ifdef NETWORK
  2921.                     || multi_sending_message || multi_defining_message
  2922.                     #endif
  2923.                     )     // WATCH OUT!!! WEIRD CODE ABOVE!!!
  2924.                     memset( &Controls, 0, sizeof(control_info) );
  2925.                 else
  2926.                     controls_read_all();        //NOTE LINK TO ABOVE!!!
  2927.  
  2928.             check_rear_view();
  2929.                         
  2930.             //    If automap key pressed, enable automap unless you are in network mode, control center destroyed and < 10 seconds left
  2931.             if ( Controls.automap_down_count && !((Game_mode & GM_MULTI) && Fuelcen_control_center_destroyed && (Fuelcen_seconds_left < 10)))
  2932.                 Automap_flag = 1;            
  2933.  
  2934.             if (Controls.fire_flare_down_count)
  2935.                 if (allowed_to_fire_flare())
  2936.                     Flare_create(ConsoleObject);
  2937.  
  2938.             if (allowed_to_fire_missile())
  2939.                 Global_missile_firing_count += Weapon_info[Secondary_weapon_to_weapon_info[Secondary_weapon]].fire_count * (Controls.fire_secondary_state || Controls.fire_secondary_down_count);
  2940.  
  2941.             if (Global_missile_firing_count) {
  2942.                 do_missile_firing();
  2943.                 Global_missile_firing_count--;
  2944.             }
  2945.  
  2946.             if (Global_missile_firing_count < 0)
  2947.                 Global_missile_firing_count = 0;
  2948.  
  2949.             //    Drop proximity bombs.
  2950.             if (Controls.drop_bomb_down_count) {
  2951.                 int    ssw_save = Secondary_weapon;
  2952.                 Secondary_weapon = PROXIMITY_INDEX;
  2953.                 while (Controls.drop_bomb_down_count--)
  2954.                     do_missile_firing();
  2955.                 Secondary_weapon = ssw_save;
  2956.             }
  2957.         }
  2958.  
  2959.         if (Player_exploded) { //Player_is_dead && (ConsoleObject->flags & OF_EXPLODING) ) {
  2960.             if (exploding_flag==0)    {
  2961.                 exploding_flag = 1;             // When player starts exploding, clear all input devices...
  2962.                 game_flush_inputs();
  2963.             } else {    
  2964.                 int i;
  2965.                 if (key_down_count(KEY_BACKSP))
  2966.                     Int3();
  2967.                 if (key_down_count(KEY_PRINT_SCREEN))
  2968.                     save_screen_shot(0);
  2969.                 for (i=0; i<4; i++ )    
  2970.                     if (joy_get_button_down_cnt(i)>0) Death_sequence_aborted = 1;
  2971.                 for (i=0; i<3; i++ )    
  2972.                     if (mouse_button_down_count(i)>0) Death_sequence_aborted = 1;
  2973.                 for (i=0; i<256; i++ )    
  2974.                     if (key_down_count(i)>0) Death_sequence_aborted = 1;
  2975.                 if (Death_sequence_aborted)
  2976.                     game_flush_inputs();
  2977.             }
  2978.         } else {
  2979.             exploding_flag=0;
  2980.         }
  2981.  
  2982.         if (Newdemo_state == ND_STATE_PLAYBACK )    {
  2983.             if ((keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) && keyd_pressed[KEY_RIGHT])
  2984.                 Newdemo_vcr_state = ND_STATE_FASTFORWARD;
  2985.             else if ((keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) && keyd_pressed[KEY_LEFT])
  2986.                 Newdemo_vcr_state = ND_STATE_REWINDING;
  2987.             else if (!(keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) && keyd_pressed[KEY_RIGHT] && ((timer_get_fixed_seconds() - newdemo_single_frame_time) >= F1_0))
  2988.                 Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD;
  2989.             else if (!(keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) && keyd_pressed[KEY_LEFT] && ((timer_get_fixed_seconds() - newdemo_single_frame_time) >= F1_0))
  2990.                 Newdemo_vcr_state = ND_STATE_ONEFRAMEBACKWARD;
  2991.             else if ((Newdemo_vcr_state == ND_STATE_FASTFORWARD) || (Newdemo_vcr_state == ND_STATE_REWINDING))
  2992.                 Newdemo_vcr_state = ND_STATE_PLAYBACK;
  2993.         }
  2994.  
  2995.         while ((key=key_inkey_time(&key_time)) != 0)    {
  2996.  
  2997.             john_cheat_func_1(key);
  2998.  
  2999.             #ifdef NETWORK
  3000.             if ( (Game_mode&GM_MULTI) && (multi_sending_message || multi_defining_message ))    {
  3001.                 multi_message_input_sub( key );
  3002.                 key = 0;        // Wipe out key!
  3003.             }
  3004.             #endif
  3005.  
  3006.             if (!(Game_mode&GM_MULTI) && key == cheat_enable_keys[cheat_enable_index]) {
  3007.                 if (++cheat_enable_index == CHEAT_ENABLE_LENGTH) {
  3008.                     HUD_init_message(TXT_CHEATS_ENABLED);
  3009.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3010.                     Cheats_enabled = 1;
  3011.                     Players[Player_num].score = 0;
  3012.                 }
  3013.             }
  3014.             else
  3015.                 cheat_enable_index = 0;
  3016.  
  3017.  
  3018.             john_cheat_func_2(key);
  3019.  
  3020. #ifdef FINAL_CHEATS
  3021.         if (Cheats_enabled) {
  3022.             if (!(Game_mode&GM_MULTI) && key == cheat_wowie[cheat_wowie_index]) {
  3023.                 if (++cheat_wowie_index == CHEAT_WOWIE_LENGTH) {
  3024.                     int i;
  3025.  
  3026.                     HUD_init_message(TXT_WOWIE_ZOWIE);
  3027.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3028.  
  3029.                     Players[Player_num].primary_weapon_flags |= 0xff ^ (HAS_PLASMA_FLAG | HAS_FUSION_FLAG);
  3030.                     Players[Player_num].secondary_weapon_flags |= 0xff ^ (HAS_SMART_FLAG | HAS_MEGA_FLAG);
  3031.  
  3032.                     for (i=0; i<3; i++)
  3033.                         Players[Player_num].primary_ammo[i] = Primary_ammo_max[i];
  3034.                     
  3035.                     for (i=0; i<3; i++)
  3036.                         Players[Player_num].secondary_ammo[i] = Secondary_ammo_max[i];
  3037.                     
  3038.                     if (Newdemo_state == ND_STATE_RECORDING)
  3039.                         newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
  3040.  
  3041.                     Players[Player_num].energy = MAX_ENERGY;
  3042.                     Players[Player_num].laser_level = MAX_LASER_LEVEL;
  3043.                     Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
  3044.                     update_laser_weapon_info();
  3045.  
  3046.                     cheat_wowie_index = 0;
  3047.                 }
  3048.             }
  3049.             else
  3050.                 cheat_wowie_index = 0;
  3051.  
  3052.             if (!(Game_mode&GM_MULTI) && key == (0xaa^new_cheats[cheat_wowie2_index*NUM_NEW_CHEATS+CHEAT_WOWIE2_OFS])) {
  3053.                 if (++cheat_wowie2_index == CHEAT_WOWIE2_LENGTH) {
  3054.                     int i;
  3055.  
  3056.                     HUD_init_message("SUPER %s",TXT_WOWIE_ZOWIE);
  3057.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3058.  
  3059.                     Players[Player_num].primary_weapon_flags = 0xff;
  3060.                     Players[Player_num].secondary_weapon_flags = 0xff;
  3061.  
  3062.                     for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
  3063.                         Players[Player_num].primary_ammo[i] = Primary_ammo_max[i];
  3064.                     
  3065.                     for (i=0; i<MAX_SECONDARY_WEAPONS; i++)
  3066.                         Players[Player_num].secondary_ammo[i] = Secondary_ammo_max[i];
  3067.                     
  3068.                     if (Newdemo_state == ND_STATE_RECORDING)
  3069.                         newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
  3070.  
  3071.                     Players[Player_num].energy = MAX_ENERGY;
  3072.                     Players[Player_num].laser_level = MAX_LASER_LEVEL;
  3073.                     Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
  3074.                     update_laser_weapon_info();
  3075.  
  3076.                     cheat_wowie2_index = 0;
  3077.                 }
  3078.             }
  3079.             else
  3080.                 cheat_wowie2_index = 0;
  3081.  
  3082.             if (!(Game_mode&GM_MULTI) && key == cheat_allkeys[cheat_allkeys_index]) {
  3083.                 if (++cheat_allkeys_index == CHEAT_ALLKEYS_LENGTH) {
  3084.                     HUD_init_message(TXT_ALL_KEYS);
  3085.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3086.                     Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  3087.  
  3088.                     cheat_allkeys_index = 0;
  3089.                 }
  3090.             }
  3091.             else
  3092.                 cheat_allkeys_index = 0;
  3093.  
  3094.  
  3095.             if (!(Game_mode&GM_MULTI) && key == cheat_invuln[cheat_invuln_index]) {
  3096.                 if (++cheat_invuln_index == CHEAT_INVULN_LENGTH) {
  3097.                     Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  3098.                     HUD_init_message("%s %s!", TXT_INVULNERABILITY, (Players[Player_num].flags&PLAYER_FLAGS_INVULNERABLE)?TXT_ON:TXT_OFF);
  3099.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3100.                     Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  3101.  
  3102.                     cheat_invuln_index = 0;
  3103.                 }
  3104.             }
  3105.             else
  3106.                 cheat_invuln_index = 0;
  3107.  
  3108.             if (!(Game_mode&GM_MULTI) && key == cheat_cloak[cheat_cloak_index]) {
  3109.                 if (++cheat_cloak_index == CHEAT_CLOAK_LENGTH) {
  3110.                     Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  3111.                     HUD_init_message("%s %s!", TXT_CLOAK, (Players[Player_num].flags&PLAYER_FLAGS_CLOAKED)?TXT_ON:TXT_OFF);
  3112.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3113.                     if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  3114.                         ai_do_cloak_stuff();
  3115.                         Players[Player_num].cloak_time = GameTime;
  3116.                     }
  3117.  
  3118.                     cheat_cloak_index = 0;
  3119.                 }
  3120.             }
  3121.             else
  3122.                 cheat_cloak_index = 0;
  3123.  
  3124.             if (!(Game_mode&GM_MULTI) && key == cheat_shield[cheat_shield_index]) {
  3125.                 if (++cheat_shield_index == CHEAT_SHIELD_LENGTH) {
  3126.                     HUD_init_message(TXT_FULL_SHIELDS);
  3127.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3128.                     Players[Player_num].shields = MAX_SHIELDS;
  3129.  
  3130.                     cheat_shield_index = 0;
  3131.                 }
  3132.             }
  3133.             else
  3134.                 cheat_shield_index = 0;
  3135.  
  3136.             if (!(Game_mode&GM_MULTI) && key == cheat_warp[cheat_warp_index]) {
  3137.                 if (++cheat_warp_index == CHEAT_WARP_LENGTH) {
  3138.                     newmenu_item m;
  3139.                     char text[10]="";
  3140.                     int new_level_num;
  3141.                     int item;
  3142.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3143.                     m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
  3144.                     item = newmenu_do( NULL, TXT_WARP_TO_LEVEL, 1, &m, NULL );
  3145.                     if (item != -1) {
  3146.                         new_level_num = atoi(m.text);
  3147.                         if (new_level_num!=0 && new_level_num>=0 && new_level_num<=Last_level)
  3148.                             StartNewLevel(new_level_num);
  3149.                     }
  3150.  
  3151.                     cheat_warp_index = 0;
  3152.                 }
  3153.             }
  3154.             else
  3155.                 cheat_warp_index = 0;
  3156.  
  3157.             if (!(Game_mode&GM_MULTI) && key == cheat_astral[cheat_astral_index]) {
  3158.                 if (++cheat_astral_index == CHEAT_ASTRAL_LENGTH) {
  3159.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3160.                     if ( Physics_cheat_flag==0xBADA55 )    {
  3161.                         Physics_cheat_flag = 0;
  3162.                     } else {
  3163.                         Physics_cheat_flag = 0xBADA55;
  3164.                     }
  3165.                     HUD_init_message("%s %s!", "Ghosty mode", Physics_cheat_flag==0xBADA55?TXT_ON:TXT_OFF);
  3166.                     cheat_astral_index = 0;
  3167.                 }
  3168.             }
  3169.             else
  3170.                 cheat_astral_index = 0;
  3171.  
  3172.             if (!(Game_mode&GM_MULTI) && key == (0xaa^new_cheats[cheat_turbomode_index*NUM_NEW_CHEATS+CHEAT_TURBOMODE_OFS])) {
  3173.                 if (++cheat_turbomode_index == CHEAT_TURBOMODE_LENGTH) {
  3174.                     Game_turbo_mode ^= 1;
  3175.                     HUD_init_message("%s %s!", "Turbo mode", Game_turbo_mode?TXT_ON:TXT_OFF);
  3176.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3177.                 }
  3178.             }
  3179.             else
  3180.                 cheat_turbomode_index = 0;
  3181.  
  3182.             if (!(Game_mode&GM_MULTI) && key == (0xaa^new_cheats[cheat_newlife_index*NUM_NEW_CHEATS+CHEAT_NEWLIFE_OFS])) {
  3183.                 if (++cheat_newlife_index == CHEAT_NEWLIFE_LENGTH) {
  3184.                     if (Players[Player_num].lives<50) {
  3185.                         Players[Player_num].lives++;
  3186.                         HUD_init_message("Extra life!");
  3187.                         digi_play_sample( SOUND_CHEATER, F1_0);
  3188.                     }
  3189.  
  3190.                     cheat_newlife_index = 0;
  3191.                 }
  3192.             }
  3193.             else
  3194.                 cheat_newlife_index = 0;
  3195.  
  3196.             if (!(Game_mode&GM_MULTI) && key == (0xaa^new_cheats[cheat_exitpath_index*NUM_NEW_CHEATS+CHEAT_EXITPATH_OFS])) {
  3197.                 if (++cheat_exitpath_index == CHEAT_EXITPATH_LENGTH) {
  3198.                     #ifdef SHOW_EXIT_PATH
  3199.                     if (create_special_path()) {
  3200.                         HUD_init_message("Exit path illuminated!");
  3201.                         digi_play_sample( SOUND_CHEATER, F1_0);
  3202.                     }
  3203.                     #endif
  3204.  
  3205.                     cheat_exitpath_index = 0;
  3206.                 }
  3207.             }
  3208.             else
  3209.                 cheat_exitpath_index = 0;
  3210.  
  3211.  
  3212.             if (!(Game_mode&GM_MULTI) && key == (0xaa^new_cheats[cheat_robotpause_index*NUM_NEW_CHEATS+CHEAT_ROBOTPAUSE_OFS])) {
  3213.                 if (++cheat_robotpause_index == CHEAT_ROBOTPAUSE_LENGTH) {
  3214.                     Robot_firing_enabled = !Robot_firing_enabled;
  3215.                     HUD_init_message("%s %s!", "Robot firing", Robot_firing_enabled?TXT_ON:TXT_OFF);
  3216.                     digi_play_sample( SOUND_CHEATER, F1_0);
  3217.  
  3218.                     cheat_robotpause_index = 0;
  3219.                 }
  3220.  
  3221.             }
  3222.             else
  3223.                 cheat_robotpause_index = 0;
  3224.  
  3225.  
  3226.         }
  3227. #endif
  3228.  
  3229.             john_cheat_func_3(key);
  3230.  
  3231.             #ifndef RELEASE
  3232.             #ifdef NETWORK
  3233.             if ((key&KEY_DEBUGGED)&&(Game_mode&GM_MULTI))    {
  3234.                 Network_message_reciever = 100;        // Send to everyone...
  3235.                 sprintf( Network_message, "%s %s", TXT_I_AM_A, TXT_CHEATER);
  3236.             }
  3237.             #endif
  3238.             #endif
  3239.     
  3240.             if (Endlevel_sequence) {
  3241.  
  3242.                   if (key==KEY_PRINT_SCREEN)
  3243.                     save_screen_shot(0);
  3244.  
  3245.                 if (key == KEY_PAUSE)
  3246.                     key = do_game_pause(0);        //so esc from pause will end level
  3247.  
  3248.                 if (key == KEY_ESC)    {
  3249.                     stop_endlevel_sequence();
  3250.                     last_drawn_cockpit[0]=-1;
  3251.                     last_drawn_cockpit[1]=-1;
  3252.                     return;
  3253.                 }
  3254.  
  3255.                 if (key == KEY_BACKSP)
  3256.                     Int3();
  3257.  
  3258.                 break;        //don't process any other keys
  3259.             }
  3260.  
  3261.             john_cheat_func_4(key);
  3262.  
  3263.             if (Player_is_dead) {
  3264.  
  3265.                   if (key==KEY_PRINT_SCREEN)
  3266.                     save_screen_shot(0);
  3267.  
  3268.                 if (key == KEY_PAUSE)    {
  3269.                     key = do_game_pause(0);        //so esc from pause will end level
  3270.                     Death_sequence_aborted  = 0;        // Clear because code above sets this for any key.
  3271.                 }
  3272.                     
  3273.                 if (key == KEY_ESC) {
  3274.                     if (ConsoleObject->flags & OF_EXPLODING)    
  3275.                         Death_sequence_aborted = 1;
  3276.                 }
  3277.  
  3278.                 if (key == KEY_BACKSP)    {
  3279.                     Death_sequence_aborted  = 0;        // Clear because code above sets this for any key.
  3280.                     Int3();
  3281.                 }
  3282.  
  3283.                 break;        //don't process any other keys
  3284.             }
  3285.  
  3286.             if (Newdemo_state == ND_STATE_PLAYBACK )    {
  3287.                 switch (key) {
  3288.  
  3289.                 case KEY_DEBUGGED + KEY_I:    
  3290.                     Newdemo_do_interpolate = !Newdemo_do_interpolate;
  3291.                     if (Newdemo_do_interpolate)
  3292.                         mprintf ((0, "demo playback interpolation now on\n"));
  3293.                     else
  3294.                         mprintf ((0, "demo playback interpolation now off\n"));
  3295.                     break;
  3296. #ifndef NDEBUG
  3297.                 case KEY_DEBUGGED + KEY_K: {
  3298.                     int how_many, c;
  3299.                     char filename[13], num[16];
  3300.                     newmenu_item m[6];
  3301.  
  3302.                     filename[0] = '\0';
  3303.                     m[ 0].type = NM_TYPE_TEXT; m[ 0].text = "output file name";
  3304.                     m[ 1].type = NM_TYPE_INPUT;m[ 1].text_len = 8; m[1].text = filename;
  3305.                     c = newmenu_do( NULL, NULL, 2, m, NULL );
  3306.                     if (c == -2)
  3307.                         break;
  3308.                     strcat(filename, ".dem");
  3309.                     num[0] = '\0';
  3310.                     m[ 0].type = NM_TYPE_TEXT; m[ 0].text = "strip how many bytes";
  3311.                     m[ 1].type = NM_TYPE_INPUT;m[ 1].text_len = 16; m[1].text = num;
  3312.                     c = newmenu_do( NULL, NULL, 2, m, NULL );
  3313.                     if (c == -2)
  3314.                         break;
  3315.                     how_many = atoi(num);
  3316.                     if (how_many <= 0)
  3317.                         break;
  3318.                     newdemo_strip_frames(filename, how_many);
  3319.                 }
  3320.                 break;
  3321. #endif
  3322.  
  3323.                 case KEY_F3:                toggle_cockpit();            break;
  3324.                 case KEY_SHIFTED+KEY_MINUS:
  3325.                 case KEY_MINUS:            shrink_window();            break;
  3326.                 case KEY_SHIFTED+KEY_EQUAL:
  3327.                 case KEY_EQUAL:            grow_window();                break;
  3328.                 case KEY_F2:                Config_menu_flag = 1;    break;
  3329.                 case KEY_F7:                
  3330.                     #ifdef NETWORK
  3331.                     Show_kill_list = (Show_kill_list+1) % ((Newdemo_game_mode & GM_TEAM) ? 3 : 2);
  3332.                     #endif
  3333.                     break;
  3334.                 case KEY_BACKSP:
  3335.                     Int3();
  3336.                     break;
  3337.                 case KEY_ESC:                 
  3338.                     Function_mode = FMODE_MENU;
  3339.                     break;
  3340.                 case KEY_UP:
  3341.                     Newdemo_vcr_state = ND_STATE_PLAYBACK;
  3342.                     break;
  3343.                 case KEY_DOWN:
  3344.                     Newdemo_vcr_state = ND_STATE_PAUSED;
  3345.                     break;
  3346.                 case KEY_LEFT:
  3347.                     newdemo_single_frame_time = timer_get_fixed_seconds();
  3348.                     Newdemo_vcr_state = ND_STATE_ONEFRAMEBACKWARD;
  3349.                     break;
  3350.                 case KEY_RIGHT:
  3351.                     newdemo_single_frame_time = timer_get_fixed_seconds();
  3352.                     Newdemo_vcr_state = ND_STATE_ONEFRAMEFORWARD;
  3353.                     break;
  3354.                 case KEY_CTRLED + KEY_RIGHT:
  3355.                     newdemo_goto_end();
  3356.                     break;
  3357.                 case KEY_CTRLED + KEY_LEFT:
  3358.                     newdemo_goto_beginning();
  3359.                     break;
  3360.                 case KEY_PAUSE:
  3361.                     do_game_pause(0);
  3362.                     break;
  3363.                   case KEY_PRINT_SCREEN: {
  3364.                     int old_state;
  3365.             
  3366.                     old_state = Newdemo_vcr_state;
  3367.                     Newdemo_vcr_state = ND_STATE_PRINTSCREEN;
  3368.                     game_render_frame_mono();
  3369.                      save_screen_shot(0);
  3370.                     Newdemo_vcr_state = old_state;
  3371.                     break;
  3372.                     }
  3373.                 }
  3374.                 break;
  3375.               }
  3376.  
  3377.  
  3378. #ifndef FINAL_CHEATS
  3379.             //Here are the "legal" cheats
  3380.             if (Cheats_enabled && !(Game_mode&GM_MULTI))
  3381.                 switch (key) {
  3382.                     case KEY_ALTED+KEY_1: {
  3383.                         int i;
  3384.  
  3385.                         HUD_init_message(TXT_WOWIE_ZOWIE);
  3386.  
  3387.                         #ifndef SHAREWARE
  3388.                             Players[Player_num].primary_weapon_flags = 0xff;
  3389.                             Players[Player_num].secondary_weapon_flags = 0xff;
  3390.                         #else
  3391.                             Players[Player_num].primary_weapon_flags = 0xff ^ (HAS_PLASMA_FLAG | HAS_FUSION_FLAG);
  3392.                             Players[Player_num].secondary_weapon_flags = 0xff ^ (HAS_SMART_FLAG | HAS_MEGA_FLAG);
  3393.                         #endif
  3394.  
  3395.                         for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
  3396.                             Players[Player_num].primary_ammo[i] = Primary_ammo_max[i];
  3397.                         
  3398.                         for (i=0; i<MAX_SECONDARY_WEAPONS; i++)
  3399.                             Players[Player_num].secondary_ammo[i] = Secondary_ammo_max[i];
  3400.                         
  3401.                         if (Newdemo_state == ND_STATE_RECORDING)
  3402.                             newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
  3403.  
  3404.                         Players[Player_num].energy = MAX_ENERGY;
  3405.                         Players[Player_num].laser_level = MAX_LASER_LEVEL;
  3406.                         Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
  3407.                         update_laser_weapon_info();
  3408.  
  3409.                         break;
  3410.                     }
  3411.     
  3412.                     case KEY_ALTED+KEY_2:
  3413.                         HUD_init_message(TXT_ALL_KEYS);
  3414.                         Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY;
  3415.                         break;
  3416.     
  3417.                     case KEY_ALTED+KEY_3:
  3418.                         Players[Player_num].flags ^= PLAYER_FLAGS_INVULNERABLE;
  3419.                         HUD_init_message("%s %s!", TXT_INVULNERABILITY, (Players[Player_num].flags&PLAYER_FLAGS_INVULNERABLE)?TXT_ON:TXT_OFF);
  3420.                         Players[Player_num].invulnerable_time = GameTime+i2f(1000);
  3421.                         break;
  3422.     
  3423.                     case KEY_ALTED+KEY_4:
  3424.                         Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  3425.                         HUD_init_message("%s %s!", TXT_CLOAK, (Players[Player_num].flags&PLAYER_FLAGS_CLOAKED)?TXT_ON:TXT_OFF);
  3426.                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  3427.                             ai_do_cloak_stuff();
  3428.                             Players[Player_num].cloak_time = GameTime;
  3429.                         }
  3430.                         break;
  3431.  
  3432.                     case KEY_ALTED+KEY_5:
  3433.                         HUD_init_message(TXT_FULL_SHIELDS);
  3434.                         Players[Player_num].shields = MAX_SHIELDS;
  3435.                         break;
  3436.  
  3437.                     case KEY_ALTED+KEY_6: {
  3438.                         newmenu_item m;
  3439.                         char text[10]="";
  3440.                         int new_level_num;
  3441.                         int item;
  3442.                         m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
  3443.                         item = newmenu_do( NULL, TXT_WARP_TO_LEVEL, 1, &m, NULL );
  3444.                         if (item != -1) {
  3445.                             new_level_num = atoi(m.text);
  3446.                             if (new_level_num!=0 && new_level_num>=0 && new_level_num<=LAST_LEVEL)
  3447.                                 StartNewLevel(new_level_num);
  3448.                         }
  3449.                         break;
  3450.  
  3451.                     }
  3452.                 }
  3453. #endif
  3454.  
  3455.             //--killed--Players[Player_num].flags &= ~PLAYER_FLAGS_AFTERBURNER;    //    Turn off, keypress might turn it on.
  3456.  
  3457.             switch (key) {
  3458.  
  3459.                 //    ================================================================================================
  3460.                 //FIRST ARE ALL THE REAL GAME KEYS.  PUT TEST AND DEBUG KEYS LATER.
  3461.  
  3462.                 //--killed--case KEY_SHIFTED+KEY_A:    toggle_afterburner_status();    break;
  3463.                 case KEY_ESC:
  3464.                     Game_aborted=1;
  3465.                     Function_mode = FMODE_MENU;
  3466.                     break;
  3467.                 case KEY_F1:                 do_show_help();            break;
  3468.                 case KEY_F2:                Config_menu_flag = 1;    break;
  3469.                 case KEY_F3:                toggle_cockpit();            break;
  3470.                 case KEY_F4:                palette_save(); joydefs_calibrate(); palette_restore(); break;
  3471.                 case KEY_F5:    
  3472.                         if ( Newdemo_state == ND_STATE_RECORDING )
  3473.                             newdemo_stop_recording();
  3474.                         else if ( Newdemo_state == ND_STATE_NORMAL )            
  3475.                             newdemo_start_recording();
  3476.                         break;
  3477.                 case KEY_F6:                
  3478.                     #ifdef NETWORK
  3479.                     Show_reticle_name = (Show_reticle_name+1)%2;
  3480.                     #endif
  3481.                     break;    
  3482.                 case KEY_F7:                
  3483.                     #ifdef NETWORK
  3484.                     Show_kill_list = (Show_kill_list+1) % ((Game_mode & GM_TEAM) ? 3 : 2);
  3485.                     #endif
  3486.                     break;
  3487.                 case KEY_F8:    
  3488.                     #ifdef NETWORK
  3489.                     multi_send_message_start();
  3490.                     #endif
  3491.                     break;
  3492.                 case KEY_F9:
  3493.                 case KEY_F10:
  3494.                 case KEY_F11:
  3495.                 case KEY_F12:
  3496.                     #ifdef NETWORK
  3497.                     multi_send_macro(key);
  3498.                     #endif
  3499.                     break;        // send taunt macros
  3500.     
  3501.                 case KEY_ALTED + KEY_F9:
  3502.                     #ifdef NETWORK
  3503.                     multi_send_audio_taunt(0);
  3504.                     #endif
  3505.                     break;
  3506.                 case KEY_ALTED + KEY_F10:
  3507.                     #ifdef NETWORK
  3508.                     multi_send_audio_taunt(1);
  3509.                     #endif
  3510.                     break;
  3511.                 case KEY_ALTED + KEY_F11:
  3512.                     #ifdef NETWORK
  3513.                     multi_send_audio_taunt(2);
  3514.                     #endif
  3515.                     break;
  3516.                 case KEY_ALTED + KEY_F12:
  3517.                     #ifdef NETWORK
  3518.                     multi_send_audio_taunt(3);
  3519.                     #endif
  3520.                     break;
  3521.  
  3522.                 case KEY_SHIFTED + KEY_F9:
  3523.                 case KEY_SHIFTED + KEY_F10:
  3524.                 case KEY_SHIFTED + KEY_F11:
  3525.                 case KEY_SHIFTED + KEY_F12:
  3526.                     #ifdef NETWORK
  3527.                     multi_define_macro(key);
  3528.                     #endif
  3529.                     break;        // redefine taunt macros
  3530.  
  3531.                 case KEY_PAUSE:            do_game_pause(1);         break;
  3532.                   case KEY_PRINT_SCREEN:     save_screen_shot(0);        break;
  3533.  
  3534.                 case KEY_SHIFTED+KEY_MINUS:
  3535.                 case KEY_MINUS:            shrink_window();            break;
  3536.                 case KEY_SHIFTED+KEY_EQUAL:
  3537.                 case KEY_EQUAL:            grow_window();                break;
  3538.  
  3539.                 //    Select primary or secondary weapon.
  3540.                 case KEY_1:
  3541.                 case KEY_2:
  3542.                 case KEY_3:
  3543.                 case KEY_4:
  3544.                 case KEY_5:
  3545.  
  3546.                     do_weapon_select(key - KEY_1 , 0);
  3547.                     break;
  3548.  
  3549.                 case KEY_6:
  3550.                 case KEY_7:
  3551.                 case KEY_8:
  3552.                 case KEY_9:
  3553.                 case KEY_0:
  3554.  
  3555.                     do_weapon_select(key - KEY_6 , 1);
  3556.                     break;
  3557.  
  3558.                 case KEY_SHIFTED + KEY_ESC: //quick exit
  3559.                     #ifdef EDITOR
  3560.                         if (! SafetyCheck()) break;
  3561.                         close_editor_screen();
  3562.                     #endif
  3563.  
  3564.                     Game_aborted=1;
  3565.                     Function_mode=FMODE_EXIT;
  3566.                     break;
  3567.  
  3568. #ifdef SHAREWARE
  3569.                 case KEY_ALTED+KEY_F2:
  3570.                 case KEY_ALTED+KEY_F3:
  3571.                     HUD_init_message( TXT_ONLY_REGISTERED );
  3572.                     digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  3573.                     break;
  3574. #else
  3575.                 case KEY_ALTED+KEY_F2:    state_save_all( 0 );        break;    // 0 means not between levels.
  3576.                 case KEY_ALTED+KEY_F3:    state_restore_all(1);        break;
  3577. #endif
  3578.  
  3579.                 case KEY_SHIFTED+KEY_Z:
  3580.                     kconfig_center_headset();
  3581.                     break;
  3582.  
  3583.  
  3584.                 case KEY_V + KEY_ALTED:     // changes 11/9/95
  3585.                     if ( Game_victor_flag )        {
  3586.                         victor_init_graphics();
  3587.                         HUD_init_message( "Victor mode toggled" );
  3588.                     }
  3589.                     break;
  3590.  
  3591.                     // changes 11/9/95, 11/10/95
  3592.                 case KEY_SHIFTED+KEY_F5:  
  3593.                     if ( Game_victor_flag )        {
  3594.                         victor_init_graphics();
  3595.                         HUD_init_message( "Victor mode toggled" );
  3596.                     } else if ( VR_render_mode != VR_NONE )    {
  3597.                         simuleyes_offset_ratio = VR_DEFAULT_OFFSET_RATIO;
  3598.                         simuleyes_adjusted_offset_ratio = fixdiv (simuleyes_offset_ratio *
  3599.                                 VR_PIXEL_SHIFT, VR_SEPARATION);
  3600.                         VR_eye_width        = VR_SEPARATION;
  3601.                         VR_eye_offset = VR_PIXEL_SHIFT;
  3602.                         VR_eye_offset_changed = 2;
  3603.                         HUD_init_message( "Stereo parameters reset");
  3604.                     }
  3605.                     break;
  3606.  
  3607.                 case KEY_SHIFTED+KEY_F6:
  3608.                         if ( VR_render_mode != VR_NONE )    {
  3609.                             if (Game_simuleyes_flag)    {
  3610.                                 vr_reset_display();
  3611.                             } else {
  3612.                                 VR_low_res++;
  3613.                                 if ( VR_low_res > 3 ) VR_low_res = 0;
  3614.                                 switch( VR_low_res )    {
  3615.                                     case 0: HUD_init_message( "High Res" ); break;
  3616.                                     case 1: HUD_init_message( "Low V.Res" ); break;
  3617.                                     case 2: HUD_init_message( "Low H.Res" ); break;
  3618.                                     case 3: HUD_init_message( "Low Res" ); break;
  3619.                                 }
  3620.                             }
  3621.                         }
  3622.                     break;
  3623.  
  3624.                 case KEY_SHIFTED+KEY_F7:
  3625.                     if (!Game_simuleyes_flag)    {  // constraint added
  3626.                         if ( VR_render_mode != VR_NONE )    {
  3627.                             VR_switch_eyes = !VR_switch_eyes;
  3628.                             if ( VR_switch_eyes )
  3629.                                 HUD_init_message( "Right Eye -- Left Eye" );
  3630.                             else
  3631.                                 HUD_init_message( "Left Eye -- Right Eye" );
  3632.                         }
  3633.                     }
  3634.                     break;
  3635.  
  3636.                 case KEY_SHIFTED+KEY_F8:
  3637.                     if (!Game_simuleyes_flag)    {  // constraint added
  3638.                         VR_sensitivity++;
  3639.                         if (VR_sensitivity > 2 )
  3640.                             VR_sensitivity = 0;
  3641.                         HUD_init_message( "Head tracking sensitivy = %d", VR_sensitivity );
  3642.                     }
  3643.                     break;
  3644.  
  3645.                 case KEY_SHIFTED+KEY_ENTER:
  3646.                     if ( VR_render_mode != VR_NONE )    {
  3647.                         VR_show_hud = !VR_show_hud;
  3648.                     }
  3649.                     break;
  3650.  
  3651.                 case KEY_SHIFTED+KEY_F1:   // altered 11/9/95, 11/10/95
  3652.                         simuleyes_offset_ratio = fixdiv (simuleyes_offset_ratio,
  3653.                                 VR_ADJUST_OFFSET_RATIO);
  3654.                         if (simuleyes_offset_ratio <    VR_MIN_OFFSET_RATIO)
  3655.                             simuleyes_offset_ratio = VR_MIN_OFFSET_RATIO;
  3656.                         simuleyes_adjusted_offset_ratio = fixdiv (simuleyes_offset_ratio *
  3657.                                 VR_PIXEL_SHIFT, VR_SEPARATION);
  3658.                         VR_eye_offset = (int) ((fixmul (simuleyes_adjusted_offset_ratio,
  3659.                                 VR_eye_width) - F1_0/2) / F1_0);
  3660.                         HUD_init_message( "Stereoscopic balance = %.1f",
  3661.                                 f2fl(simuleyes_offset_ratio)*10);
  3662.                     VR_eye_offset_changed = 2;
  3663.                     break;
  3664.                 case KEY_SHIFTED+KEY_F2:   // altered 11/9/95, 11/10/95
  3665.                         simuleyes_offset_ratio = fixmul (simuleyes_offset_ratio,
  3666.                                 VR_ADJUST_OFFSET_RATIO);
  3667.                         if (simuleyes_offset_ratio > VR_MAX_OFFSET_RATIO)
  3668.                             simuleyes_offset_ratio = VR_MAX_OFFSET_RATIO;
  3669.                         simuleyes_adjusted_offset_ratio = fixdiv (simuleyes_offset_ratio *
  3670.                                 VR_PIXEL_SHIFT, VR_SEPARATION);
  3671.                         VR_eye_offset = (int) ((fixmul (simuleyes_adjusted_offset_ratio,
  3672.                                 VR_eye_width) - F1_0/2) / F1_0);
  3673.                         HUD_init_message( "Stereoscopic balance = %.1f",
  3674.                                 f2fl(simuleyes_offset_ratio)*10);
  3675.                     VR_eye_offset_changed = 2;
  3676.                     break;
  3677.                 case KEY_SHIFTED+KEY_F3:
  3678.                         VR_eye_width = VR_eye_width * 10 / 11;
  3679.                         if ( VR_eye_width < VR_MIN_SEPARATION )
  3680.                             VR_eye_width = VR_MIN_SEPARATION;
  3681.                         VR_eye_offset = (int) ((fixmul (simuleyes_adjusted_offset_ratio,
  3682.                                 VR_eye_width) - F1_0/2) / F1_0);
  3683.                         VR_eye_offset_changed = 2;
  3684.                         HUD_init_message( "Stereo separation = %.1f", f2fl(VR_eye_width)*10);
  3685.                     break;
  3686.                 case KEY_SHIFTED+KEY_F4:
  3687.                         VR_eye_width = VR_eye_width * 11 / 10;
  3688.                         if ( VR_eye_width > VR_MAX_SEPARATION )
  3689.                             VR_eye_width = VR_MAX_SEPARATION; //11/10/95
  3690.                         VR_eye_offset = (int) ((fixmul (simuleyes_adjusted_offset_ratio,
  3691.                                 VR_eye_width) - F1_0/2) / F1_0);
  3692.                         VR_eye_offset_changed = 2;
  3693.                         HUD_init_message( "Stereo separation = %.1f", f2fl(VR_eye_width)*10);
  3694.                     break;
  3695.  
  3696.  
  3697.  
  3698.                 //use function keys for window sizing
  3699.  
  3700.                 //    ================================================================================================
  3701.                 //ALL KEYS BELOW HERE GO AWAY IN RELEASE VERSION
  3702.  
  3703.             #ifndef RELEASE
  3704.     
  3705.                 case KEY_DEBUGGED+KEY_0:    show_weapon_status();    break;
  3706.  
  3707.                 #ifdef SHOW_EXIT_PATH
  3708.                 case KEY_DEBUGGED+KEY_1:    create_special_path();    break;
  3709.                 #endif
  3710.  
  3711.                 case KEY_DEBUGGED+KEY_Y:
  3712.                     do_controlcen_destroyed_stuff(NULL);
  3713.                     break;
  3714.  
  3715.                 case KEY_BACKSP:
  3716.                 case KEY_CTRLED+KEY_BACKSP:
  3717.                 case KEY_ALTED+KEY_BACKSP:
  3718.                 case KEY_SHIFTED+KEY_BACKSP:
  3719.                 case KEY_SHIFTED+KEY_ALTED+KEY_BACKSP:
  3720.                 case KEY_CTRLED+KEY_ALTED+KEY_BACKSP:
  3721.                 case KEY_SHIFTED+KEY_CTRLED+KEY_BACKSP:
  3722.                 case KEY_SHIFTED+KEY_CTRLED+KEY_ALTED+KEY_BACKSP:
  3723.  
  3724.                          Int3(); break;
  3725.  
  3726.                 case KEY_DEBUGGED+KEY_S:            digi_reset(); break;
  3727.  
  3728.                 case KEY_DEBUGGED+KEY_P:
  3729.                      if (Game_suspended & SUSP_ROBOTS)
  3730.                          Game_suspended &= ~SUSP_ROBOTS;         //robots move
  3731.                      else
  3732.                          Game_suspended |= SUSP_ROBOTS;          //robots don't move
  3733.                     break;
  3734.     
  3735.  
  3736.     
  3737.                 case KEY_DEBUGGED+KEY_K:    Players[Player_num].shields = 1;    break;                        //    a virtual kill
  3738.                 case KEY_DEBUGGED+KEY_SHIFTED + KEY_K:    Players[Player_num].shields = -1;    break;    //    an actual kill
  3739.                 case KEY_DEBUGGED+KEY_X: Players[Player_num].lives++; break; // Extra life cheat key.
  3740.                 case KEY_DEBUGGED+KEY_H:
  3741. //                    if (!(Game_mode & GM_MULTI) )    {
  3742.                         Players[Player_num].flags ^= PLAYER_FLAGS_CLOAKED;
  3743.                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  3744.                             #ifdef NETWORK
  3745.                             if (Game_mode & GM_MULTI)
  3746.                                 multi_send_cloak();
  3747.                             #endif
  3748.                             ai_do_cloak_stuff();
  3749.                             Players[Player_num].cloak_time = GameTime;
  3750.                             mprintf((0, "You are cloaked!\n"));
  3751.                         } else
  3752.                             mprintf((0, "You are DE-cloaked!\n"));
  3753. //                    }
  3754.                     break;
  3755.  
  3756.  
  3757.                 case KEY_DEBUGGED+KEY_R:
  3758.                     Robot_firing_enabled = !Robot_firing_enabled;
  3759.                     break;
  3760.  
  3761.                 #ifdef EDITOR        //editor-specific functions
  3762.  
  3763.                     case KEY_E + KEY_DEBUGGED:
  3764.                             network_leave_game();
  3765.                             Function_mode = FMODE_EDITOR; 
  3766.                             break;
  3767.     
  3768.                     case KEY_C + KEY_SHIFTED + KEY_DEBUGGED: 
  3769.                         if (!( Game_mode & GM_MULTI ))
  3770.                             move_player_2_segment(Cursegp,Curside); 
  3771.                         break;   //move eye to curseg
  3772.  
  3773.     
  3774.                     case KEY_DEBUGGED+KEY_W:    draw_world_from_game();    break;
  3775.  
  3776.                 #endif    //#ifdef EDITOR
  3777.     
  3778.                 //flythrough keys
  3779.                 // case KEY_DEBUGGED+KEY_SHIFTED+KEY_F:    toggle_flythrough(); break;
  3780.                 // case KEY_LEFT:          ft_preference=FP_LEFT; break;
  3781.                 // case KEY_RIGHT:             ft_preference=FP_RIGHT; break;
  3782.                 // case KEY_UP:            ft_preference=FP_UP; break;
  3783.                 // case KEY_DOWN:          ft_preference=FP_DOWN; break;
  3784.     
  3785.                 case KEY_DEBUGGED+KEY_LAPOSTRO: Show_view_text_timer = 0x30000; object_goto_next_viewer(); break;
  3786.                 case KEY_DEBUGGED+KEY_SHIFTED+KEY_LAPOSTRO: Viewer=ConsoleObject; break;
  3787.     
  3788. #ifndef NDEBUG
  3789.                   case KEY_DEBUGGED+KEY_O: toggle_outline_mode(); break;
  3790. #endif
  3791.                   case KEY_DEBUGGED+KEY_T:
  3792.                     *Toggle_var = !*Toggle_var;
  3793.                     mprintf((0, "Variable at %08x set to %i\n", Toggle_var, *Toggle_var));
  3794.                     break;
  3795.                   case KEY_DEBUGGED + KEY_L: 
  3796.                     if (++Lighting_on >= 2) Lighting_on = 0; break;
  3797.                   case KEY_DEBUGGED + KEY_SHIFTED + KEY_L: 
  3798.                     Beam_brightness=0x38000-Beam_brightness; break;
  3799.                   case KEY_PAD5: slew_stop(); break;
  3800.     
  3801.                   case KEY_DEBUGGED + KEY_F11: play_test_sound(); break;
  3802.                   case KEY_DEBUGGED + KEY_SHIFTED+KEY_F11: advance_sound(); play_test_sound(); break;
  3803.  
  3804.                 case KEY_DEBUGGED +KEY_F4: {
  3805.                     //fvi_info hit_data;
  3806.                     //vms_vector p0 = {-0x1d99a7,-0x1b20000,0x186ab7f};
  3807.                     //vms_vector p1 = {-0x217865,-0x1b20000,0x187de3e};
  3808.                     //find_vector_intersection(&hit_data,&p0,0x1b9,&p1,0x40000,0x0,NULL,-1);
  3809.                     break;
  3810.                 }
  3811.     
  3812.                 case KEY_DEBUGGED + KEY_M:
  3813.                     Debug_spew = !Debug_spew;
  3814.                     if (Debug_spew) {
  3815.                         mopen( 0, 8, 1, 78, 16, "Debug Spew");
  3816.                         HUD_init_message( "Debug Spew: ON" );
  3817.                     } else {
  3818.                         mclose( 0 );
  3819.                         HUD_init_message( "Debug Spew: OFF" );
  3820.                     }
  3821.                     break;        
  3822.     
  3823.                 case KEY_DEBUGGED + KEY_C:    
  3824.  
  3825.                         do_cheat_menu(); 
  3826.                         break;
  3827.                 case KEY_DEBUGGED + KEY_SHIFTED + KEY_A:
  3828.                         do_megawow_powerup(10);
  3829.                         break;
  3830.                 case KEY_DEBUGGED + KEY_A:    {
  3831.                         do_megawow_powerup(200);
  3832. //                        if ( Game_mode & GM_MULTI )    {
  3833. //                            nm_messagebox( NULL, 1, "Damn", "CHEATER!\nYou cannot use the\nmega-thing in network mode." );
  3834. //                            Network_message_reciever = 100;        // Send to everyone...
  3835. //                            sprintf( Network_message, "%s cheated!", Players[Player_num].callsign);
  3836. //                        } else {
  3837. //                            do_megawow_powerup();
  3838. //                        }
  3839.                         break;
  3840.                 }
  3841.     
  3842.                  case KEY_DEBUGGED+KEY_F:    framerate_on = !framerate_on; break;
  3843.      
  3844.                  case KEY_DEBUGGED+KEY_SPACEBAR:              //KEY_F7:                       // Toggle physics flying
  3845.                      slew_stop();
  3846.                     game_flush_inputs();
  3847.                      if ( ConsoleObject->control_type != CT_FLYING ) {
  3848.                          fly_init(ConsoleObject);
  3849.                          Game_suspended &= ~SUSP_ROBOTS;         //robots move
  3850.                      } else {
  3851.                          slew_init(ConsoleObject);                                              //start player slewing
  3852.                          Game_suspended |= SUSP_ROBOTS;          //robots don't move
  3853.                     }
  3854.                     break;
  3855.         
  3856.                 case KEY_DEBUGGED+KEY_COMMA: Render_zoom = fixmul(Render_zoom,62259); break;
  3857.                 case KEY_DEBUGGED+KEY_PERIOD: Render_zoom = fixmul(Render_zoom,68985); break;
  3858.     
  3859.                 case KEY_DEBUGGED+KEY_P+KEY_SHIFTED: Debug_pause = 1; break;
  3860.     
  3861.                 //case KEY_F7: {
  3862.                 //    char mystr[30];
  3863.                 //    sprintf(mystr,"mark %i start",Mark_count);
  3864.                 //    _MARK_(mystr);
  3865.                 //    break;
  3866.                 //}
  3867.                 //case KEY_SHIFTED+KEY_F7: {
  3868.                 //    char mystr[30];
  3869.                 //    sprintf(mystr,"mark %i end",Mark_count);
  3870.                 //    Mark_count++;
  3871.                 //    _MARK_(mystr);
  3872.                 //    break;
  3873.                 //}
  3874.     
  3875.         
  3876. #ifndef NDEBUG
  3877.                 case KEY_DEBUGGED+KEY_F8: speedtest_init(); Speedtest_count = 1;    break;
  3878.                 case KEY_DEBUGGED+KEY_F9: speedtest_init(); Speedtest_count = 10;    break;
  3879.  
  3880.                 case KEY_DEBUGGED+KEY_D:
  3881.                     if ((Game_double_buffer = !Game_double_buffer)!=0)
  3882.                         init_cockpit();
  3883.                     break;
  3884. #endif
  3885.  
  3886. #ifdef EDITOR
  3887.                 case KEY_DEBUGGED+KEY_Q:
  3888.                     stop_time();
  3889.                     dump_used_textures_all();
  3890.                     start_time();
  3891.                     break;
  3892. #endif
  3893.  
  3894.                 #endif        //#ifndef RELEASE
  3895.  
  3896.                 default:        break;
  3897.  
  3898.             }       //switch (key)
  3899.         }
  3900. }
  3901.  
  3902.  
  3903. void vr_reset_display()
  3904. {
  3905.     if (VR_render_mode == VR_NONE ) return;
  3906.  
  3907.     if (VR_screen_mode == SCREEN_MENU)    // low res 320x200 (overall) mode
  3908.         gr_set_mode( SM_320x400U );
  3909.     set_screen_mode (SCREEN_MENU);
  3910.     set_screen_mode (SCREEN_GAME);
  3911. }
  3912.  
  3913.  
  3914. #ifndef    NDEBUG
  3915. int    Debug_slowdown=0;
  3916. #endif
  3917.  
  3918. #ifdef EDITOR
  3919. extern void player_follow_path(object *objp);
  3920. extern void check_create_player_path(void);
  3921.  
  3922. #endif
  3923.  
  3924. extern    int    Do_appearance_effect;
  3925.  
  3926.  
  3927.  
  3928. void GameLoop(int RenderFlag, int ReadControlsFlag )
  3929. {
  3930.     static int desc_dead_countdown=100;   /*  used if player shouldn't be playing */
  3931.  
  3932. #ifndef    NDEBUG
  3933.     //    Used to slow down frame rate for testing things.
  3934. //    RenderFlag = 1; // DEBUG
  3935.     if (Debug_slowdown) {
  3936.         int    h, i, j=0;
  3937.  
  3938.         for (h=0; h<Debug_slowdown; h++)
  3939.             for (i=0; i<1000; i++)
  3940.                 j += i;
  3941.     }
  3942. #endif
  3943.  
  3944.         if (desc_id_exit_num) {                 // are we supposed to be checking
  3945.             if (!(--desc_dead_countdown))  // if so, at zero, then pull the plug
  3946.                 Error ("Loading overlay -- error number: %d\n", (int)desc_id_exit_num);
  3947.         }
  3948.                 
  3949.         #ifndef RELEASE
  3950.         if (FindArg("-invulnerability"))
  3951.             Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
  3952.         #endif
  3953.  
  3954.         update_player_stats();
  3955.         diminish_palette_towards_normal();        //    Should leave palette effect up for as long as possible by putting right before render.
  3956.         //--killed--do_afterburner_stuff();
  3957.         do_cloak_stuff();
  3958.         do_invulnerable_stuff();
  3959.         remove_obsolete_stuck_objects();
  3960. #ifdef EDITOR
  3961. check_create_player_path();
  3962. player_follow_path(ConsoleObject);
  3963. #endif
  3964.         #ifdef NETWORK
  3965.         if (Game_mode & GM_MULTI)
  3966.             multi_do_frame();
  3967.         #endif
  3968.  
  3969.         if (RenderFlag) {
  3970.             if (force_cockpit_redraw) {            //screen need redrawing?
  3971.                 init_cockpit();
  3972.                 force_cockpit_redraw=0;
  3973.             }
  3974.             game_render_frame();
  3975.         }
  3976.  
  3977. //        mprintf(0,"Velocity %2.2f\n", f2fl(vm_vec_mag(&ConsoleObject->phys_info.velocity)));
  3978.  
  3979. #if 0
  3980. mem_fill();
  3981. mem_check();
  3982. #endif
  3983.  
  3984.         calc_frame_time();
  3985.  
  3986.         dead_player_frame();
  3987.         if (Newdemo_state != ND_STATE_PLAYBACK)
  3988.             do_controlcen_dead_frame();
  3989.  
  3990.         if (ReadControlsFlag)
  3991.             ReadControls();
  3992.         else
  3993.             memset(&Controls, 0, sizeof(Controls));
  3994.  
  3995.         GameTime += FrameTime;
  3996.  
  3997.         digi_sync_sounds();
  3998.  
  3999.         if (Endlevel_sequence) {
  4000.             do_endlevel_frame();
  4001.             powerup_grab_cheat_all();
  4002.             do_special_effects();
  4003.             return;                    //skip everything else
  4004.         }
  4005.  
  4006.         #ifdef ARCADE
  4007.         if (Arcade_mode && (Arcade_timer<0) && (Newdemo_state != ND_STATE_PLAYBACK) )    {
  4008.             memset( &Controls, 0, sizeof(Controls) );
  4009.             continue;
  4010.         }
  4011.         #endif
  4012.  
  4013.         if (Newdemo_state != ND_STATE_PLAYBACK)
  4014.             do_exploding_wall_frame();
  4015.         if ((Newdemo_state != ND_STATE_PLAYBACK) || (Newdemo_vcr_state != ND_STATE_PAUSED)) {
  4016.             do_special_effects();
  4017.             wall_frame_process();
  4018.             triggers_frame_process();
  4019.         }
  4020.  
  4021.  
  4022.         if (Fuelcen_control_center_destroyed)    {
  4023.             if (Newdemo_state==ND_STATE_RECORDING )
  4024.                 newdemo_record_control_center_destroyed();
  4025.             flash_frame();
  4026.         }
  4027.         
  4028.         if ( Newdemo_state == ND_STATE_PLAYBACK )    {
  4029.             newdemo_playback_one_frame();
  4030.             if ( Newdemo_state != ND_STATE_PLAYBACK )        {
  4031.                 longjmp( LeaveGame, 0 );        // Go back to menu
  4032.             }
  4033.         } else    
  4034.         { // Note the link to above!
  4035.  
  4036.             Players[Player_num].homing_object_dist = -1;        //    Assume not being tracked.  Laser_do_weapon_sequence modifies this.
  4037.  
  4038.             object_move_all();    
  4039.             powerup_grab_cheat_all();
  4040.  
  4041.             if (Endlevel_sequence)    //might have been started during move
  4042.                 return;
  4043.  
  4044.             fuelcen_update_all();
  4045.  
  4046.             do_ai_frame_all();
  4047.  
  4048.             if (allowed_to_fire_laser()) {
  4049.                 Global_laser_firing_count += Weapon_info[Primary_weapon_to_weapon_info[Primary_weapon]].fire_count * (Controls.fire_primary_state || Controls.fire_primary_down_count);
  4050.                 if ((Primary_weapon == FUSION_INDEX) && (Global_laser_firing_count)) {
  4051.                     if ((Players[Player_num].energy < F1_0*2) && (Auto_fire_fusion_cannon_time == 0)) {
  4052.                         Global_laser_firing_count = 0;
  4053.                     } else {
  4054.                         if (Fusion_charge == 0)
  4055.                             Players[Player_num].energy -= F1_0*2;
  4056.  
  4057.                         Fusion_charge += FrameTime;
  4058.                         Players[Player_num].energy -= FrameTime;
  4059.  
  4060.                         if (Players[Player_num].energy <= 0) {
  4061.                             Players[Player_num].energy = 0;
  4062.                             Auto_fire_fusion_cannon_time = GameTime -1;                //    Fire now!
  4063.                         } else
  4064.                             Auto_fire_fusion_cannon_time = GameTime + FrameTime/2 + 1;        //    Fire the fusion cannon at this time in the future.
  4065.  
  4066.                         if (Fusion_charge < F1_0*2)
  4067.                             PALETTE_FLASH_ADD(Fusion_charge >> 11, 0, Fusion_charge >> 11);
  4068.                         else
  4069.                             PALETTE_FLASH_ADD(Fusion_charge >> 11, Fusion_charge >> 11, 0);
  4070.  
  4071.                         if (Fusion_next_sound_time < GameTime) {
  4072.                             if (Fusion_charge > F1_0*2) {
  4073.                                 digi_play_sample( 11, F1_0 );
  4074.                                 apply_damage_to_player(ConsoleObject, ConsoleObject, rand() * 4);
  4075.                             } else {
  4076.                                 create_awareness_event(ConsoleObject, PA_WEAPON_ROBOT_COLLISION);
  4077.                                 digi_play_sample( SOUND_FUSION_WARMUP, F1_0 );
  4078.                                 #ifdef NETWORK
  4079.                                 if (Game_mode & GM_MULTI)
  4080.                                     multi_send_play_sound(SOUND_FUSION_WARMUP, F1_0);
  4081.                                 #endif
  4082.                             }
  4083.                             Fusion_next_sound_time = GameTime + F1_0/8 + rand()/4;
  4084.                         }
  4085.                     }
  4086.                 }
  4087.             }
  4088.  
  4089.             if (Auto_fire_fusion_cannon_time) {
  4090.                 if (Primary_weapon != FUSION_INDEX)
  4091.                     Auto_fire_fusion_cannon_time = 0;
  4092.                 else if (GameTime + FrameTime/2 >= Auto_fire_fusion_cannon_time) {
  4093.                     Auto_fire_fusion_cannon_time = 0;
  4094.                     Global_laser_firing_count = 1;
  4095.                 } else {
  4096.                     vms_vector    rand_vec;
  4097.                     fix            bump_amount;
  4098.  
  4099.                     Global_laser_firing_count = 0;
  4100.  
  4101.                     ConsoleObject->mtype.phys_info.rotvel.x += (rand() - 16384)/8;
  4102.                     ConsoleObject->mtype.phys_info.rotvel.z += (rand() - 16384)/8;
  4103.                     make_random_vector(&rand_vec);
  4104.  
  4105.                     bump_amount = F1_0*4;
  4106.  
  4107.                     if (Fusion_charge > F1_0*2)
  4108.                         bump_amount = Fusion_charge*4;
  4109.  
  4110.                     bump_one_object(ConsoleObject, &rand_vec, bump_amount);
  4111.                 }
  4112.             }
  4113.  
  4114.             if (Global_laser_firing_count) {
  4115.                 //    Don't cap here, gets capped in Laser_create_new and is based on whether in multiplayer mode, MK, 3/27/95
  4116.                 // if (Fusion_charge > F1_0*2)
  4117.                 //     Fusion_charge = F1_0*2;
  4118.                 Global_laser_firing_count -= do_laser_firing_player();    //do_laser_firing(Players[Player_num].objnum, Primary_weapon);
  4119.             }
  4120.  
  4121.             if (Global_laser_firing_count < 0)
  4122.                 Global_laser_firing_count = 0;
  4123.         }
  4124.  
  4125.     if (Do_appearance_effect) {
  4126.         create_player_appearance_effect(ConsoleObject);
  4127.         Do_appearance_effect = 0;
  4128.     }
  4129. }
  4130.  
  4131. //    -------------------------------------------------------------------------------------------------------
  4132. //    If player is close enough to objnum, which ought to be a powerup, pick it up!
  4133. //    This could easily be made difficulty level dependent.
  4134. void powerup_grab_cheat(object *player, int objnum)
  4135. {
  4136.     fix    powerup_size;
  4137.     fix    player_size;
  4138.     fix    dist;
  4139.  
  4140.     Assert(Objects[objnum].type == OBJ_POWERUP);
  4141.  
  4142.     powerup_size = Objects[objnum].size;
  4143.     player_size = player->size;
  4144.  
  4145.     dist = vm_vec_dist_quick(&Objects[objnum].pos, &player->pos);
  4146.  
  4147.     if ((dist < 2*(powerup_size + player_size)) && !(Objects[objnum].flags & OF_SHOULD_BE_DEAD)) {
  4148.         vms_vector    collision_point;
  4149.  
  4150.         vm_vec_avg(&collision_point, &Objects[objnum].pos, &player->pos);
  4151.         collide_player_and_powerup(player, &Objects[objnum], &collision_point);
  4152.     }
  4153. }
  4154.  
  4155. //    -------------------------------------------------------------------------------------------------------
  4156. //    Make it easier to pick up powerups.
  4157. //    For all powerups in this segment, pick them up at up to twice pickuppable distance based on dot product
  4158. //    from player to powerup and player's forward vector.
  4159. //    This has the effect of picking them up more easily left/right and up/down, but not making them disappear
  4160. //    way before the player gets there.
  4161. void powerup_grab_cheat_all(void)
  4162. {
  4163.     segment    *segp;
  4164.     int        objnum;
  4165.  
  4166.     segp = &Segments[ConsoleObject->segnum];
  4167.     objnum = segp->objects;
  4168.  
  4169.     while (objnum != -1) {
  4170.         if (Objects[objnum].type == OBJ_POWERUP)
  4171.             powerup_grab_cheat(ConsoleObject, objnum);
  4172.         objnum = Objects[objnum].next;
  4173.     }
  4174.  
  4175. }
  4176.  
  4177. int    Last_level_path_created = -1;
  4178.  
  4179. #ifdef SHOW_EXIT_PATH
  4180.  
  4181. //    ------------------------------------------------------------------------------------------------------------------
  4182. //    Create path for player from current segment to goal segment.
  4183. //    Return true if path created, else return false.
  4184. int mark_player_path_to_segment(int segnum)
  4185. {
  4186.     int        i;
  4187.     object    *objp = ConsoleObject;
  4188.     short        player_path_length=0;
  4189.     int        player_hide_index=-1;
  4190.  
  4191.     if (Last_level_path_created == Current_level_num) {
  4192.         return 0;
  4193.     }
  4194.  
  4195.     Last_level_path_created = Current_level_num;
  4196.  
  4197.     if (create_path_points(objp, objp->segnum, segnum, Point_segs_free_ptr, &player_path_length, 100, 0, 0, -1) == -1) {
  4198.         mprintf((0, "Unable to form path of length %i for myself\n", 100));
  4199.         return 0;
  4200.     }
  4201.  
  4202.     player_hide_index = Point_segs_free_ptr - Point_segs;
  4203.     Point_segs_free_ptr += player_path_length;
  4204.  
  4205.     if (Point_segs_free_ptr - Point_segs + MAX_PATH_LENGTH*2 > MAX_POINT_SEGS) {
  4206.         mprintf((1, "Can't create path.  Not enough point_segs.\n"));
  4207.         ai_reset_all_paths();
  4208.         return 0;
  4209.     }
  4210.  
  4211.     for (i=1; i<player_path_length; i++) {
  4212.         int            segnum, objnum;
  4213.         vms_vector    seg_center;
  4214.         object        *obj;
  4215.  
  4216.         segnum = Point_segs[player_hide_index+i].segnum;
  4217.         mprintf((0, "%3i ", segnum));
  4218.         seg_center = Point_segs[player_hide_index+i].point;
  4219.  
  4220.         objnum = obj_create( OBJ_POWERUP, POW_ENERGY, segnum, &seg_center, &vmd_identity_matrix, Powerup_info[POW_ENERGY].size, CT_POWERUP, MT_NONE, RT_POWERUP);
  4221.         if (objnum == -1) {
  4222.             Int3();        //    Unable to drop energy powerup for path
  4223.             return 1;
  4224.         }
  4225.  
  4226.         obj = &Objects[objnum];
  4227.         obj->rtype.vclip_info.vclip_num = Powerup_info[obj->id].vclip_num;
  4228.         obj->rtype.vclip_info.frametime = Vclip[obj->rtype.vclip_info.vclip_num].frame_time;
  4229.         obj->rtype.vclip_info.framenum = 0;
  4230.         obj->lifeleft = F1_0*100 + rand() * 4;
  4231.     }
  4232.  
  4233.     mprintf((0, "\n"));
  4234.     return 1;
  4235. }
  4236.  
  4237. //    Return true if it happened, else return false.
  4238. int create_special_path(void)
  4239. {
  4240.     int    i,j;
  4241.  
  4242.     //    ---------- Find exit doors ----------
  4243.     for (i=0; i<=Highest_segment_index; i++)
  4244.         for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
  4245.             if (Segments[i].children[j] == -2) {
  4246.                 mprintf((0, "Exit at segment %i\n", i));
  4247.                 return mark_player_path_to_segment(i);
  4248.             }
  4249.  
  4250.     return 0;
  4251. }
  4252.  
  4253. #endif
  4254.  
  4255.  
  4256. #ifndef RELEASE
  4257. int    Max_obj_count_mike = 0;
  4258.  
  4259. //    Shows current number of used objects.
  4260. void show_free_objects(void)
  4261. {
  4262.     if (!(FrameCount & 8)) {
  4263.         int    i;
  4264.         int    count=0;
  4265.  
  4266.         mprintf((0, "Highest_object_index = %3i, MAX_OBJECTS = %3i, now used = ", Highest_object_index, MAX_OBJECTS));
  4267.  
  4268.         for (i=0; i<=Highest_object_index; i++)
  4269.             if (Objects[i].type != OBJ_NONE)
  4270.                 count++;
  4271.  
  4272.         mprintf((0, "%3i", count));
  4273.  
  4274.         if (count > Max_obj_count_mike) {
  4275.             Max_obj_count_mike = count;
  4276.             mprintf((0, " ***"));
  4277.         }
  4278.  
  4279.         mprintf((0, "\n"));
  4280.     }
  4281.  
  4282. }
  4283.  
  4284. #define    FILL_VAL    0xcc        //    int 3 opcode value
  4285.  
  4286.  
  4287. extern void code_01s(void), code_01e(void);
  4288. extern void code_02s(void), code_02e(void);
  4289. extern void code_03s(void), code_03e(void);
  4290. extern void code_04s(void), code_04e(void);
  4291. extern void code_05s(void), code_05e(void);
  4292. extern void code_06s(void), code_06e(void);
  4293. extern void code_07s(void), code_07e(void);
  4294. extern void code_08s(void), code_08e(void);
  4295. extern void code_09s(void), code_09e(void);
  4296. extern void code_10s(void), code_10e(void);
  4297. extern void code_11s(void), code_11e(void);
  4298. extern void code_12s(void), code_12e(void);
  4299. extern void code_13s(void), code_13e(void);
  4300. extern void code_14s(void), code_14e(void);
  4301. extern void code_15s(void), code_15e(void);
  4302. extern void code_16s(void), code_16e(void);
  4303. extern void code_17s(void), code_17e(void);
  4304. extern void code_18s(void), code_18e(void);
  4305. extern void code_19s(void), code_19e(void);
  4306. extern void code_20s(void), code_20e(void);
  4307. extern void code_21s(void), code_21e(void);
  4308.  
  4309. int    Mem_filled = 0;
  4310.  
  4311. void fill_func(char *start, char *end, char value)
  4312. {
  4313.     char    *i;
  4314.  
  4315.     mprintf((0, "Filling from %8x to %8x\n", start, end));
  4316.  
  4317.     for (i=start; i<end; i++)
  4318.         *i = value;
  4319.  
  4320. }
  4321.  
  4322. void check_func(char *start, char *end, char value)
  4323. {
  4324.     char    *i;
  4325.  
  4326.     for (i=start; i<end; i++)
  4327.         if (*i != value) {
  4328.             Int3();        //    The nast triple aught six bug...we can smell it...contact Mike!
  4329.             Error("Oops, the nasty triple aught six bug.  Address == %8x\n", i);
  4330.         }
  4331.  
  4332. }
  4333.  
  4334. #if 0
  4335. void mem_fill(void)
  4336. {
  4337.     if (Mem_filled)
  4338.         return;
  4339.  
  4340.     Mem_filled = 1;
  4341.  
  4342.     fill_func((char *) code_01s, (char *) code_01e, FILL_VAL);
  4343.     fill_func((char *) code_02s, (char *) code_02e, FILL_VAL);
  4344.     fill_func((char *) code_03s, (char *) code_03e, FILL_VAL);
  4345.     fill_func((char *) code_04s, (char *) code_04e, FILL_VAL);
  4346.     fill_func((char *) code_05s, (char *) code_05e, FILL_VAL);
  4347.     fill_func((char *) code_06s, (char *) code_06e, FILL_VAL);
  4348.     fill_func((char *) code_07s, (char *) code_07e, FILL_VAL);
  4349.     fill_func((char *) code_08s, (char *) code_08e, FILL_VAL);
  4350.     fill_func((char *) code_09s, (char *) code_09e, FILL_VAL);
  4351.     fill_func((char *) code_10s, (char *) code_10e, FILL_VAL);
  4352.     fill_func((char *) code_11s, (char *) code_11e, FILL_VAL);
  4353.     fill_func((char *) code_12s, (char *) code_12e, FILL_VAL);
  4354.     fill_func((char *) code_13s, (char *) code_13e, FILL_VAL);
  4355.     fill_func((char *) code_14s, (char *) code_14e, FILL_VAL);
  4356.     fill_func((char *) code_15s, (char *) code_15e, FILL_VAL);
  4357.     fill_func((char *) code_16s, (char *) code_16e, FILL_VAL);
  4358.     fill_func((char *) code_17s, (char *) code_17e, FILL_VAL);
  4359.     fill_func((char *) code_18s, (char *) code_18e, FILL_VAL);
  4360.     fill_func((char *) code_19s, (char *) code_19e, FILL_VAL);
  4361.     fill_func((char *) code_20s, (char *) code_20e, FILL_VAL);
  4362.     fill_func((char *) code_21s, (char *) code_21e, FILL_VAL);
  4363. }
  4364.  
  4365. void mem_check(void)
  4366. {
  4367.     check_func((char *) code_01s, (char *) code_01e, FILL_VAL);
  4368.     check_func((char *) code_02s, (char *) code_02e, FILL_VAL);
  4369.     check_func((char *) code_03s, (char *) code_03e, FILL_VAL);
  4370.     check_func((char *) code_04s, (char *) code_04e, FILL_VAL);
  4371.     check_func((char *) code_05s, (char *) code_05e, FILL_VAL);
  4372.     check_func((char *) code_06s, (char *) code_06e, FILL_VAL);
  4373.     check_func((char *) code_07s, (char *) code_07e, FILL_VAL);
  4374.     check_func((char *) code_08s, (char *) code_08e, FILL_VAL);
  4375.     check_func((char *) code_09s, (char *) code_09e, FILL_VAL);
  4376.     check_func((char *) code_10s, (char *) code_10e, FILL_VAL);
  4377.     check_func((char *) code_11s, (char *) code_11e, FILL_VAL);
  4378.     check_func((char *) code_12s, (char *) code_12e, FILL_VAL);
  4379.     check_func((char *) code_13s, (char *) code_13e, FILL_VAL);
  4380.     check_func((char *) code_14s, (char *) code_14e, FILL_VAL);
  4381.     check_func((char *) code_15s, (char *) code_15e, FILL_VAL);
  4382.     check_func((char *) code_16s, (char *) code_16e, FILL_VAL);
  4383.     check_func((char *) code_17s, (char *) code_17e, FILL_VAL);
  4384.     check_func((char *) code_18s, (char *) code_18e, FILL_VAL);
  4385.     check_func((char *) code_19s, (char *) code_19e, FILL_VAL);
  4386.     check_func((char *) code_20s, (char *) code_20e, FILL_VAL);
  4387.     check_func((char *) code_21s, (char *) code_21e, FILL_VAL);
  4388. }
  4389. #endif
  4390. #endif
  4391.