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