home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / gauges.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  67KB  |  2,284 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/gauges.c $
  15.  * $Revision: 2.7 $
  16.  * $Author: john $
  17.  * $Date: 1995/12/19 16:18:33 $
  18.  *
  19.  * Inferno gauge drivers
  20.  *
  21.  * $Log: gauges.c $
  22.  * Revision 2.7  1995/12/19  16:18:33  john
  23.  * Made weapon info align with canvas width, not 315.
  24.  * 
  25.  * Revision 2.6  1995/03/21  14:39:25  john
  26.  * Ifdef'd out the NETWORK code.
  27.  * 
  28.  * Revision 2.5  1995/03/14  12:31:25  john
  29.  * Prevent negative shields from printing.
  30.  * 
  31.  * Revision 2.4  1995/03/10  12:57:58  allender
  32.  * move rear view text up four pixels up when playing back demo
  33.  * 
  34.  * Revision 2.3  1995/03/09  11:47:51  john
  35.  * Added HUD for VR helmets.
  36.  * 
  37.  * Revision 2.2  1995/03/06  15:23:26  john
  38.  * New screen techniques.
  39.  * 
  40.  * Revision 2.1  1995/02/27  13:13:45  john
  41.  * Removed floating point.
  42.  * 
  43.  * Revision 2.0  1995/02/27  11:29:06  john
  44.  * New version 2.0, which has no anonymous unions, builds with
  45.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  46.  * 
  47.  * Revision 1.203  1995/02/11  01:56:45  mike
  48.  * move up weapons text on fullscreen hud, missiles was offscreen.
  49.  * 
  50.  * Revision 1.202  1995/02/09  13:23:34  rob
  51.  * Added reticle names in demo playback.
  52.  * 
  53.  * Revision 1.201  1995/02/08  19:20:46  rob
  54.  * Show cloaked teammates on H
  55.  * UD.  Get rid of show ID's in anarchy option.
  56.  * 
  57.  * Revision 1.200  1995/02/07  21:09:00  mike
  58.  * add flashing to invulnerability and cloak on fullscreen.
  59.  * 
  60.  * Revision 1.199  1995/02/02  21:55:57  matt
  61.  * Added new colored key icons for fullscreen
  62.  * 
  63.  * Revision 1.198  1995/01/30  17:17:07  rob
  64.  * Fixed teammate names on hud.
  65.  * 
  66.  * Revision 1.197  1995/01/28  17:40:49  mike
  67.  * fix gauge fontcolor.
  68.  * 
  69.  * Revision 1.196  1995/01/27  17:03:14  mike
  70.  * fix placement of weapon info in multiplayer fullscreen, as per AP request.
  71.  * 
  72.  * Revision 1.195  1995/01/27  11:51:23  rob
  73.  * Put deaths tally into cooperative mode
  74.  * 
  75.  * Revision 1.194  1995/01/27  11:43:24  adam
  76.  * fiddled with key display
  77.  * 
  78.  * Revision 1.193  1995/01/25  23:38:35  mike
  79.  * fix keys on fullscreen.
  80.  * 
  81.  * Revision 1.192  1995/01/24  22:03:28  mike
  82.  * Lotsa hud stuff, put a lot of messages up.
  83.  * 
  84.  * Revision 1.191  1995/01/23  16:47:21  rob
  85.  * Fixed problem with playing extra life noise in coop.
  86.  * 
  87.  * Revision 1.190  1995/01/22  16:00:46  mike
  88.  * remove unneeded string.
  89.  * 
  90.  * Revision 1.189  1995/01/22  15:58:22  mike
  91.  * localization
  92.  * 
  93.  * Revision 1.188  1995/01/20  17:19:45  rob
  94.  * Fixing colors of hud kill list players.
  95.  * 
  96.  * Revision 1.187  1995/01/20  09:19:18  allender
  97.  * record player flags when in CM_FULL_SCREEN
  98.  * 
  99.  * Revision 1.186  1995/01/19  16:29:09  allender
  100.  * made demo recording of weapon change be in this file for shareware only
  101.  * 
  102.  * Revision 1.185  1995/01/19  15:00:33  allender
  103.  * code to record shield, energy, and ammo in fullscreen
  104.  * 
  105.  * Revision 1.184  1995/01/19  13:43:13  matt
  106.  * Fixed "cheater" message on HUD
  107.  * 
  108.  * Revision 1.183  1995/01/18  16:11:58  mike
  109.  * Don't show added scores of 0.
  110.  * 
  111.  * Revision 1.182  1995/01/17  17:42:39  allender
  112.  * do ammo counts in demo recording
  113.  * 
  114.  * Revision 1.181  1995/01/16  17:26:25  rob
  115.  * Fixed problem with coloration of team kill list.
  116.  * 
  117.  * Revision 1.180  1995/01/16  17:22:39  john
  118.  * Made so that KB and framerate don't collide.
  119.  * 
  120.  * Revision 1.179  1995/01/16  14:58:31  matt
  121.  * Changed score_added display to print "Cheater!" when cheats enabled
  122.  * 
  123.  * Revision 1.178  1995/01/15  19:42:07  matt
  124.  * Ripped out hostage faces for registered version
  125.  * 
  126.  * Revision 1.177  1995/01/15  19:25:07  mike
  127.  * show vulcan ammo and secondary ammo in fullscreen view.
  128.  * 
  129.  * Revision 1.176  1995/01/15  13:16:12  john
  130.  * Made so that paging always happens, lowmem just loads less.
  131.  * Also, make KB load print to hud.
  132.  * 
  133.  * Revision 1.175  1995/01/14  19:17:32  john
  134.  * First version of piggy paging.
  135.  * 
  136.  * Revision 1.174  1995/01/05  21:25:23  rob
  137.  * Re-did some changes lost due to RCS weirdness.
  138.  * 
  139.  * Revision 1.173  1995/01/05  12:22:34  rob
  140.  * Don't show player names for cloaked players.
  141.  * 
  142.  * Revision 1.172  1995/01/04  17:14:50  allender
  143.  * make init_gauges work properly on demo playback
  144.  * 
  145.  * Revision 1.171  1995/01/04  15:04:42  allender
  146.  * new demo calls for registered version
  147.  * 
  148.  * Revision 1.167  1995/01/03  13:03:57  allender
  149.  * pass score points instead of total points.   Added ifdef for
  150.  * multi_send_score
  151.  * 
  152.  * Revision 1.166  1995/01/03  11:45:02  allender
  153.  * add hook to record player score
  154.  * 
  155.  * Revision 1.165  1995/01/03  11:25:19  allender
  156.  * remove newdemo stuff around score display
  157.  * 
  158.  * Revision 1.163  1995/01/02  21:03:53  rob
  159.  * Fixing up the hud-score-list for coop games.
  160.  * 
  161.  * Revision 1.162  1994/12/31  20:54:40  rob
  162.  * Added coop mode HUD score list.
  163.  * Added more generic system for player names on HUD.
  164.  * 
  165.  * Revision 1.161  1994/12/30  20:13:01  rob
  166.  * Ifdef reticle names on shareware.
  167.  * Added robot reticle naming.
  168.  * 
  169.  * Revision 1.160  1994/12/29  17:53:51  mike
  170.  * move up energy/shield in fullscreen to get out of way of kill list.
  171.  * 
  172.  * Revision 1.159  1994/12/29  16:44:05  mike
  173.  * add energy and shield showing.
  174.  * 
  175.  * Revision 1.158  1994/12/28  16:34:29  mike
  176.  * make warning beep go away on Player_is_dead.
  177.  * 
  178.  * Revision 1.157  1994/12/28  10:00:43  allender
  179.  * change in init_gauges to for multiplayer demo playbacks
  180.  * 
  181.  * Revision 1.156  1994/12/27  11:06:46  allender
  182.  * removed some previous code to for demo playback stuff
  183.  * 
  184.  * Revision 1.155  1994/12/23  14:23:06  john
  185.  * Added floating reticle for VR helments.  
  186.  * 
  187.  * Revision 1.154  1994/12/21  12:56:41  allender
  188.  * on multiplayer demo playback, show kills and deaths
  189.  * 
  190.  * Revision 1.153  1994/12/19  20:28:42  rob
  191.  * Get rid of kill list in coop games.
  192.  * 
  193.  * Revision 1.152  1994/12/14  18:06:44  matt
  194.  * Removed compile warnings
  195.  * 
  196.  * Revision 1.151  1994/12/14  15:21:28  rob
  197.  * Made gauges align in status_bar net game.
  198.  * 
  199.  * Revision 1.150  1994/12/12  17:20:33  matt
  200.  * Don't get bonus points when cheating
  201.  * 
  202.  * Revision 1.149  1994/12/12  16:47:00  matt
  203.  * When cheating, get no score.  Change level cheat to prompt for and 
  204.  * jump to new level.
  205.  * 
  206.  * Revision 1.148  1994/12/12  12:05:45  rob
  207.  * Grey out players who are disconnected.
  208.  * 
  209.  * Revision 1.147  1994/12/09  16:19:48  yuan
  210.  * kill matrix stuff.
  211.  * 
  212.  * Revision 1.146  1994/12/09  16:12:34  rob
  213.  * Fixed up the status bar kills gauges for net play.
  214.  * 
  215.  * Revision 1.145  1994/12/09  01:55:34  rob
  216.  * Added kills list to HUD/status bar.
  217.  * Added something for Mark.
  218.  * 
  219.  * Revision 1.144  1994/12/08  21:03:30  allender
  220.  * pass old player flags to record_player_flags
  221.  * 
  222.  * Revision 1.143  1994/12/07  22:49:33  mike
  223.  * no homing missile warning during endlevel sequence.
  224.  * 
  225.  * Revision 1.142  1994/12/06  13:55:31  matt
  226.  * Use new rounding func, f2ir()
  227.  * 
  228.  * Revision 1.141  1994/12/03  19:03:37  matt
  229.  * Fixed vulcan ammo HUD message
  230.  * 
  231.  * Revision 1.140  1994/12/03  18:43:18  matt
  232.  * Fixed (hopefully) claok gauge
  233.  * 
  234.  * Revision 1.139  1994/12/03  14:26:21  yuan
  235.  * Fixed dumb bug
  236.  * 
  237.  * Revision 1.138  1994/12/03  14:17:30  yuan
  238.  * Localization 320
  239.  * 
  240.  */
  241.  
  242. #pragma off (unreferenced)
  243. static char rcsid[] = "$Id: gauges.c 2.7 1995/12/19 16:18:33 john Exp $";
  244. #pragma on (unreferenced)
  245.  
  246. #include <stdio.h>
  247. #include <string.h>
  248. #include <stdlib.h>
  249. #include <stdarg.h>
  250.  
  251. #include "inferno.h"
  252. #include "game.h"
  253. #include "screens.h"
  254. #include "gauges.h"
  255. #include "physics.h"
  256. #include "error.h"
  257.  
  258. #include "menu.h"            // For the font.
  259. #include "mono.h"
  260. #include "collide.h"
  261. #include "newdemo.h"
  262. #include "player.h"
  263. #include "gamefont.h"
  264. #include "hostage.h"
  265. #include "bm.h"
  266. #include "text.h"
  267. #include "powerup.h"
  268. #include "sounds.h"
  269. #include "multi.h"
  270. #include "network.h"
  271. #include "endlevel.h"
  272.  
  273. #include "wall.h"
  274. #include "text.h"
  275. #include "render.h"
  276. #include "piggy.h"
  277.  
  278. bitmap_index Gauges[MAX_GAUGE_BMS];   // Array of all gauge bitmaps.
  279.  
  280. grs_canvas *Canv_LeftEnergyGauge;
  281. grs_canvas *Canv_SBEnergyGauge;
  282. grs_canvas *Canv_RightEnergyGauge;
  283. grs_canvas *Canv_NumericalGauge;
  284.  
  285. //bitmap numbers for gauges
  286.  
  287. #define GAUGE_SHIELDS            0        //0..9, in decreasing order (100%,90%...0%)
  288.  
  289. #define GAUGE_INVULNERABLE        10        //10..19
  290. #define N_INVULNERABLE_FRAMES    10
  291.  
  292. #define GAUGE_SPEED               20        //unused
  293. #define GAUGE_ENERGY_LEFT        21
  294. #define GAUGE_ENERGY_RIGHT        22
  295. #define GAUGE_NUMERICAL            23
  296.  
  297. #define GAUGE_BLUE_KEY            24
  298. #define GAUGE_GOLD_KEY            25
  299. #define GAUGE_RED_KEY            26
  300. #define GAUGE_BLUE_KEY_OFF        27
  301. #define GAUGE_GOLD_KEY_OFF        28
  302. #define GAUGE_RED_KEY_OFF        29
  303.  
  304. #define SB_GAUGE_BLUE_KEY        30
  305. #define SB_GAUGE_GOLD_KEY        31
  306. #define SB_GAUGE_RED_KEY        32
  307. #define SB_GAUGE_BLUE_KEY_OFF    33
  308. #define SB_GAUGE_GOLD_KEY_OFF    34
  309. #define SB_GAUGE_RED_KEY_OFF    35
  310.  
  311. #define SB_GAUGE_ENERGY            36
  312.  
  313. #define GAUGE_LIVES                37    
  314.  
  315. #define GAUGE_SHIPS                38
  316. #define GAUGE_SHIPS_LAST        45
  317.  
  318. #define RETICLE_CROSS            46
  319. #define RETICLE_PRIMARY            48
  320. #define RETICLE_SECONDARY        51
  321. #define RETICLE_LAST                55
  322.  
  323. #define GAUGE_HOMING_WARNING_ON    56
  324. #define GAUGE_HOMING_WARNING_OFF    57
  325.  
  326. #define SML_RETICLE_CROSS        58
  327. #define SML_RETICLE_PRIMARY    60
  328. #define SML_RETICLE_SECONDARY    63
  329. #define SML_RETICLE_LAST        67
  330.  
  331. #define KEY_ICON_BLUE            68
  332. #define KEY_ICON_YELLOW            69
  333. #define KEY_ICON_RED                70
  334.  
  335. //change MAX_GAUGE_BMS when adding gauges
  336.  
  337. //Coordinats for gauges
  338.  
  339. #define GAUGE_BLUE_KEY_X        45
  340. #define GAUGE_BLUE_KEY_Y        152
  341. #define GAUGE_GOLD_KEY_X        44
  342. #define GAUGE_GOLD_KEY_Y        162
  343. #define GAUGE_RED_KEY_X            43
  344. #define GAUGE_RED_KEY_Y            172
  345.  
  346. #define SB_GAUGE_KEYS_X            11
  347.  
  348. #define SB_GAUGE_BLUE_KEY_Y    153
  349. #define SB_GAUGE_GOLD_KEY_Y    169
  350. #define SB_GAUGE_RED_KEY_Y        185
  351.  
  352. #define LEFT_ENERGY_GAUGE_X     70
  353. #define LEFT_ENERGY_GAUGE_Y     131
  354. #define LEFT_ENERGY_GAUGE_W     64
  355. #define LEFT_ENERGY_GAUGE_H     8
  356.  
  357. #define RIGHT_ENERGY_GAUGE_X     190
  358. #define RIGHT_ENERGY_GAUGE_Y     131
  359. #define RIGHT_ENERGY_GAUGE_W     64
  360. #define RIGHT_ENERGY_GAUGE_H     8
  361.  
  362. #define SB_ENERGY_GAUGE_X         98
  363. #define SB_ENERGY_GAUGE_Y         155
  364. #define SB_ENERGY_GAUGE_W         16
  365. #define SB_ENERGY_GAUGE_H         41
  366.  
  367. #define SB_ENERGY_NUM_X         (SB_ENERGY_GAUGE_X+2)
  368. #define SB_ENERGY_NUM_Y         190
  369.  
  370. #define SHIELD_GAUGE_X             146
  371. #define SHIELD_GAUGE_Y            155
  372. #define SHIELD_GAUGE_W             35
  373. #define SHIELD_GAUGE_H            32 
  374.  
  375. #define SHIP_GAUGE_X             (SHIELD_GAUGE_X+5)
  376. #define SHIP_GAUGE_Y                (SHIELD_GAUGE_Y+5)
  377.  
  378. #define SB_SHIELD_GAUGE_X         123        //139
  379. #define SB_SHIELD_GAUGE_Y         163
  380.  
  381. #define SB_SHIP_GAUGE_X         (SB_SHIELD_GAUGE_X+5)
  382. #define SB_SHIP_GAUGE_Y         (SB_SHIELD_GAUGE_Y+5)
  383.  
  384. #define SB_SHIELD_NUM_X         (SB_SHIELD_GAUGE_X+12)    //151
  385. #define SB_SHIELD_NUM_Y         156
  386.  
  387. #define NUMERICAL_GAUGE_X        154
  388. #define NUMERICAL_GAUGE_Y        130
  389. #define NUMERICAL_GAUGE_W        19
  390. #define NUMERICAL_GAUGE_H        22
  391.  
  392. #define PRIMARY_W_PIC_X            64
  393. #define PRIMARY_W_PIC_Y            154
  394. #define PRIMARY_W_TEXT_X        87
  395. #define PRIMARY_W_TEXT_Y        157
  396. #define PRIMARY_AMMO_X            (96-3)
  397. #define PRIMARY_AMMO_Y            171
  398.  
  399. #define SECONDARY_W_PIC_X        234
  400. #define SECONDARY_W_PIC_Y        154
  401. #define SECONDARY_W_TEXT_X        207
  402. #define SECONDARY_W_TEXT_Y        157
  403. #define SECONDARY_AMMO_X        213
  404. #define SECONDARY_AMMO_Y        171
  405.  
  406. #define SB_LIVES_X                266
  407. #define SB_LIVES_Y                185
  408. #define SB_LIVES_LABEL_X        237
  409. #define SB_LIVES_LABEL_Y        (SB_LIVES_Y+1)
  410.  
  411. #define SB_SCORE_RIGHT            301
  412. #define SB_SCORE_Y                158
  413. #define SB_SCORE_LABEL_X        237
  414.  
  415. #define SB_SCORE_ADDED_RIGHT    301
  416. #define SB_SCORE_ADDED_Y        165
  417.  
  418. static int score_display;
  419. static fix score_time;
  420.  
  421. static int old_score[2]                = { -1, -1 };
  422. static int old_energy[2]            = { -1, -1 };
  423. static int old_shields[2]            = { -1, -1 };
  424. static int old_flags[2]                = { -1, -1 };
  425. static int old_weapon[2][2]        = {{ -1, -1 },{-1,-1}};
  426. static int old_ammo_count[2][2]    = {{ -1, -1 },{-1,-1}};
  427. static int old_cloak[2]                = { 0, 0 };
  428. static int old_lives[2]                = { -1, -1 };
  429.  
  430. static int invulnerable_frame = 0;
  431.  
  432. static int cloak_fade_state;        //0=steady, -1 fading out, 1 fading in 
  433.  
  434. #define WS_SET                0        //in correct state
  435. #define WS_FADING_OUT    1
  436. #define WS_FADING_IN        2
  437.  
  438. int weapon_box_states[2];
  439. fix weapon_box_fade_values[2];
  440.  
  441. #define FADE_SCALE    (2*i2f(GR_FADE_LEVELS)/REARM_TIME)        // fade out and back in REARM_TIME, in fade levels per seconds (int)
  442.  
  443. typedef struct span {
  444.     byte l,r;
  445. } span;
  446.  
  447. //store delta x values from left of box
  448. span weapon_window_left[] = {        //first span 67,154
  449.         {4,53},
  450.         {4,53},
  451.         {4,53},
  452.         {4,53},
  453.         {4,53},
  454.         {3,53},
  455.         {3,53},
  456.         {3,53},
  457.         {3,53},
  458.         {3,53},
  459.         {3,53},
  460.         {3,53},
  461.         {3,53},
  462.         {2,53},
  463.         {2,53},
  464.         {2,53},
  465.         {2,53},
  466.         {2,53},
  467.         {2,53},
  468.         {2,53},
  469.         {2,53},
  470.         {1,53},
  471.         {1,53},
  472.         {1,53},
  473.         {1,53},
  474.         {1,53},
  475.         {1,53},
  476.         {1,53},
  477.         {1,53},
  478.         {0,53},
  479.         {0,53},
  480.         {0,53},
  481.         {0,53},
  482.         {0,52},
  483.         {1,52},
  484.         {2,51},
  485.         {3,51},
  486.         {4,50},
  487.         {5,50},
  488.     };
  489.  
  490.  
  491. //store delta x values from left of box
  492. span weapon_window_right[] = {        //first span 207,154
  493.         {208-202,255-202},
  494.         {206-202,257-202},
  495.         {205-202,258-202},
  496.         {204-202,259-202},
  497.         {203-202,260-202},
  498.         {203-202,260-202},
  499.         {203-202,260-202},
  500.         {203-202,260-202},
  501.         {203-202,260-202},
  502.         {203-202,261-202},
  503.         {203-202,261-202},
  504.         {203-202,261-202},
  505.         {203-202,261-202},
  506.         {203-202,261-202},
  507.         {203-202,261-202},
  508.         {203-202,261-202},
  509.         {203-202,261-202},
  510.         {203-202,261-202},
  511.         {203-202,262-202},
  512.         {203-202,262-202},
  513.         {203-202,262-202},
  514.         {203-202,262-202},
  515.         {203-202,262-202},
  516.         {203-202,262-202},
  517.         {203-202,262-202},
  518.         {203-202,262-202},
  519.         {204-202,263-202},
  520.         {204-202,263-202},
  521.         {204-202,263-202},
  522.         {204-202,263-202},
  523.         {204-202,263-202},
  524.         {204-202,263-202},
  525.         {204-202,263-202},
  526.         {204-202,263-202},
  527.         {204-202,263-202},
  528.         {204-202,263-202},
  529.         {204-202,263-202},
  530.         {204-202,263-202},
  531.         {205-202,263-202},
  532.         {206-202,262-202},
  533.         {207-202,261-202},
  534.         {208-202,260-202},
  535.         {211-202,255-202},
  536.     };
  537.  
  538.                                             
  539. #define N_LEFT_WINDOW_SPANS  (sizeof(weapon_window_left)/sizeof(*weapon_window_left))
  540. #define N_RIGHT_WINDOW_SPANS (sizeof(weapon_window_right)/sizeof(*weapon_window_right))
  541.  
  542. #define PRIMARY_W_BOX_LEFT        63
  543. #define PRIMARY_W_BOX_TOP        154
  544. #define PRIMARY_W_BOX_RIGHT    (PRIMARY_W_BOX_LEFT+58)
  545. #define PRIMARY_W_BOX_BOT        (PRIMARY_W_BOX_TOP+N_LEFT_WINDOW_SPANS-1)
  546.                                             
  547. #define SECONDARY_W_BOX_LEFT    202    //207
  548. #define SECONDARY_W_BOX_TOP    151
  549. #define SECONDARY_W_BOX_RIGHT    263    //(SECONDARY_W_BOX_LEFT+54)
  550. #define SECONDARY_W_BOX_BOT    (SECONDARY_W_BOX_TOP+N_RIGHT_WINDOW_SPANS-1)
  551.  
  552. #define SB_PRIMARY_W_BOX_LEFT        34        //50
  553. #define SB_PRIMARY_W_BOX_TOP        153
  554. #define SB_PRIMARY_W_BOX_RIGHT    (SB_PRIMARY_W_BOX_LEFT+53)
  555. #define SB_PRIMARY_W_BOX_BOT        (195)
  556.                                             
  557. #define SB_SECONDARY_W_BOX_LEFT    169    //210
  558. #define SB_SECONDARY_W_BOX_TOP    153
  559. #define SB_SECONDARY_W_BOX_RIGHT    (SB_SECONDARY_W_BOX_LEFT+54)
  560. #define SB_SECONDARY_W_BOX_BOT    (153+43)
  561.  
  562. #define SB_PRIMARY_W_PIC_X            (SB_PRIMARY_W_BOX_LEFT+1)    //51
  563. #define SB_PRIMARY_W_PIC_Y            154
  564. #define SB_PRIMARY_W_TEXT_X        (SB_PRIMARY_W_BOX_LEFT+24)    //(51+23)
  565. #define SB_PRIMARY_W_TEXT_Y        157
  566. #define SB_PRIMARY_AMMO_X            ((SB_PRIMARY_W_BOX_LEFT+33)-3)    //(51+32)
  567. #define SB_PRIMARY_AMMO_Y            171
  568.  
  569. #define SB_SECONDARY_W_PIC_X        (SB_SECONDARY_W_BOX_LEFT+29)    //(212+27)
  570. #define SB_SECONDARY_W_PIC_Y        154
  571. #define SB_SECONDARY_W_TEXT_X        (SB_SECONDARY_W_BOX_LEFT+2)    //212
  572. #define SB_SECONDARY_W_TEXT_Y        157
  573. #define SB_SECONDARY_AMMO_X        (SB_SECONDARY_W_BOX_LEFT+11)    //(212+9)
  574. #define SB_SECONDARY_AMMO_Y        171
  575.  
  576. typedef struct gauge_box {
  577.     int left,top;
  578.     int right,bot;        //maximal box
  579.     span *spanlist;    //list of left,right spans for copy
  580. } gauge_box;
  581.  
  582. //first two are primary & secondary
  583. //seconds two are the same for the status bar
  584. gauge_box gauge_boxes[] = {
  585.         {PRIMARY_W_BOX_LEFT,PRIMARY_W_BOX_TOP,PRIMARY_W_BOX_RIGHT,PRIMARY_W_BOX_BOT,weapon_window_left},
  586.         {SECONDARY_W_BOX_LEFT,SECONDARY_W_BOX_TOP,SECONDARY_W_BOX_RIGHT,SECONDARY_W_BOX_BOT,weapon_window_right},
  587.  
  588.         {SB_PRIMARY_W_BOX_LEFT,SB_PRIMARY_W_BOX_TOP,SB_PRIMARY_W_BOX_RIGHT,SB_PRIMARY_W_BOX_BOT,NULL},
  589.         {SB_SECONDARY_W_BOX_LEFT,SB_SECONDARY_W_BOX_TOP,SB_SECONDARY_W_BOX_RIGHT,SB_SECONDARY_W_BOX_BOT,NULL}
  590.     };
  591.  
  592.  
  593. int    Color_0_31_0 = -1;
  594.  
  595. //copy a box from the off-screen buffer to the visible page
  596. copy_gauge_box(gauge_box *box,grs_bitmap *bm)
  597. {
  598.  
  599.     if (box->spanlist) {
  600.         int n_spans = box->bot-box->top+1;
  601.         int cnt,y;
  602.  
  603. //gr_setcolor(BM_XRGB(31,0,0));
  604.  
  605.         for (cnt=0,y=box->top;cnt<n_spans;cnt++,y++)
  606.             gr_bm_ubitblt(box->spanlist[cnt].r-box->spanlist[cnt].l+1,1,
  607.                         box->left+box->spanlist[cnt].l,y,box->left+box->spanlist[cnt].l,y,bm,&grd_curcanv->cv_bitmap);
  608.             //gr_scanline(box->left+box->spanlist[cnt].l,box->left+box->spanlist[cnt].r,y);
  609.     }
  610.     else
  611.         gr_bm_ubitblt(box->right-box->left+1,box->bot-box->top+1,
  612.                         box->left,box->top,box->left,box->top,
  613.                         bm,&grd_curcanv->cv_bitmap);
  614. }
  615.  
  616. //fills in the coords of the hostage video window
  617. get_hostage_window_coords(int *x,int *y,int *w,int *h)
  618. {
  619.     if (Cockpit_mode == CM_STATUS_BAR) {
  620.         *x = SB_SECONDARY_W_BOX_LEFT;
  621.         *y = SB_SECONDARY_W_BOX_TOP;
  622.         *w = SB_SECONDARY_W_BOX_RIGHT - SB_SECONDARY_W_BOX_LEFT + 1;
  623.         *h = SB_SECONDARY_W_BOX_BOT - SB_SECONDARY_W_BOX_TOP + 1;
  624.     }
  625.     else {
  626.         *x = SECONDARY_W_BOX_LEFT;
  627.         *y = SECONDARY_W_BOX_TOP;
  628.         *w = SECONDARY_W_BOX_RIGHT - SECONDARY_W_BOX_LEFT + 1;
  629.         *h = SECONDARY_W_BOX_BOT - SECONDARY_W_BOX_TOP + 1;
  630.     }
  631.  
  632. }
  633.  
  634. //these should be in gr.h 
  635. #define cv_w  cv_bitmap.bm_w
  636. #define cv_h  cv_bitmap.bm_h
  637.  
  638. #define HUD_MESSAGE_LENGTH 150
  639. #define HUD_MAX_NUM 4
  640. extern int HUD_nmessages, hud_first; // From hud.c
  641. extern char HUD_messages[HUD_MAX_NUM][HUD_MESSAGE_LENGTH+5]; 
  642.  
  643. void hud_show_score()
  644. {
  645.     char    score_str[20];
  646.     int    w, h, aw;
  647.  
  648.     if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
  649.         return;
  650.  
  651.     gr_set_curfont( GAME_FONT );
  652.  
  653.     if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) ) {
  654.         sprintf(score_str, "%s: %5d", TXT_KILLS, Players[Player_num].net_kills_total);
  655.     } else {
  656.         sprintf(score_str, "%s: %5d", TXT_SCORE, Players[Player_num].score);
  657.     }
  658.     gr_get_string_size(score_str, &w, &h, &aw );
  659.  
  660.     if (Color_0_31_0 == -1)
  661.         Color_0_31_0 = gr_getcolor(0,31,0);
  662.     gr_set_fontcolor(Color_0_31_0, -1);
  663.  
  664.     gr_printf(grd_curcanv->cv_w-w-2, 3, score_str);
  665. }
  666.  
  667. void hud_show_score_added()
  668. {
  669.     int    color;
  670.     int    w, h, aw;
  671.     char    score_str[20];
  672.  
  673.     if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  674.         return;
  675.  
  676.     if (score_display == 0)
  677.         return;
  678.  
  679.     gr_set_curfont( GAME_FONT );
  680.  
  681.     score_time -= FrameTime;
  682.     if (score_time > 0) {
  683.         color = f2i(score_time * 20) + 10;
  684.  
  685.         if (color < 10) color = 10;
  686.         if (color > 31) color = 31;
  687.  
  688.         if (Cheats_enabled)
  689.             sprintf(score_str, "%s", TXT_CHEATER);
  690.         else
  691.             sprintf(score_str, "%5d", score_display);
  692.  
  693.         gr_get_string_size(score_str, &w, &h, &aw );
  694.         gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
  695.         gr_printf(grd_curcanv->cv_w-w-2-10, GAME_FONT->ft_h+5, score_str);
  696.     } else {
  697.         score_time = 0;
  698.         score_display = 0;
  699.     }
  700.     
  701. }
  702.  
  703. void sb_show_score()
  704. {                                                                                                                                                                                                                                                                 
  705.     char    score_str[20];
  706.     int x,y;
  707.     int    w, h, aw;
  708.     static int last_x[2]={SB_SCORE_RIGHT,SB_SCORE_RIGHT};
  709.     int redraw_score;
  710.  
  711.     if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  712.         redraw_score = -99;
  713.     else
  714.         redraw_score = -1;
  715.  
  716.     if (old_score[VR_current_page]==redraw_score) {
  717.         gr_set_curfont( GAME_FONT );
  718.         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  719.  
  720.         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  721.             gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS);
  722.         else
  723.             gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE);
  724.     }
  725.  
  726.     gr_set_curfont( GAME_FONT );
  727.     if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  728.         sprintf(score_str, "%5d", Players[Player_num].net_kills_total);
  729.     else
  730.         sprintf(score_str, "%5d", Players[Player_num].score);
  731.     gr_get_string_size(score_str, &w, &h, &aw );
  732.  
  733.     x = SB_SCORE_RIGHT-w-2;
  734.     y = SB_SCORE_Y;
  735.  
  736.     //erase old score
  737.     gr_setcolor(BM_XRGB(0,0,0));
  738.     gr_rect(last_x[VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h);
  739.  
  740.     if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  741.         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  742.     else
  743.         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );    
  744.  
  745.     gr_printf(x,y,score_str);
  746.  
  747.     last_x[VR_current_page] = x;
  748. }
  749.  
  750. void sb_show_score_added()
  751. {
  752.     int    color;
  753.     int w, h, aw;
  754.     char    score_str[32];
  755.     int x;
  756.     static int last_x[2]={SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_RIGHT};
  757.     static    int last_score_display[2] = { -1, -1};
  758.  
  759.     if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
  760.         return;
  761.  
  762.     if (score_display == 0)
  763.         return;
  764.  
  765.     gr_set_curfont( GAME_FONT );
  766.  
  767.     score_time -= FrameTime;
  768.     if (score_time > 0) {
  769.         if (score_display != last_score_display[VR_current_page]) {
  770.             gr_setcolor(BM_XRGB(0,0,0));
  771.             gr_rect(last_x[VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h);
  772.             last_score_display[VR_current_page] = score_display;
  773.         }
  774.  
  775.         color = f2i(score_time * 20) + 10;
  776.  
  777.         if (color < 10) color = 10;
  778.         if (color > 31) color = 31;
  779.  
  780.         if (Cheats_enabled)
  781.             sprintf(score_str, "%s", TXT_CHEATER);
  782.         else
  783.             sprintf(score_str, "%5d", score_display);
  784.  
  785.         gr_get_string_size(score_str, &w, &h, &aw );
  786.  
  787.         x = SB_SCORE_ADDED_RIGHT-w-2;
  788.  
  789.         gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
  790.         gr_printf(x, SB_SCORE_ADDED_Y, score_str);
  791.  
  792.         last_x[VR_current_page] = x;
  793.  
  794.     } else {
  795.         //erase old score
  796.         gr_setcolor(BM_XRGB(0,0,0));
  797.         gr_rect(last_x[VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h);
  798.  
  799.         score_time = 0;
  800.         score_display = 0;
  801.  
  802.     }
  803.     
  804. }
  805.  
  806. fix    Last_warning_beep_time[2] = {0,0};        //    Time we last played homing missile warning beep.
  807.  
  808. //    -----------------------------------------------------------------------------
  809. void play_homing_warning(void)
  810. {
  811.     fix    beep_delay;
  812.  
  813.     if (Endlevel_sequence || Player_is_dead)
  814.         return;
  815.  
  816.     if (Players[Player_num].homing_object_dist >= 0) {
  817.         beep_delay = Players[Player_num].homing_object_dist/128;
  818.         if (beep_delay > F1_0)
  819.             beep_delay = F1_0;
  820.         else if (beep_delay < F1_0/8)
  821.             beep_delay = F1_0/8;
  822.  
  823.         if (GameTime - Last_warning_beep_time[VR_current_page] > beep_delay/2) {
  824.             digi_play_sample( SOUND_HOMING_WARNING, F1_0 );
  825.             Last_warning_beep_time[VR_current_page] = GameTime;
  826.         }
  827.     }
  828. }
  829.  
  830. int    Last_homing_warning_shown[2]={-1,-1};
  831.  
  832. //    -----------------------------------------------------------------------------
  833. void show_homing_warning(void)
  834. {
  835.     if ((Cockpit_mode == CM_STATUS_BAR) || (Endlevel_sequence)) {
  836.         if (Last_homing_warning_shown[VR_current_page] == 1) {
  837.             PIGGY_PAGE_IN( Gauges[GAUGE_HOMING_WARNING_OFF] );
  838.             gr_ubitmapm( 7, 171, &GameBitmaps[Gauges[GAUGE_HOMING_WARNING_OFF].index] );
  839.             Last_homing_warning_shown[VR_current_page] = 0;
  840.         }
  841.         return;
  842.     }
  843.  
  844.     gr_set_current_canvas( get_current_game_screen() );
  845.  
  846.     if (Players[Player_num].homing_object_dist >= 0) {
  847.  
  848.         if (GameTime & 0x4000) {
  849.             if (Last_homing_warning_shown[VR_current_page] != 1) {
  850.                 PIGGY_PAGE_IN(Gauges[GAUGE_HOMING_WARNING_ON]);
  851.                 gr_ubitmapm( 7, 171, &GameBitmaps[Gauges[GAUGE_HOMING_WARNING_ON].index]);
  852.                 Last_homing_warning_shown[VR_current_page] = 1;
  853.             }
  854.         } else {
  855.             if (Last_homing_warning_shown[VR_current_page] != 0) {
  856.                 PIGGY_PAGE_IN(Gauges[GAUGE_HOMING_WARNING_OFF]);
  857.                 gr_ubitmapm( 7, 171, &GameBitmaps[Gauges[GAUGE_HOMING_WARNING_OFF].index] );
  858.                 Last_homing_warning_shown[VR_current_page] = 0;
  859.             }
  860.         }
  861.     } else if (Last_homing_warning_shown[VR_current_page] != 0) {
  862.         PIGGY_PAGE_IN(Gauges[GAUGE_HOMING_WARNING_OFF]);
  863.         gr_ubitmapm( 7, 171, &GameBitmaps[Gauges[GAUGE_HOMING_WARNING_OFF].index] );
  864.         Last_homing_warning_shown[VR_current_page] = 0;
  865.     }
  866.  
  867. }
  868.  
  869. #define MAX_SHOWN_LIVES 4
  870.  
  871. void hud_show_homing_warning(void)
  872. {
  873.     if (Players[Player_num].homing_object_dist >= 0) {
  874.  
  875.         if (GameTime & 0x4000) {
  876.             //gr_set_current_canvas(&VR_render_sub_buffer[0]);    //render off-screen
  877.             gr_set_curfont( GAME_FONT );
  878.             gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  879.             gr_printf(0x8000, grd_curcanv->cv_h-8,TXT_LOCK);
  880.         }
  881.     }
  882. }
  883.  
  884. void hud_show_keys(void)
  885. {
  886.  
  887.     if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY) {
  888.         PIGGY_PAGE_IN(Gauges[KEY_ICON_BLUE]);
  889.         gr_ubitmapm(2,24,&GameBitmaps[Gauges[KEY_ICON_BLUE].index]);
  890.  
  891.     }
  892.  
  893.     if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY) {
  894.         PIGGY_PAGE_IN(Gauges[KEY_ICON_YELLOW]);
  895.         gr_ubitmapm(10,24,&GameBitmaps[Gauges[KEY_ICON_YELLOW].index]);
  896.     }
  897.  
  898.     if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY) {
  899.         PIGGY_PAGE_IN(Gauges[KEY_ICON_RED]);
  900.         gr_ubitmapm(18,24,&GameBitmaps[Gauges[KEY_ICON_RED].index]);
  901.     }
  902.  
  903. }
  904.  
  905. void hud_show_energy(void)
  906. {
  907.     //gr_set_current_canvas(&VR_render_sub_buffer[0]);    //render off-screen
  908.     gr_set_curfont( GAME_FONT );
  909.     gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  910.     if (Game_mode & GM_MULTI)
  911.         gr_printf(2, grd_curcanv->cv_h-40,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
  912.     else
  913.         gr_printf(2, grd_curcanv->cv_h-8,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
  914.  
  915.     if (Newdemo_state==ND_STATE_RECORDING ) {
  916.         int energy = f2ir(Players[Player_num].energy);
  917.  
  918.         if (energy != old_energy[VR_current_page]) {
  919. #ifdef SHAREWARE
  920.             newdemo_record_player_energy(energy);
  921. #else
  922.             newdemo_record_player_energy(old_energy[VR_current_page], energy);
  923. #endif
  924.             old_energy[VR_current_page] = energy;
  925.          }
  926.     }
  927. }
  928.  
  929. void hud_show_weapons(void)
  930. {
  931.     int    w, h, aw;
  932.     int    y;
  933.     char    weapon_str[32], temp_str[10];
  934.  
  935. //    gr_set_current_canvas(&VR_render_sub_buffer[0]);    //render off-screen
  936.     gr_set_curfont( GAME_FONT );
  937.     gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  938.  
  939.     if (Game_mode & GM_MULTI)
  940.         y = grd_curcanv->cv_h-32;
  941.     else
  942.         y = grd_curcanv->cv_h;
  943.  
  944. //    #ifndef RELEASE
  945.     y -= 8;
  946. //    #endif
  947.  
  948.     switch (Primary_weapon) {
  949.         case 0:
  950.             if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)
  951.                 sprintf(weapon_str, "%s %s %i", TXT_QUAD, TXT_LASER, Players[Player_num].laser_level+1);
  952.             else
  953.                 sprintf(weapon_str, "%s %i", TXT_LASER, Players[Player_num].laser_level+1);
  954.             break;
  955.         case 1:
  956.             sprintf(weapon_str, "%s: %i", TXT_W_VULCAN_S, f2i(Players[Player_num].primary_ammo[Primary_weapon] * VULCAN_AMMO_SCALE));
  957.             break;
  958.         case 2:
  959.             strcpy(weapon_str, TXT_W_SPREADFIRE_S);
  960.             break;
  961.         #ifndef SHAREWARE
  962.         case 3:
  963.             strcpy(weapon_str, TXT_W_PLASMA_S);
  964.             break;
  965.         case 4:
  966.             strcpy(weapon_str, TXT_W_FUSION_S);
  967.             break;
  968.         #endif
  969.     }
  970.  
  971.     gr_get_string_size(weapon_str, &w, &h, &aw );
  972.     gr_printf(grd_curcanv->cv_w-5-w, y-8, weapon_str);
  973.  
  974.     if (Primary_weapon == VULCAN_INDEX) {
  975.  
  976. #ifndef SHAREWARE
  977.         if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0][VR_current_page]) {
  978.             if (Newdemo_state == ND_STATE_RECORDING)
  979.                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[Primary_weapon]);
  980.             old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[Primary_weapon];
  981.         }
  982. #endif
  983.     }
  984.  
  985.     switch (Secondary_weapon) {
  986.         case 0:    strcpy(weapon_str, TXT_CONCUSSION);    break;
  987.         case 1:    strcpy(weapon_str, TXT_HOMING);    break;
  988.         case 2:    strcpy(weapon_str, TXT_PROXBOMB   );    break;
  989.         #ifndef SHAREWARE
  990.         case 3:    strcpy(weapon_str, TXT_SMART);    break;
  991.         case 4:    strcpy(weapon_str, TXT_MEGA);    break;
  992.         #endif
  993.         default:    Int3();    weapon_str[0] = 0;    break;
  994.     }
  995.  
  996. #ifndef SHAREWARE
  997.     if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
  998.         if (Newdemo_state == ND_STATE_RECORDING)
  999.             newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
  1000.         old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
  1001.     }
  1002. #endif
  1003.  
  1004.     strcat(weapon_str, " ");
  1005.     strcat(weapon_str, itoa(Players[Player_num].secondary_ammo[Secondary_weapon], temp_str, 10));
  1006.     gr_get_string_size(weapon_str, &w, &h, &aw );
  1007.     gr_printf(grd_curcanv->cv_w-5-w, y, weapon_str);
  1008. }
  1009.  
  1010. void hud_show_cloak_invuln(void)
  1011. {
  1012.     if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
  1013.         int    y = grd_curcanv->cv_h;
  1014.  
  1015.         if (Game_mode & GM_MULTI)
  1016.             y -= 72;
  1017.         else
  1018.             y -= 32;
  1019.  
  1020.         if ((Players[Player_num].cloak_time+CLOAK_TIME_MAX - GameTime > F1_0*3 ) || (GameTime & 0x8000))
  1021.             gr_printf(2, y, "%s", TXT_CLOAKED);
  1022.     }
  1023.  
  1024.     if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
  1025.         int    y = grd_curcanv->cv_h;
  1026.  
  1027.         if (Game_mode & GM_MULTI)
  1028.             y -= 80;
  1029.         else
  1030.             y -= 40;
  1031.  
  1032.         if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000))
  1033.             gr_printf(2, y, "%s", TXT_INVULNERABLE);
  1034.     }
  1035.  
  1036. }
  1037.  
  1038. void hud_show_shield(void)
  1039. {
  1040. //    gr_set_current_canvas(&VR_render_sub_buffer[0]);    //render off-screen
  1041.     gr_set_curfont( GAME_FONT );
  1042.     gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  1043.     if ( Players[Player_num].shields >= 0 )    {
  1044.         if (Game_mode & GM_MULTI)
  1045.             gr_printf(2, grd_curcanv->cv_h-48,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
  1046.         else
  1047.             gr_printf(2, grd_curcanv->cv_h-16,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
  1048.     } else {
  1049.         if (Game_mode & GM_MULTI)
  1050.             gr_printf(2, grd_curcanv->cv_h-48,"%s: 0", TXT_SHIELD );
  1051.         else
  1052.             gr_printf(2, grd_curcanv->cv_h-16,"%s: 0", TXT_SHIELD );
  1053.     }
  1054.  
  1055.     if (Newdemo_state==ND_STATE_RECORDING ) {
  1056.         int shields = f2ir(Players[Player_num].shields);
  1057.  
  1058.         if (shields != old_shields[VR_current_page]) {        // Draw the shield gauge
  1059. #ifdef SHAREWARE
  1060.             newdemo_record_player_shields(shields);
  1061. #else
  1062.             newdemo_record_player_shields(old_shields[VR_current_page], shields);
  1063. #endif
  1064.             old_shields[VR_current_page] = shields;
  1065.         }
  1066.     }
  1067. }
  1068.  
  1069. //draw the icons for number of lives
  1070. hud_show_lives()
  1071. {
  1072.     if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
  1073.         return;
  1074.  
  1075.     if (Game_mode & GM_MULTI) {
  1076.         gr_set_curfont( GAME_FONT );
  1077.         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  1078.         gr_printf(10, 3, "%s: %d", TXT_DEATHS, Players[Player_num].net_killed_total);
  1079.     } 
  1080.     else if (Players[Player_num].lives > 1)  {
  1081.         gr_set_curfont( GAME_FONT );
  1082.         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  1083.         PIGGY_PAGE_IN(Gauges[GAUGE_LIVES]);
  1084.         gr_ubitmapm(10,3,&GameBitmaps[Gauges[GAUGE_LIVES].index]);
  1085.         gr_printf(22, 3, "x %d", Players[Player_num].lives-1);
  1086.     }
  1087.  
  1088. }
  1089.  
  1090. sb_show_lives()
  1091. {
  1092.     int x,y;
  1093.     grs_bitmap * bm = &GameBitmaps[Gauges[GAUGE_LIVES].index];
  1094.     x = SB_LIVES_X;
  1095.     y = SB_LIVES_Y;
  1096.  
  1097.     if (old_lives[VR_current_page]==-1) {
  1098.         gr_set_curfont( GAME_FONT );
  1099.         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  1100.         if (Game_mode & GM_MULTI)
  1101.             gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS);
  1102.         else
  1103.             gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES);
  1104.     }
  1105.  
  1106.     if (Game_mode & GM_MULTI)
  1107.     {
  1108.         char killed_str[20];
  1109.         int w, h, aw;
  1110.         static int last_x[2] = {SB_SCORE_RIGHT,SB_SCORE_RIGHT};
  1111.         int x;
  1112.  
  1113.         sprintf(killed_str, "%5d", Players[Player_num].net_killed_total);
  1114.         gr_get_string_size(killed_str, &w, &h, &aw);
  1115.         gr_setcolor(BM_XRGB(0,0,0));
  1116.         gr_rect(last_x[VR_current_page], y+1, SB_SCORE_RIGHT, y+GAME_FONT->ft_h);
  1117.         gr_set_fontcolor(gr_getcolor(0,20,0),-1);
  1118.         x = SB_SCORE_RIGHT-w-2;        
  1119.         gr_printf(x, y+1, killed_str);
  1120.         last_x[VR_current_page] = x;
  1121.         return;
  1122.     }
  1123.  
  1124.     if (old_lives[VR_current_page]==-1 || Players[Player_num].lives != old_lives[VR_current_page]) {
  1125.  
  1126.         //erase old icons
  1127.  
  1128.         gr_setcolor(BM_XRGB(0,0,0));
  1129.         gr_rect(x, y, x+32, y+bm->bm_h);
  1130.  
  1131.         if (Players[Player_num].lives-1 > 0) {
  1132.             gr_set_curfont( GAME_FONT );
  1133.             gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  1134.             PIGGY_PAGE_IN(Gauges[GAUGE_LIVES]);
  1135.             gr_ubitmapm(x, y,bm);
  1136.             gr_printf(x+12, y, "x %d", Players[Player_num].lives-1);
  1137.         }
  1138.     }
  1139.  
  1140. //    for (i=0;i<draw_count;i++,x+=bm->bm_w+2)
  1141. //        gr_ubitmapm(x,y,bm);
  1142.  
  1143. }
  1144.  
  1145. #ifndef RELEASE
  1146.  
  1147. #ifdef PIGGY_USE_PAGING
  1148. extern int Piggy_bitmap_cache_next;
  1149. #endif
  1150.  
  1151. void show_time()
  1152. {
  1153.     int secs = f2i(Players[Player_num].time_level) % 60;
  1154.     int mins = f2i(Players[Player_num].time_level) / 60;
  1155.  
  1156.     gr_set_curfont( GAME_FONT );
  1157.  
  1158.     if (Color_0_31_0 == -1)
  1159.         Color_0_31_0 = gr_getcolor(0,31,0);
  1160.     gr_set_fontcolor(Color_0_31_0, -1 );
  1161.  
  1162.     gr_printf(grd_curcanv->cv_w-25,grd_curcanv->cv_h-28,"%d:%02d", mins, secs);
  1163.  
  1164. #ifdef PIGGY_USE_PAGING
  1165.     {
  1166.         char text[25];
  1167.         int w,h,aw;
  1168.         sprintf( text, "%d KB", Piggy_bitmap_cache_next/1024 );
  1169.         gr_get_string_size( text, &w, &h, &aw );    
  1170.         gr_printf(grd_curcanv->cv_w-10-w,grd_curcanv->cv_h/2, text );
  1171.     }
  1172. #endif
  1173.  
  1174. }
  1175. #endif
  1176.  
  1177. #define EXTRA_SHIP_SCORE    50000        //get new ship every this many points
  1178.  
  1179. void add_points_to_score(int points) 
  1180. {
  1181.     int prev_score;
  1182.  
  1183.     score_time += f1_0*2;
  1184.     score_display += points;
  1185.     if (score_time > f1_0*4) score_time = f1_0*4;
  1186.  
  1187.     if (points == 0 || Cheats_enabled)
  1188.         return;
  1189.  
  1190.     if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
  1191.         return;
  1192.  
  1193.     prev_score=Players[Player_num].score;
  1194.  
  1195.     Players[Player_num].score += points;
  1196.  
  1197. #ifndef SHAREWARE
  1198.     if (Newdemo_state == ND_STATE_RECORDING)
  1199.         newdemo_record_player_score(points);
  1200. #endif
  1201.  
  1202. #ifndef SHAREWARE
  1203. #ifdef NETWORK
  1204.     if (Game_mode & GM_MULTI_COOP)
  1205.         multi_send_score();
  1206. #endif
  1207. #endif
  1208.  
  1209.     if (Game_mode & GM_MULTI)
  1210.         return;
  1211.  
  1212.     if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
  1213.         int snd;
  1214.         Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
  1215.         powerup_basic(20, 20, 20, 0, TXT_EXTRA_LIFE);
  1216.         if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
  1217.             digi_play_sample( snd, F1_0 );
  1218.     }
  1219. }
  1220.  
  1221. void add_bonus_points_to_score(int points) 
  1222. {
  1223.     int prev_score;
  1224.  
  1225.     if (points == 0 || Cheats_enabled)
  1226.         return;
  1227.  
  1228.     prev_score=Players[Player_num].score;
  1229.  
  1230.     Players[Player_num].score += points;
  1231.  
  1232.  
  1233. #ifndef SHAREWARE
  1234.     if (Newdemo_state == ND_STATE_RECORDING)
  1235.         newdemo_record_player_score(points);
  1236. #endif
  1237.  
  1238.     if (Game_mode & GM_MULTI)
  1239.         return;
  1240.  
  1241.     if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
  1242.         int snd;
  1243.         Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
  1244.         if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
  1245.             digi_play_sample( snd, F1_0 );
  1246.     }
  1247. }
  1248.  
  1249. void init_gauge_canvases()
  1250. {
  1251.     Canv_LeftEnergyGauge = gr_create_canvas( LEFT_ENERGY_GAUGE_W, LEFT_ENERGY_GAUGE_H );
  1252.     Canv_SBEnergyGauge = gr_create_canvas( SB_ENERGY_GAUGE_W, SB_ENERGY_GAUGE_H );
  1253.     Canv_RightEnergyGauge = gr_create_canvas( RIGHT_ENERGY_GAUGE_W, RIGHT_ENERGY_GAUGE_H );
  1254.     Canv_NumericalGauge = gr_create_canvas( NUMERICAL_GAUGE_W, NUMERICAL_GAUGE_H );
  1255. }
  1256.  
  1257. void close_gauge_canvases()
  1258. {
  1259.     gr_free_canvas( Canv_LeftEnergyGauge );
  1260.     gr_free_canvas( Canv_SBEnergyGauge );
  1261.     gr_free_canvas( Canv_RightEnergyGauge );
  1262.     gr_free_canvas( Canv_NumericalGauge );
  1263. }
  1264.  
  1265. void init_gauges()
  1266. {
  1267.     int i;
  1268.  
  1269.     //draw_gauges_on     = 1;
  1270.  
  1271.     for (i=0; i<2; i++ )    {
  1272.         if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) || ((Newdemo_state == ND_STATE_PLAYBACK) && (Newdemo_game_mode & GM_MULTI) && !(Newdemo_game_mode & GM_MULTI_COOP)) ) 
  1273.             old_score[i] = -99;
  1274.         else
  1275.             old_score[i]            = -1;
  1276.         old_energy[i]            = -1;
  1277.         old_shields[i]            = -1;
  1278.         old_flags[i]            = -1;
  1279.         old_cloak[i]            = -1;
  1280.         old_lives[i]            = -1;
  1281.     
  1282.         old_weapon[0][i] = old_weapon[1][i] = -1;
  1283.         old_ammo_count[0][i] = old_ammo_count[1][i] = -1;
  1284.     }
  1285.  
  1286.     cloak_fade_state = 0;
  1287. }
  1288.  
  1289. void draw_energy_bar(int energy)
  1290. {
  1291.     int not_energy;
  1292.     int x1, x2, y;
  1293.  
  1294.     // Draw left energy bar
  1295.     gr_set_current_canvas( Canv_LeftEnergyGauge );
  1296.     PIGGY_PAGE_IN(Gauges[GAUGE_ENERGY_LEFT]);
  1297.     gr_ubitmapm( 0, 0, &GameBitmaps[Gauges[GAUGE_ENERGY_LEFT].index] );
  1298.     gr_setcolor( 0 );
  1299.  
  1300.     not_energy = 61 - (energy*61)/100;
  1301.  
  1302.     if (energy < 100)
  1303.         for (y=0; y<8; y++) {
  1304.             x1 = 7 - y;
  1305.             x2 = 7 - y + not_energy;
  1306.     
  1307.             if ( y>=0 && y<2 ) if (x2 > LEFT_ENERGY_GAUGE_W - 1) x2 = LEFT_ENERGY_GAUGE_W - 1;
  1308.             if ( y>=2 && y<6 ) if (x2 > LEFT_ENERGY_GAUGE_W - 2) x2 = LEFT_ENERGY_GAUGE_W - 2;
  1309.             if ( y>=6 ) if (x2 > LEFT_ENERGY_GAUGE_W - 3) x2 = LEFT_ENERGY_GAUGE_W - 3;
  1310.             
  1311.             if (x2 > x1) gr_uscanline( x1, x2, y ); 
  1312.         }
  1313.  
  1314.     gr_set_current_canvas( get_current_game_screen() );
  1315.     gr_ubitmapm( LEFT_ENERGY_GAUGE_X, LEFT_ENERGY_GAUGE_Y, &Canv_LeftEnergyGauge->cv_bitmap );
  1316.  
  1317.     // Draw right energy bar
  1318.     gr_set_current_canvas( Canv_RightEnergyGauge );
  1319.     PIGGY_PAGE_IN(Gauges[GAUGE_ENERGY_RIGHT]);
  1320.     gr_ubitmapm( 0, 0, &GameBitmaps[Gauges[GAUGE_ENERGY_RIGHT].index] );
  1321.  
  1322.     if (energy < 100)
  1323.         for (y=0; y<8; y++) {
  1324.             x1 = RIGHT_ENERGY_GAUGE_W - 8 + y - not_energy;
  1325.             x2 = RIGHT_ENERGY_GAUGE_W - 8 + y;
  1326.     
  1327.             if ( y>=0 && y<2 ) if (x1 < 0) x1 = 0;
  1328.             if ( y>=2 && y<6 ) if (x1 < 1) x1 = 1;
  1329.             if ( y>=6 ) if (x1 < 2) x1 = 2;
  1330.             
  1331.             if (x2 > x1) gr_uscanline( x1, x2, y ); 
  1332.         }
  1333.  
  1334.     gr_set_current_canvas( get_current_game_screen() );
  1335.     gr_ubitmapm( RIGHT_ENERGY_GAUGE_X, RIGHT_ENERGY_GAUGE_Y, &Canv_RightEnergyGauge->cv_bitmap );
  1336.  
  1337. }
  1338.  
  1339. void draw_shield_bar(int shield)
  1340. {
  1341.     int bm_num = shield>=100?9:(shield / 10);
  1342.  
  1343.     PIGGY_PAGE_IN(Gauges[GAUGE_SHIELDS+9-bm_num]    );
  1344.     gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[Gauges[GAUGE_SHIELDS+9-bm_num].index] );
  1345.  
  1346. }
  1347.  
  1348. #define CLOAK_FADE_WAIT_TIME  0x400
  1349.  
  1350. void draw_player_ship(int cloak_state,int old_cloak_state,int x, int y)
  1351. {
  1352.     static fix cloak_fade_timer=0;
  1353.     static int cloak_fade_value=GR_FADE_LEVELS-1;
  1354.     grs_bitmap *bm;
  1355.  
  1356.     if (Game_mode & GM_TEAM)    {
  1357.         #ifdef NETWORK
  1358.         PIGGY_PAGE_IN(Gauges[GAUGE_SHIPS+get_team(Player_num)]);
  1359.         bm = &GameBitmaps[Gauges[GAUGE_SHIPS+get_team(Player_num)].index];
  1360.         #endif
  1361.     } else {
  1362.         PIGGY_PAGE_IN(Gauges[GAUGE_SHIPS+Player_num]);
  1363.         bm = &GameBitmaps[Gauges[GAUGE_SHIPS+Player_num].index];
  1364.     }
  1365.     
  1366.  
  1367.     if (old_cloak_state==-1 && cloak_state)
  1368.             cloak_fade_value=0;
  1369.  
  1370.     if (!cloak_state) {
  1371.         cloak_fade_value=GR_FADE_LEVELS-1;
  1372.         cloak_fade_state = 0;
  1373.     }
  1374.  
  1375.     if (cloak_state==1 && old_cloak_state==0)
  1376.         cloak_fade_state = -1;
  1377.     //else if (cloak_state==0 && old_cloak_state==1)
  1378.     //    cloak_fade_state = 1;
  1379.  
  1380.     if (cloak_state==old_cloak_state)        //doing "about-to-uncloak" effect
  1381.         if (cloak_fade_state==0)
  1382.             cloak_fade_state = 2;
  1383.     
  1384.  
  1385.     if (cloak_fade_state)
  1386.         cloak_fade_timer -= FrameTime;
  1387.  
  1388.     while (cloak_fade_state && cloak_fade_timer < 0) {
  1389.  
  1390.         cloak_fade_timer += CLOAK_FADE_WAIT_TIME;
  1391.  
  1392.         cloak_fade_value += cloak_fade_state;
  1393.  
  1394.         if (cloak_fade_value >= GR_FADE_LEVELS-1) {
  1395.             cloak_fade_value = GR_FADE_LEVELS-1;
  1396.             if (cloak_fade_state == 2 && cloak_state)
  1397.                 cloak_fade_state = -2;
  1398.             else
  1399.                 cloak_fade_state = 0;
  1400.         }
  1401.         else if (cloak_fade_value <= 0) {
  1402.             cloak_fade_value = 0;
  1403.             if (cloak_fade_state == -2)
  1404.                 cloak_fade_state = 2;
  1405.             else
  1406.                 cloak_fade_state = 0;
  1407.         }
  1408.     }
  1409.  
  1410.     gr_set_current_canvas(&VR_render_buffer[0]);
  1411.     gr_ubitmap( x, y, bm);
  1412.  
  1413.     Gr_scanline_darkening_level = cloak_fade_value;
  1414.     gr_rect(x, y, x+bm->bm_w-1, y+bm->bm_h-1);
  1415.     Gr_scanline_darkening_level = GR_FADE_LEVELS;
  1416.  
  1417.     gr_set_current_canvas(get_current_game_screen());
  1418.     gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &VR_render_buffer[0].cv_bitmap, &grd_curcanv->cv_bitmap);
  1419.  
  1420. }
  1421.  
  1422. #define INV_FRAME_TIME    (f1_0/10)        //how long for each frame
  1423.  
  1424. void draw_numerical_display(int shield, int energy)
  1425. {
  1426.     gr_set_current_canvas( Canv_NumericalGauge );
  1427.     gr_set_curfont( GAME_FONT );
  1428.     PIGGY_PAGE_IN(Gauges[GAUGE_NUMERICAL]);
  1429.     gr_ubitmap( 0, 0, &GameBitmaps[Gauges[GAUGE_NUMERICAL].index] );
  1430.  
  1431.     gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
  1432.  
  1433.     gr_printf((shield>99)?3:((shield>9)?5:7),15,"%d",shield);
  1434.  
  1435.     gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
  1436.     gr_printf((energy>99)?3:((energy>9)?5:7),2,"%d",energy);
  1437.                       
  1438.     gr_set_current_canvas( get_current_game_screen() );
  1439.     gr_ubitmapm( NUMERICAL_GAUGE_X, NUMERICAL_GAUGE_Y, &Canv_NumericalGauge->cv_bitmap );
  1440. }
  1441.  
  1442.  
  1443. void draw_keys()
  1444. {
  1445.     gr_set_current_canvas( get_current_game_screen() );
  1446.  
  1447.     if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY )    {
  1448.         PIGGY_PAGE_IN(Gauges[GAUGE_BLUE_KEY]);
  1449.         gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[Gauges[GAUGE_BLUE_KEY].index] );
  1450.     } else {
  1451.         PIGGY_PAGE_IN(Gauges[GAUGE_BLUE_KEY_OFF]);
  1452.         gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[Gauges[GAUGE_BLUE_KEY_OFF].index] );
  1453.     }
  1454.  
  1455.     if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)    {
  1456.         PIGGY_PAGE_IN(Gauges[GAUGE_GOLD_KEY]);
  1457.         gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[Gauges[GAUGE_GOLD_KEY].index] );
  1458.     } else {
  1459.         PIGGY_PAGE_IN(Gauges[GAUGE_GOLD_KEY_OFF]);
  1460.         gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[Gauges[GAUGE_GOLD_KEY_OFF].index] );
  1461.     }
  1462.  
  1463.     if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)    {
  1464.         PIGGY_PAGE_IN( Gauges[GAUGE_RED_KEY] );
  1465.         gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[Gauges[GAUGE_RED_KEY].index] );
  1466.     } else {
  1467.         PIGGY_PAGE_IN(Gauges[GAUGE_RED_KEY_OFF]);
  1468.         gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[Gauges[GAUGE_RED_KEY_OFF].index] );
  1469.     }
  1470. }
  1471.  
  1472.  
  1473. draw_weapon_info_sub(int info_index,gauge_box *box,int pic_x,int pic_y,char *name,int text_x,int text_y)
  1474. {
  1475.     grs_bitmap *bm;
  1476.     char *p;
  1477.  
  1478.     //clear the window
  1479.     gr_setcolor(BM_XRGB(0,0,0));
  1480.     gr_rect(box->left,box->top,box->right,box->bot);
  1481.  
  1482.     bm=&GameBitmaps[Weapon_info[info_index].picture.index];
  1483.     Assert(bm != NULL);
  1484.  
  1485.     PIGGY_PAGE_IN( Weapon_info[info_index].picture );
  1486.     gr_ubitmapm(pic_x,pic_y,bm);
  1487.  
  1488.     gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
  1489.  
  1490.     if ((p=strchr(name,'\n'))!=NULL) {
  1491.         *p=0;
  1492.         gr_printf(text_x,text_y,name);
  1493.         gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
  1494.         *p='\n';
  1495.     } else
  1496.         gr_printf(text_x,text_y,name);
  1497.  
  1498.     //    For laser, show level and quadness
  1499.     if (info_index == 0) {
  1500.         char    temp_str[7];
  1501.  
  1502.         sprintf(temp_str, "%s: 0", TXT_LVL);
  1503.  
  1504.         temp_str[5] = Players[Player_num].laser_level+1 + '0';
  1505.  
  1506.         gr_printf(text_x,text_y+8, temp_str);
  1507.  
  1508.         if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
  1509.             strcpy(temp_str, TXT_QUAD);
  1510.             gr_printf(text_x,text_y+16, temp_str);
  1511.         }
  1512.  
  1513.     }
  1514. }
  1515.  
  1516.  
  1517. draw_weapon_info(int weapon_type,int weapon_num)
  1518. {
  1519. #ifdef SHAREWARE
  1520.     if (Newdemo_state==ND_STATE_RECORDING )
  1521.         newdemo_record_player_weapon(weapon_type, weapon_num);
  1522. #endif
  1523.     if (weapon_type == 0)
  1524.         if (Cockpit_mode == CM_STATUS_BAR)
  1525.             draw_weapon_info_sub(Primary_weapon_to_weapon_info[weapon_num],
  1526.                 &gauge_boxes[2],
  1527.                 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
  1528.                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
  1529.                 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
  1530.         else
  1531.             draw_weapon_info_sub(Primary_weapon_to_weapon_info[weapon_num],
  1532.                 &gauge_boxes[0],
  1533.                 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
  1534.                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
  1535.                 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
  1536.  
  1537.     else
  1538.         if (Cockpit_mode == CM_STATUS_BAR)
  1539.             draw_weapon_info_sub(Secondary_weapon_to_weapon_info[weapon_num],
  1540.                 &gauge_boxes[3],
  1541.                 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
  1542.                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
  1543.                 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
  1544.         else
  1545.             draw_weapon_info_sub(Secondary_weapon_to_weapon_info[weapon_num],
  1546.                 &gauge_boxes[1],
  1547.                 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
  1548.                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
  1549.                 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
  1550. }
  1551.  
  1552. draw_ammo_info(int x,int y,int ammo_count,int primary)
  1553. {
  1554.     int w;
  1555.  
  1556.     if (primary)
  1557.         w = (grd_curcanv->cv_font->ft_w*6)/2;
  1558.     else
  1559.         w = (grd_curcanv->cv_font->ft_w*5)/2;
  1560.  
  1561.     gr_setcolor(BM_XRGB(0,0,0));
  1562.     gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
  1563.  
  1564.     gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
  1565.     gr_printf(x,y,"%03d",ammo_count);
  1566. }
  1567.  
  1568. draw_primary_ammo_info(int ammo_count)
  1569. {
  1570.     if (Cockpit_mode == CM_STATUS_BAR)
  1571.         draw_ammo_info(SB_PRIMARY_AMMO_X,SB_PRIMARY_AMMO_Y,ammo_count,1);
  1572.     else
  1573.         draw_ammo_info(PRIMARY_AMMO_X,PRIMARY_AMMO_Y,ammo_count,1);
  1574. }
  1575.  
  1576. draw_secondary_ammo_info(int ammo_count)
  1577. {
  1578.     if (Cockpit_mode == CM_STATUS_BAR)
  1579.         draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
  1580.     else
  1581.         draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
  1582. }
  1583.  
  1584. //returns true if drew picture
  1585. int draw_weapon_box(int weapon_type,int weapon_num)
  1586. {
  1587.     int drew_flag=0;
  1588.  
  1589.     gr_set_current_canvas(&VR_render_buffer[0]);
  1590.     gr_set_curfont( GAME_FONT );
  1591.  
  1592.     if (weapon_num != old_weapon[weapon_type][VR_current_page] && weapon_box_states[weapon_type] == WS_SET) {
  1593.         weapon_box_states[weapon_type] = WS_FADING_OUT;
  1594.         weapon_box_fade_values[weapon_type]=i2f(GR_FADE_LEVELS-1);
  1595.     }
  1596.         
  1597.     if (old_weapon[weapon_type][VR_current_page] == -1) {
  1598.         draw_weapon_info(weapon_type,weapon_num);
  1599.         old_weapon[weapon_type][VR_current_page] = weapon_num;
  1600.         old_ammo_count[weapon_type][VR_current_page]=-1;
  1601.         drew_flag=1;
  1602.         weapon_box_states[weapon_type] = WS_SET;
  1603.     }
  1604.  
  1605.     if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
  1606.         draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page]);
  1607.         old_ammo_count[weapon_type][VR_current_page]=-1;
  1608.         drew_flag=1;
  1609.         weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
  1610.         if (weapon_box_fade_values[weapon_type] <= 0) {
  1611.             weapon_box_states[weapon_type] = WS_FADING_IN;
  1612.             old_weapon[weapon_type][VR_current_page] = weapon_num;
  1613.             weapon_box_fade_values[weapon_type] = 0;
  1614.         }
  1615.     }
  1616.     else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
  1617.         if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
  1618.             weapon_box_states[weapon_type] = WS_FADING_OUT;
  1619.         }
  1620.         else {
  1621.             draw_weapon_info(weapon_type,weapon_num);
  1622.             old_ammo_count[weapon_type][VR_current_page]=-1;
  1623.             drew_flag=1;
  1624.             weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
  1625.             if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1))
  1626.                 weapon_box_states[weapon_type] = WS_SET;
  1627.         }
  1628.     }
  1629.  
  1630.     if (weapon_box_states[weapon_type] != WS_SET) {        //fade gauge
  1631.         int fade_value = f2i(weapon_box_fade_values[weapon_type]);
  1632.         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?2:0;
  1633.  
  1634.         Gr_scanline_darkening_level = fade_value;
  1635.         gr_rect(gauge_boxes[boxofs+weapon_type].left,gauge_boxes[boxofs+weapon_type].top,gauge_boxes[boxofs+weapon_type].right,gauge_boxes[boxofs+weapon_type].bot);
  1636.         Gr_scanline_darkening_level = GR_FADE_LEVELS;
  1637.     }
  1638.  
  1639.     gr_set_current_canvas(get_current_game_screen());
  1640.  
  1641.     return drew_flag;
  1642.  
  1643.  
  1644. }
  1645.  
  1646. draw_weapon_boxes()
  1647. {
  1648.     int boxofs = (Cockpit_mode==CM_STATUS_BAR)?2:0;
  1649.     int drew;
  1650.  
  1651.     drew = draw_weapon_box(0,Primary_weapon);
  1652.     if (drew) copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap);
  1653.  
  1654.     if (weapon_box_states[0] == WS_SET)
  1655.         if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0][VR_current_page]) {
  1656.             if (Primary_weapon == VULCAN_INDEX) {
  1657. #ifndef SHAREWARE
  1658.                 if (Newdemo_state == ND_STATE_RECORDING)
  1659.                     newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[Primary_weapon]);
  1660. #endif
  1661.                 draw_primary_ammo_info(f2i(VULCAN_AMMO_SCALE * Players[Player_num].primary_ammo[Primary_weapon]));
  1662.                 old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[Primary_weapon];
  1663.             }
  1664.         }
  1665.  
  1666.     if (!hostage_is_vclip_playing()) {
  1667.         drew = draw_weapon_box(1,Secondary_weapon);
  1668.         if (drew) copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap);
  1669.  
  1670.         if (weapon_box_states[1] == WS_SET)
  1671.             if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
  1672. #ifndef SHAREWARE
  1673.                 if (Newdemo_state == ND_STATE_RECORDING)
  1674.                     newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
  1675. #endif
  1676.                 draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
  1677.                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
  1678.             }
  1679.     }
  1680. }
  1681.  
  1682.  
  1683. sb_draw_energy_bar(energy)
  1684. {
  1685.     int erase_height;
  1686.  
  1687.     gr_set_current_canvas( Canv_SBEnergyGauge );
  1688.     PIGGY_PAGE_IN(Gauges[SB_GAUGE_ENERGY]);
  1689.     gr_ubitmapm( 0, 0, &GameBitmaps[Gauges[SB_GAUGE_ENERGY].index] );
  1690.  
  1691.     erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
  1692.  
  1693.     if (erase_height > 0) {
  1694.         gr_setcolor( 0 );
  1695.         gr_rect(0,0,SB_ENERGY_GAUGE_W-1,erase_height-1);
  1696.     }
  1697.  
  1698.     gr_set_current_canvas( get_current_game_screen() );
  1699.     gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap );
  1700.  
  1701.     //draw numbers
  1702.     gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
  1703.     gr_printf((energy>99)?SB_ENERGY_NUM_X:((energy>9)?SB_ENERGY_NUM_X+2:SB_ENERGY_NUM_X+4),SB_ENERGY_NUM_Y,"%d",energy);
  1704.                       
  1705. }
  1706.  
  1707. sb_draw_shield_num(int shield)
  1708. {
  1709.     grs_bitmap *bm = &GameBitmaps[cockpit_bitmap[Cockpit_mode].index];
  1710.  
  1711.     //draw numbers
  1712.  
  1713.     gr_set_curfont( GAME_FONT );
  1714.     gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
  1715.  
  1716.     //erase old one
  1717.     PIGGY_PAGE_IN( cockpit_bitmap[Cockpit_mode] );
  1718.     gr_setcolor(gr_gpixel(bm,SB_SHIELD_NUM_X,SB_SHIELD_NUM_Y-(VR_render_height-bm->bm_h)));
  1719.     gr_rect(SB_SHIELD_NUM_X,SB_SHIELD_NUM_Y,SB_SHIELD_NUM_X+13,SB_SHIELD_NUM_Y+GAME_FONT->ft_h);
  1720.  
  1721.     gr_printf((shield>99)?SB_SHIELD_NUM_X:((shield>9)?SB_SHIELD_NUM_X+2:SB_SHIELD_NUM_X+4),SB_SHIELD_NUM_Y,"%d",shield);
  1722. }
  1723.  
  1724. sb_draw_shield_bar(int shield)
  1725. {
  1726.     int bm_num = shield>=100?9:(shield / 10);
  1727.  
  1728.     gr_set_current_canvas( get_current_game_screen() );
  1729.  
  1730.     PIGGY_PAGE_IN( Gauges[GAUGE_SHIELDS+9-bm_num] );
  1731.     gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[Gauges[GAUGE_SHIELDS+9-bm_num].index] );
  1732.  
  1733. }
  1734.  
  1735. sb_draw_keys()
  1736. {
  1737.     grs_bitmap * bm;
  1738.     int flags = Players[Player_num].flags;
  1739.  
  1740.     gr_set_current_canvas( get_current_game_screen() );
  1741.  
  1742.     bm = &GameBitmaps[Gauges[(flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF].index];
  1743.     PIGGY_PAGE_IN(Gauges[(flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF]);
  1744.     gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
  1745.     bm = &GameBitmaps[Gauges[(flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF].index];
  1746.     PIGGY_PAGE_IN(Gauges[(flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF]);
  1747.     gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
  1748.     bm = &GameBitmaps[Gauges[(flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF].index];
  1749.     PIGGY_PAGE_IN(Gauges[(flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF]);
  1750.     gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
  1751.  
  1752. }
  1753.  
  1754. //    Draws invulnerable ship, or maybe the flashing ship, depending on invulnerability time left.
  1755. void draw_invulnerable_ship()
  1756. {
  1757.     static fix time=0;
  1758.  
  1759.     gr_set_current_canvas( get_current_game_screen() );
  1760.  
  1761.     if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000)) {
  1762.  
  1763.         if (Cockpit_mode == CM_STATUS_BAR)    {
  1764.             PIGGY_PAGE_IN(Gauges[GAUGE_INVULNERABLE+invulnerable_frame]);
  1765.             gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[Gauges[GAUGE_INVULNERABLE+invulnerable_frame].index] );
  1766.         } else {
  1767.             PIGGY_PAGE_IN(Gauges[GAUGE_INVULNERABLE+invulnerable_frame]);
  1768.             gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[Gauges[GAUGE_INVULNERABLE+invulnerable_frame].index] );
  1769.         }
  1770.  
  1771.         time += FrameTime;
  1772.  
  1773.         while (time > INV_FRAME_TIME) {
  1774.             time -= INV_FRAME_TIME;
  1775.             if (++invulnerable_frame == N_INVULNERABLE_FRAMES)
  1776.                 invulnerable_frame=0;
  1777.         }
  1778.     } else if (Cockpit_mode == CM_STATUS_BAR)
  1779.         sb_draw_shield_bar(f2ir(Players[Player_num].shields));
  1780.     else
  1781.         draw_shield_bar(f2ir(Players[Player_num].shields));
  1782. }
  1783.  
  1784. #ifdef HOSTAGE_FACES
  1785. draw_hostage_gauge()
  1786. {
  1787.     int drew;
  1788.  
  1789.     gr_set_current_canvas(Canv_game_offscrn);
  1790.  
  1791.     drew = do_hostage_effects();
  1792.  
  1793.     if (drew) {
  1794.         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?2:0;
  1795.  
  1796.         gr_set_current_canvas(Canv_game);
  1797.         copy_gauge_box(&gauge_boxes[boxofs+1],&Canv_game_offscrn->cv_bitmap);
  1798.  
  1799.         old_weapon[1][VR_current_page] = old_ammo_count[1][VR_current_page] = -1;
  1800.     }
  1801.  
  1802. }
  1803. #endif
  1804.  
  1805. extern int Missile_gun;
  1806. extern int allowed_to_fire_laser(void);
  1807. extern int allowed_to_fire_missile(void);
  1808.  
  1809. rgb player_rgb[] = {
  1810.                             {15,15,23},
  1811.                             {27,0,0},
  1812.                             {0,23,0},
  1813.                             {30,11,31},
  1814.                             {31,16,0},
  1815.                             {24,17,6},
  1816.                             {14,21,12},
  1817.                             {29,29,0},
  1818.                         };
  1819.  
  1820.  
  1821. //draw the reticle
  1822. show_reticle(int force_big_one)
  1823. {
  1824.     int x,y;
  1825.     int laser_ready,missile_ready,laser_ammo,missile_ammo;
  1826.     int cross_bm_num,primary_bm_num,secondary_bm_num;
  1827.  
  1828.     x = grd_curcanv->cv_w/2;
  1829.     y = grd_curcanv->cv_h/2;
  1830.  
  1831.     laser_ready = allowed_to_fire_laser();
  1832.     missile_ready = allowed_to_fire_missile();
  1833.  
  1834.     laser_ammo = player_has_weapon(Primary_weapon,0);
  1835.     missile_ammo = player_has_weapon(Secondary_weapon,1);
  1836.  
  1837.     primary_bm_num = (laser_ready && laser_ammo==HAS_ALL);
  1838.     secondary_bm_num = (missile_ready && missile_ammo==HAS_ALL);
  1839.  
  1840.     if (primary_bm_num && Primary_weapon==LASER_INDEX && (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS))
  1841.         primary_bm_num++;
  1842.  
  1843.     if (Secondary_weapon!=CONCUSSION_INDEX && Secondary_weapon!=HOMING_INDEX)
  1844.         secondary_bm_num += 3;        //now value is 0,1 or 3,4
  1845.     else if (secondary_bm_num && !(Missile_gun&1))
  1846.             secondary_bm_num++;
  1847.  
  1848.     cross_bm_num = ((primary_bm_num > 0) || (secondary_bm_num > 0));
  1849.  
  1850.     Assert(primary_bm_num <= 2);
  1851.     Assert(secondary_bm_num <= 4);
  1852.     Assert(cross_bm_num <= 1);
  1853.  
  1854.     if (grd_curcanv->cv_bitmap.bm_w > 200 || force_big_one) {
  1855.         PIGGY_PAGE_IN(Gauges[RETICLE_CROSS + cross_bm_num]);
  1856.         gr_ubitmapm(x-4 ,y-2,&GameBitmaps[Gauges[RETICLE_CROSS + cross_bm_num].index]);
  1857.         PIGGY_PAGE_IN(Gauges[RETICLE_PRIMARY + primary_bm_num]);
  1858.         gr_ubitmapm(x-15,y+6,&GameBitmaps[Gauges[RETICLE_PRIMARY + primary_bm_num].index]);
  1859.         PIGGY_PAGE_IN(Gauges[RETICLE_SECONDARY + secondary_bm_num]);
  1860.         gr_ubitmapm(x-12,y+1,&GameBitmaps[Gauges[RETICLE_SECONDARY + secondary_bm_num].index]);
  1861.     }
  1862.     else {
  1863.         PIGGY_PAGE_IN(Gauges[SML_RETICLE_CROSS + cross_bm_num]);
  1864.         gr_ubitmapm(x-2,y-1,&GameBitmaps[Gauges[SML_RETICLE_CROSS + cross_bm_num].index]);
  1865.         PIGGY_PAGE_IN(Gauges[SML_RETICLE_PRIMARY + primary_bm_num]);
  1866.         gr_ubitmapm(x-8,y+2,&GameBitmaps[Gauges[SML_RETICLE_PRIMARY + primary_bm_num].index]);
  1867.         PIGGY_PAGE_IN(Gauges[SML_RETICLE_SECONDARY + secondary_bm_num]);
  1868.         gr_ubitmapm(x-6,y-2,&GameBitmaps[Gauges[SML_RETICLE_SECONDARY + secondary_bm_num].index]);
  1869.     }
  1870.  
  1871. #ifndef SHAREWARE
  1872. #ifdef NETWORK
  1873.     if ((Newdemo_state == ND_STATE_PLAYBACK) || (((Game_mode & GM_MULTI_COOP) || (Game_mode & GM_TEAM)) && Show_reticle_name))
  1874.     {
  1875.         // Draw player callsign for player in sights 
  1876.         fvi_query fq;
  1877.         vms_vector orient;
  1878.         int Hit_type;
  1879.         fvi_info Hit_data;
  1880.  
  1881.         fq.p0         = &ConsoleObject->pos;
  1882.         orient         = ConsoleObject->orient.fvec;
  1883.         vm_vec_scale(&orient, F1_0*1024);
  1884.         vm_vec_add2(&orient, fq.p0);
  1885.         fq.p1         = &orient;
  1886.         fq.rad         = 0;
  1887.         fq.thisobjnum = ConsoleObject - Objects;
  1888.         fq.flags     = FQ_TRANSWALL | FQ_CHECK_OBJS;
  1889.         fq.startseg    = ConsoleObject->segnum;
  1890.         fq.ignore_obj_list = NULL;
  1891.  
  1892.         Hit_type = find_vector_intersection(&fq, &Hit_data);
  1893.         if ((Hit_type == HIT_OBJECT) && (Objects[Hit_data.hit_object].type == OBJ_PLAYER))
  1894.         {
  1895.             // Draw callsign on HUD
  1896.             char s[CALLSIGN_LEN+1];
  1897.             int w, h, aw;
  1898.             int x1, y1;
  1899.             int pnum;
  1900.             int color_num;
  1901.  
  1902.             pnum = Objects[Hit_data.hit_object].id;
  1903.  
  1904.             if ((Game_mode & GM_TEAM) && (get_team(pnum) != get_team(Player_num)) && (Newdemo_state != ND_STATE_PLAYBACK))
  1905.                 return;
  1906.  
  1907.             if (Game_mode & GM_TEAM)
  1908.                 color_num = get_team(pnum);
  1909.             else
  1910.                 color_num = pnum;
  1911.             sprintf(s, "%s", Players[pnum].callsign);
  1912.             gr_get_string_size(s, &w, &h, &aw);
  1913.             gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
  1914.             x1 = x-(w/2);
  1915.             y1 = y+12;
  1916.             gr_string (x1, y1, s);
  1917. //             }
  1918.         }
  1919. #ifndef NDEBUG
  1920.         else if ((Hit_type == HIT_OBJECT) && (Objects[Hit_data.hit_object].type == OBJ_ROBOT))
  1921.         {
  1922.             char s[CALLSIGN_LEN+1];
  1923.             int w, h, aw;
  1924.             int x1, y1;
  1925.             int color_num = 0;
  1926.  
  1927.             sprintf(s, "%d", Hit_data.hit_object);
  1928.             gr_get_string_size(s, &w, &h, &aw);
  1929.             gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
  1930.             x1 = x-(w/2);
  1931.             y1 = y+12;
  1932.             gr_string (x1, y1, s);
  1933.         }
  1934. #endif
  1935.     }
  1936. #endif
  1937. #endif
  1938. }
  1939.  
  1940. #ifdef NETWORK
  1941. hud_show_kill_list()
  1942. {
  1943.     int n_players,player_list[MAX_NUM_NET_PLAYERS];
  1944.     int n_left,i,x0,x1,y,save_y,fth;
  1945.  
  1946.     if (Show_kill_list_timer > 0)
  1947.     {
  1948.         Show_kill_list_timer -= FrameTime;
  1949.         if (Show_kill_list_timer < 0)
  1950.             Show_kill_list = 0;
  1951.     }
  1952.     
  1953. #ifdef SHAREWARE
  1954.     if (Game_mode & GM_MULTI_COOP)
  1955.     {
  1956.         Show_kill_list = 0;
  1957.         return;
  1958.     }
  1959. #endif
  1960.  
  1961.     gr_set_curfont( GAME_FONT );
  1962.  
  1963.     n_players = multi_get_kill_list(player_list);
  1964.  
  1965.     if (Show_kill_list == 2)
  1966.         n_players = 2;
  1967.  
  1968.     if (n_players <= 4)
  1969.         n_left = n_players;
  1970.     else
  1971.         n_left = (n_players+1)/2;
  1972.  
  1973.     //If font size changes, this code might not work right anymore 
  1974.     Assert(GAME_FONT->ft_h==5 && GAME_FONT->ft_w==7);
  1975.  
  1976.     fth = GAME_FONT->ft_h;
  1977.  
  1978.     x0 = 1; x1 = 43;
  1979.  
  1980. #ifndef SHAREWARE
  1981.     if (Game_mode & GM_MULTI_COOP)
  1982.         x1 = 31;
  1983. #endif
  1984.  
  1985.     save_y = y = grd_curcanv->cv_h - n_left*(fth+1);
  1986.  
  1987.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  1988.         save_y = y -= 6;
  1989. #ifndef SHAREWARE
  1990.         if (Game_mode & GM_MULTI_COOP)
  1991.             x1 = 33;
  1992.         else
  1993. #endif
  1994.             x1 = 43;
  1995.     }
  1996.  
  1997.     for (i=0;i<n_players;i++) {
  1998.         int player_num;
  1999.         char name[9];
  2000.         int sw,sh,aw;
  2001.  
  2002.         if (i==n_left) {
  2003.             if (Cockpit_mode == CM_FULL_COCKPIT)
  2004.                 x0 = grd_curcanv->cv_w - 53;
  2005.             else
  2006.                 x0 = grd_curcanv->cv_w - 60;
  2007. #ifndef SHAREWARE
  2008.             if (Game_mode & GM_MULTI_COOP)
  2009.                 x1 = grd_curcanv->cv_w - 27;
  2010.             else
  2011. #endif
  2012.                 x1 = grd_curcanv->cv_w - 15;
  2013.             y = save_y;
  2014.         }
  2015.     
  2016.         if (Show_kill_list == 2)
  2017.             player_num = i;
  2018.         else
  2019.             player_num = player_list[i];
  2020.  
  2021.         if (Show_kill_list == 1)
  2022.         {
  2023.             int color;
  2024.  
  2025.             if (Players[player_num].connected != 1)
  2026.                 gr_set_fontcolor(gr_getcolor(12, 12, 12), -1);
  2027.             else if (Game_mode & GM_TEAM) {
  2028.                 color = get_team(player_num);
  2029.                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
  2030.             }
  2031.             else {
  2032.                 color = player_num;
  2033.                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
  2034.             }
  2035.         }    
  2036.  
  2037.         else 
  2038.         {
  2039.             gr_set_fontcolor(gr_getcolor(player_rgb[player_num].r,player_rgb[player_num].g,player_rgb[player_num].b),-1 );
  2040.         }
  2041.  
  2042.         if (Show_kill_list == 2)
  2043.             strcpy(name, Netgame.team_name[i]);
  2044.         else
  2045.             strcpy(name,Players[player_num].callsign);    // Note link to above if!!
  2046.         gr_get_string_size(name,&sw,&sh,&aw);
  2047.         while (sw > (x1-x0-3)) {
  2048.             name[strlen(name)-1]=0;
  2049.             gr_get_string_size(name,&sw,&sh,&aw);
  2050.         }
  2051.         gr_printf(x0,y,"%s",name);
  2052.         if (Show_kill_list == 2)    
  2053.             gr_printf(x1,y,"%3d",team_kills[i]);
  2054. #ifndef SHAREWARE
  2055.         else if (Game_mode & GM_MULTI_COOP)
  2056.             gr_printf(x1,y,"%-6d",Players[player_num].score);
  2057. #endif
  2058.         else
  2059.             gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
  2060.         y += fth+1;
  2061.  
  2062.     }
  2063. }
  2064. #endif
  2065.  
  2066. //draw all the things on the HUD
  2067. void draw_hud()
  2068. {
  2069.     //    Show score so long as not in rearview
  2070.     if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && Cockpit_mode!=CM_STATUS_BAR) {
  2071.         hud_show_score();
  2072.         if (score_time)
  2073.             hud_show_score_added();
  2074.     }
  2075.  
  2076.     //    Show other stuff if not in rearview or letterbox.
  2077.     if (!Rear_view && Cockpit_mode!=CM_REAR_VIEW) { // && Cockpit_mode!=CM_LETTERBOX) {
  2078.         if (Cockpit_mode==CM_STATUS_BAR || Cockpit_mode==CM_FULL_SCREEN)
  2079.             hud_show_homing_warning();
  2080.  
  2081.         if (Cockpit_mode==CM_FULL_SCREEN) {
  2082.             hud_show_energy();
  2083.             hud_show_shield();
  2084.             hud_show_weapons();
  2085.             hud_show_keys();
  2086.             hud_show_cloak_invuln();
  2087.  
  2088.             if ( ( Newdemo_state==ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags[VR_current_page] )) {
  2089.                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
  2090.                 old_flags[VR_current_page] = Players[Player_num].flags;
  2091.             }
  2092.         }
  2093.  
  2094.         #ifdef NETWORK
  2095.         #ifndef RELEASE
  2096.         if (!(Game_mode&GM_MULTI && Show_kill_list))
  2097.             show_time();
  2098.         #endif
  2099.         #endif
  2100.         if (Cockpit_mode != CM_LETTERBOX && (!Use_player_head_angles))
  2101.             show_reticle(0);
  2102.         HUD_render_message_frame();
  2103.  
  2104.         if (Cockpit_mode!=CM_STATUS_BAR)
  2105.             hud_show_lives();
  2106.         #ifdef NETWORK
  2107.         if (Game_mode&GM_MULTI && Show_kill_list)
  2108.             hud_show_kill_list();
  2109.         #endif
  2110.     }
  2111.  
  2112.     if (Rear_view && Cockpit_mode!=CM_REAR_VIEW) {
  2113.         HUD_render_message_frame();
  2114.         gr_set_curfont( GAME_FONT );
  2115.         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
  2116.         if (Newdemo_state == ND_STATE_PLAYBACK)
  2117.             gr_printf(0x8000,grd_curcanv->cv_h-14,TXT_REAR_VIEW);
  2118.         else
  2119.             gr_printf(0x8000,grd_curcanv->cv_h-10,TXT_REAR_VIEW);
  2120.     }
  2121.  
  2122. }
  2123.  
  2124. //print out some player statistics
  2125. void render_gauges()
  2126. {
  2127.     int energy = f2ir(Players[Player_num].energy);
  2128.     int shields = f2ir(Players[Player_num].shields);
  2129.     int cloak = ((Players[Player_num].flags&PLAYER_FLAGS_CLOAKED) != 0);
  2130.  
  2131.     Assert(Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR);
  2132.  
  2133.     #ifdef HOSTAGE_FACES
  2134.     draw_hostage_gauge();
  2135.     #endif
  2136.  
  2137.     if (shields < 0 ) shields = 0;
  2138.  
  2139.     gr_set_current_canvas(get_current_game_screen());
  2140.     gr_set_curfont( GAME_FONT );
  2141.  
  2142.     if (Newdemo_state == ND_STATE_RECORDING)
  2143.         if (Players[Player_num].homing_object_dist >= 0)
  2144.             newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
  2145.  
  2146.     if (Cockpit_mode == CM_FULL_COCKPIT) {
  2147.         if (energy != old_energy[VR_current_page]) {
  2148.             if (Newdemo_state==ND_STATE_RECORDING ) {
  2149. #ifdef SHAREWARE
  2150.                 newdemo_record_player_energy(energy);
  2151. #else
  2152.                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
  2153. #endif
  2154.             }
  2155.             draw_energy_bar(energy);
  2156.             draw_numerical_display(shields, energy);
  2157.             old_energy[VR_current_page] = energy;
  2158.         }
  2159.  
  2160.         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
  2161.             draw_numerical_display(shields, energy);
  2162.             draw_invulnerable_ship();
  2163.             old_shields[VR_current_page] = shields ^ 1;
  2164.         } else if (shields != old_shields[VR_current_page]) {        // Draw the shield gauge
  2165.             if (Newdemo_state==ND_STATE_RECORDING ) {
  2166. #ifdef SHAREWARE
  2167.                 newdemo_record_player_shields(shields);
  2168. #else
  2169.                 newdemo_record_player_shields(old_shields[VR_current_page], shields);
  2170. #endif
  2171.             }
  2172.             draw_shield_bar(shields);
  2173.             draw_numerical_display(shields, energy);
  2174.             old_shields[VR_current_page] = shields;
  2175.         }
  2176.     
  2177.         if (Players[Player_num].flags != old_flags[VR_current_page]) {
  2178.             if (Newdemo_state==ND_STATE_RECORDING )
  2179.                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
  2180.             draw_keys();
  2181.             old_flags[VR_current_page] = Players[Player_num].flags;
  2182.         }
  2183.  
  2184.         show_homing_warning();
  2185.     
  2186.     } else if (Cockpit_mode == CM_STATUS_BAR) {
  2187.  
  2188.         if (energy != old_energy[VR_current_page]) {
  2189.             if (Newdemo_state==ND_STATE_RECORDING ) {
  2190. #ifdef SHAREWARE
  2191.                 newdemo_record_player_energy(energy);
  2192. #else
  2193.                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
  2194. #endif
  2195.             }
  2196.             sb_draw_energy_bar(energy);
  2197.             old_energy[VR_current_page] = energy;
  2198.         }
  2199.     
  2200.         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
  2201.             draw_invulnerable_ship();
  2202.             old_shields[VR_current_page] = shields ^ 1;
  2203.             sb_draw_shield_num(shields);
  2204.         } 
  2205.         else 
  2206.             if (shields != old_shields[VR_current_page]) {        // Draw the shield gauge
  2207.                 if (Newdemo_state==ND_STATE_RECORDING ) {
  2208. #ifdef SHAREWARE
  2209.                     newdemo_record_player_shields(shields);
  2210. #else
  2211.                     newdemo_record_player_shields(old_shields[VR_current_page], shields);
  2212. #endif
  2213.                 }
  2214.                 sb_draw_shield_bar(shields);
  2215.                 old_shields[VR_current_page] = shields;
  2216.                 sb_draw_shield_num(shields);
  2217.             }
  2218.  
  2219.         if (Players[Player_num].flags != old_flags[VR_current_page]) {
  2220.             if (Newdemo_state==ND_STATE_RECORDING )
  2221.                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
  2222.             sb_draw_keys();
  2223.             old_flags[VR_current_page] = Players[Player_num].flags;
  2224.         }
  2225.     
  2226.  
  2227.         if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
  2228.         {
  2229.             if (Players[Player_num].net_killed_total != old_lives[VR_current_page]) {
  2230.                 sb_show_lives();
  2231.                 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
  2232.             }
  2233.         }
  2234.         else
  2235.         {
  2236.             if (Players[Player_num].lives != old_lives[VR_current_page]) {
  2237.                 sb_show_lives();
  2238.                 old_lives[VR_current_page] = Players[Player_num].lives;
  2239.             }
  2240.         }
  2241.  
  2242.         if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) {
  2243.             if (Players[Player_num].net_kills_total != old_score[VR_current_page]) {
  2244.                 sb_show_score();
  2245.                 old_score[VR_current_page] = Players[Player_num].net_kills_total;
  2246.             }
  2247.         }
  2248.         else {
  2249.             if (Players[Player_num].score != old_score[VR_current_page]) {
  2250.                 sb_show_score();
  2251.                 old_score[VR_current_page] = Players[Player_num].score;
  2252.             }
  2253.  
  2254.             if (score_time)
  2255.                 sb_show_score_added();
  2256.         }
  2257.  
  2258.     }
  2259.  
  2260.     if (cloak != old_cloak[VR_current_page] || cloak_fade_state || (cloak && GameTime>Players[Player_num].cloak_time+CLOAK_TIME_MAX-i2f(3))) {
  2261.         if (Cockpit_mode == CM_FULL_COCKPIT)
  2262.             draw_player_ship(cloak,old_cloak[VR_current_page],SHIP_GAUGE_X,SHIP_GAUGE_Y);
  2263.         else
  2264.             draw_player_ship(cloak,old_cloak[VR_current_page],SB_SHIP_GAUGE_X,SB_SHIP_GAUGE_Y);
  2265.  
  2266.         old_cloak[VR_current_page]=cloak;
  2267.     }
  2268.  
  2269.  
  2270.     draw_weapon_boxes();
  2271.  
  2272. }
  2273.  
  2274. //    ---------------------------------------------------------------------------------------------------------
  2275. //    Call when picked up a laser powerup.
  2276. //    If laser is active, set old_weapon[0] to -1 to force redraw.
  2277. void update_laser_weapon_info(void)
  2278. {
  2279.     if (old_weapon[0][VR_current_page] == 0)
  2280.         old_weapon[0][VR_current_page] = -1;
  2281. }
  2282.  
  2283. 
  2284.