lots of shareware and oem fixes
[btb/d2x.git] / main / gauges.c
1 /* $Id: gauges.c,v 1.10 2003-10-11 09:28:38 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Inferno gauge drivers
18  *
19  * Old Log:
20  * Revision 1.15  1995/10/31  10:22:37  allender
21  * shareware stuff
22  *
23  * Revision 1.14  1995/10/26  14:11:05  allender
24  * do copy of weapon boxes in cockpit correctly
25  *
26  * Revision 1.13  1995/10/21  22:54:56  allender
27  * fixed up player names on hud
28  *
29  * Revision 1.12  1995/10/12  17:39:27  allender
30  * fixed status bar lives display
31  *
32  * Revision 1.11  1995/09/22  15:21:46  allender
33  * fixed hud problems (reticle and kill lists) for
34  * non pixel doubled mode
35  *
36  * Revision 1.10  1995/09/13  11:38:47  allender
37  * show KB left in heap instead of piggy cache
38  *
39  * Revision 1.9  1995/09/04  15:52:28  allender
40  * fix vulcan ammo count to update without overwritting itself
41  *
42  * Revision 1.8  1995/08/31  14:11:20  allender
43  * worked on hud kill list for non pixel doubled mode
44  *
45  * Revision 1.7  1995/08/24  16:05:05  allender
46  * more gauge placement -- still not done!
47  *
48  * Revision 1.6  1995/08/18  15:44:56  allender
49  * put in PC gauges for keys, lives, and reticle when pixel doubling
50  *
51  * Revision 1.5  1995/08/18  10:24:47  allender
52  * added proper support for cockpit mode -- still needs
53  *
54  * Revision 1.4  1995/07/26  16:56:34  allender
55  * more gauge stuff for status bar.  still problem
56  * with ship
57  *
58  * Revision 1.3  1995/07/17  08:55:57  allender
59  * fix up for large status bar.  Still needs some work though
60  *
61  * Revision 1.2  1995/06/20  09:54:29  allender
62  * stopgap measure to get status bar "working" until real mac
63  * status bar gets added
64  *
65  * Revision 1.1  1995/05/16  15:26:05  allender
66  * Initial revision
67  *
68  * Revision 2.7  1995/12/19  16:18:33  john
69  * Made weapon info align with canvas width, not 315.
70  *
71  * Revision 2.6  1995/03/21  14:39:25  john
72  * Ifdef'd out the NETWORK code.
73  *
74  * Revision 2.5  1995/03/14  12:31:25  john
75  * Prevent negative shields from printing.
76  *
77  * Revision 2.4  1995/03/10  12:57:58  allender
78  * move rear view text up four pixels up when playing back demo
79  *
80  * Revision 2.3  1995/03/09  11:47:51  john
81  * Added HUD for VR helmets.
82  *
83  * Revision 2.2  1995/03/06  15:23:26  john
84  * New screen techniques.
85  *
86  * Revision 2.1  1995/02/27  13:13:45  john
87  * Removed floating point.
88  *
89  * Revision 2.0  1995/02/27  11:29:06  john
90  * New version 2.0, which has no anonymous unions, builds with
91  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
92  *
93  * Revision 1.203  1995/02/11  01:56:45  mike
94  * move up weapons text on fullscreen hud, missiles was offscreen.
95  *
96  * Revision 1.202  1995/02/09  13:23:34  rob
97  * Added reticle names in demo playback.
98  *
99  * Revision 1.201  1995/02/08  19:20:46  rob
100  * Show cloaked teammates on H
101  * UD.  Get rid of show ID's in anarchy option.
102  *
103  * Revision 1.200  1995/02/07  21:09:00  mike
104  * add flashing to invulnerability and cloak on fullscreen.
105  *
106  * Revision 1.199  1995/02/02  21:55:57  matt
107  * Added new colored key icons for fullscreen
108  *
109  * Revision 1.198  1995/01/30  17:17:07  rob
110  * Fixed teammate names on hud.
111  *
112  * Revision 1.197  1995/01/28  17:40:49  mike
113  * fix gauge fontcolor.
114  *
115  * Revision 1.196  1995/01/27  17:03:14  mike
116  * fix placement of weapon info in multiplayer fullscreen, as per AP request.
117  *
118  * Revision 1.195  1995/01/27  11:51:23  rob
119  * Put deaths tally into cooperative mode
120  *
121  * Revision 1.194  1995/01/27  11:43:24  adam
122  * fiddled with key display
123  *
124  * Revision 1.193  1995/01/25  23:38:35  mike
125  * fix keys on fullscreen.
126  *
127  * Revision 1.192  1995/01/24  22:03:28  mike
128  * Lotsa hud stuff, put a lot of messages up.
129  *
130  * Revision 1.191  1995/01/23  16:47:21  rob
131  * Fixed problem with playing extra life noise in coop.
132  *
133  * Revision 1.190  1995/01/22  16:00:46  mike
134  * remove unneeded string.
135  *
136  * Revision 1.189  1995/01/22  15:58:22  mike
137  * localization
138  *
139  * Revision 1.188  1995/01/20  17:19:45  rob
140  * Fixing colors of hud kill list players.
141  *
142  * Revision 1.187  1995/01/20  09:19:18  allender
143  * record player flags when in CM_FULL_SCREEN
144  *
145  * Revision 1.186  1995/01/19  16:29:09  allender
146  * made demo recording of weapon change be in this file for shareware only
147  *
148  * Revision 1.185  1995/01/19  15:00:33  allender
149  * code to record shield, energy, and ammo in fullscreen
150  *
151  * Revision 1.184  1995/01/19  13:43:13  matt
152  * Fixed "cheater" message on HUD
153  *
154  * Revision 1.183  1995/01/18  16:11:58  mike
155  * Don't show added scores of 0.
156  *
157  * Revision 1.182  1995/01/17  17:42:39  allender
158  * do ammo counts in demo recording
159  *
160  * Revision 1.181  1995/01/16  17:26:25  rob
161  * Fixed problem with coloration of team kill list.
162  *
163  * Revision 1.180  1995/01/16  17:22:39  john
164  * Made so that KB and framerate don't collide.
165  *
166  * Revision 1.179  1995/01/16  14:58:31  matt
167  * Changed score_added display to print "Cheater!" when cheats enabled
168  *
169  * Revision 1.178  1995/01/15  19:42:07  matt
170  * Ripped out hostage faces for registered version
171  *
172  * Revision 1.177  1995/01/15  19:25:07  mike
173  * show vulcan ammo and secondary ammo in fullscreen view.
174  *
175  * Revision 1.176  1995/01/15  13:16:12  john
176  * Made so that paging always happens, lowmem just loads less.
177  * Also, make KB load print to hud.
178  *
179  * Revision 1.175  1995/01/14  19:17:32  john
180  * First version of piggy paging.
181  *
182  * Revision 1.174  1995/01/05  21:25:23  rob
183  * Re-did some changes lost due to RCS weirdness.
184  *
185  * Revision 1.173  1995/01/05  12:22:34  rob
186  * Don't show player names for cloaked players.
187  *
188  * Revision 1.172  1995/01/04  17:14:50  allender
189  * make init_gauges work properly on demo playback
190  *
191  * Revision 1.171  1995/01/04  15:04:42  allender
192  * new demo calls for registered version
193  *
194  * Revision 1.167  1995/01/03  13:03:57  allender
195  * pass score points instead of total points.   Added ifdef for
196  * multi_send_score
197  *
198  * Revision 1.166  1995/01/03  11:45:02  allender
199  * add hook to record player score
200  *
201  * Revision 1.165  1995/01/03  11:25:19  allender
202  * remove newdemo stuff around score display
203  *
204  * Revision 1.163  1995/01/02  21:03:53  rob
205  * Fixing up the hud-score-list for coop games.
206  *
207  * Revision 1.162  1994/12/31  20:54:40  rob
208  * Added coop mode HUD score list.
209  * Added more generic system for player names on HUD.
210  *
211  * Revision 1.161  1994/12/30  20:13:01  rob
212  * Ifdef reticle names on shareware.
213  * Added robot reticle naming.
214  *
215  * Revision 1.160  1994/12/29  17:53:51  mike
216  * move up energy/shield in fullscreen to get out of way of kill list.
217  *
218  * Revision 1.159  1994/12/29  16:44:05  mike
219  * add energy and shield showing.
220  *
221  * Revision 1.158  1994/12/28  16:34:29  mike
222  * make warning beep go away on Player_is_dead.
223  *
224  * Revision 1.157  1994/12/28  10:00:43  allender
225  * change in init_gauges to for multiplayer demo playbacks
226  *
227  * Revision 1.156  1994/12/27  11:06:46  allender
228  * removed some previous code to for demo playback stuff
229  *
230  * Revision 1.155  1994/12/23  14:23:06  john
231  * Added floating reticle for VR helments.
232  *
233  * Revision 1.154  1994/12/21  12:56:41  allender
234  * on multiplayer demo playback, show kills and deaths
235  *
236  * Revision 1.153  1994/12/19  20:28:42  rob
237  * Get rid of kill list in coop games.
238  *
239  * Revision 1.152  1994/12/14  18:06:44  matt
240  * Removed compile warnings
241  *
242  * Revision 1.151  1994/12/14  15:21:28  rob
243  * Made gauges align in status_bar net game.
244  *
245  * Revision 1.150  1994/12/12  17:20:33  matt
246  * Don't get bonus points when cheating
247  *
248  * Revision 1.149  1994/12/12  16:47:00  matt
249  * When cheating, get no score.  Change level cheat to prompt for and
250  * jump to new level.
251  *
252  * Revision 1.148  1994/12/12  12:05:45  rob
253  * Grey out players who are disconnected.
254  *
255  * Revision 1.147  1994/12/09  16:19:48  yuan
256  * kill matrix stuff.
257  *
258  * Revision 1.146  1994/12/09  16:12:34  rob
259  * Fixed up the status bar kills gauges for net play.
260  *
261  * Revision 1.145  1994/12/09  01:55:34  rob
262  * Added kills list to HUD/status bar.
263  * Added something for Mark.
264  *
265  * Revision 1.144  1994/12/08  21:03:30  allender
266  * pass old player flags to record_player_flags
267  *
268  * Revision 1.143  1994/12/07  22:49:33  mike
269  * no homing missile warning during endlevel sequence.
270  *
271  * Revision 1.142  1994/12/06  13:55:31  matt
272  * Use new rounding func, f2ir()
273  *
274  * Revision 1.141  1994/12/03  19:03:37  matt
275  * Fixed vulcan ammo HUD message
276  *
277  * Revision 1.140  1994/12/03  18:43:18  matt
278  * Fixed (hopefully) claok gauge
279  *
280  * Revision 1.139  1994/12/03  14:26:21  yuan
281  * Fixed dumb bug
282  *
283  * Revision 1.138  1994/12/03  14:17:30  yuan
284  * Localization 320
285  *
286  */
287
288 #ifdef HAVE_CONFIG_H
289 #include <conf.h>
290 #endif
291
292 #ifdef WINDOWS
293 #include "desw.h"
294 #endif
295
296 #include <stdio.h>
297 #include <string.h>
298 #include <stdlib.h>
299 #include <stdarg.h>
300
301 #include "hudmsg.h"
302
303 #include "pa_enabl.h"                   //$$POLY_ACC
304 #include "inferno.h"
305 #include "game.h"
306 #include "screens.h"
307 #include "gauges.h"
308 #include "physics.h"
309 #include "error.h"
310
311 #include "menu.h"                       // For the font.
312 #include "mono.h"
313 #include "collide.h"
314 #include "newdemo.h"
315 #include "player.h"
316 #include "gamefont.h"
317 #include "bm.h"
318 #include "text.h"
319 #include "powerup.h"
320 #include "sounds.h"
321 #ifdef NETWORK
322 #include "multi.h"
323 #include "network.h"
324 #endif
325 #include "endlevel.h"
326 #include "cntrlcen.h"
327 #include "controls.h"
328
329 #include "wall.h"
330 #include "text.h"
331 #include "render.h"
332 #include "piggy.h"
333 #include "laser.h"
334
335 #ifdef OGL
336 #include "ogl_init.h"
337 #endif
338
339 #if defined(POLY_ACC)
340 #include "poly_acc.h"
341 #endif
342
343 void draw_ammo_info(int x,int y,int ammo_count,int primary);
344 extern void draw_guided_crosshair(void);
345
346 bitmap_index Gauges[MAX_GAUGE_BMS];   // Array of all gauge bitmaps.
347 bitmap_index Gauges_hires[MAX_GAUGE_BMS];   // hires gauges
348
349 grs_canvas *Canv_LeftEnergyGauge;
350 grs_canvas *Canv_AfterburnerGauge;
351 grs_canvas *Canv_SBEnergyGauge;
352 grs_canvas *Canv_SBAfterburnerGauge;
353 grs_canvas *Canv_RightEnergyGauge;
354 grs_canvas *Canv_NumericalGauge;
355
356 //Flags for gauges/hud stuff
357 ubyte Reticle_on=1;
358
359 //bitmap numbers for gauges
360
361 #define GAUGE_SHIELDS                   0               //0..9, in decreasing order (100%,90%...0%)
362
363 #define GAUGE_INVULNERABLE              10              //10..19
364 #define N_INVULNERABLE_FRAMES   10
365
366 #define GAUGE_AFTERBURNER       20
367 #define GAUGE_ENERGY_LEFT               21
368 #define GAUGE_ENERGY_RIGHT              22
369 #define GAUGE_NUMERICAL                 23
370
371 #define GAUGE_BLUE_KEY                  24
372 #define GAUGE_GOLD_KEY                  25
373 #define GAUGE_RED_KEY                   26
374 #define GAUGE_BLUE_KEY_OFF              27
375 #define GAUGE_GOLD_KEY_OFF              28
376 #define GAUGE_RED_KEY_OFF               29
377
378 #define SB_GAUGE_BLUE_KEY               30
379 #define SB_GAUGE_GOLD_KEY               31
380 #define SB_GAUGE_RED_KEY                32
381 #define SB_GAUGE_BLUE_KEY_OFF   33
382 #define SB_GAUGE_GOLD_KEY_OFF   34
383 #define SB_GAUGE_RED_KEY_OFF    35
384
385 #define SB_GAUGE_ENERGY                 36
386
387 #define GAUGE_LIVES                             37      
388
389 #define GAUGE_SHIPS                             38
390 #define GAUGE_SHIPS_LAST                45
391
392 #define RETICLE_CROSS                   46
393 #define RETICLE_PRIMARY                 48
394 #define RETICLE_SECONDARY               51
395 #define RETICLE_LAST                            55
396
397 #define GAUGE_HOMING_WARNING_ON 56
398 #define GAUGE_HOMING_WARNING_OFF        57
399
400 #define SML_RETICLE_CROSS               58
401 #define SML_RETICLE_PRIMARY     60
402 #define SML_RETICLE_SECONDARY   63
403 #define SML_RETICLE_LAST                67
404
405 #define KEY_ICON_BLUE                   68
406 #define KEY_ICON_YELLOW                 69
407 #define KEY_ICON_RED                            70
408
409 #define SB_GAUGE_AFTERBURNER    71
410
411 #define FLAG_ICON_RED                   72
412 #define FLAG_ICON_BLUE                  73
413
414
415 /* Use static inline function under GCC to avoid CR/LF issues */
416 #ifdef __GNUC__
417 #define PAGE_IN_GAUGE(x) _page_in_gauge(x)
418 static inline void _page_in_gauge(int x)
419 {
420     if (FontHires) {
421         PIGGY_PAGE_IN(Gauges_hires[x]);
422     } else {
423         PIGGY_PAGE_IN(Gauges[x]);
424     }
425 }
426
427 #else
428 #define PAGE_IN_GAUGE(x) \
429         do {                                                                                                    \
430                 if (FontHires) {                                \
431                         PIGGY_PAGE_IN(Gauges_hires[x]);         \
432                 } else {                                                                                        \
433                         PIGGY_PAGE_IN(Gauges[x]);                               \
434                 }                                                                                                       \
435         } while (0)
436
437 #endif
438
439 #define GET_GAUGE_INDEX(x)      (FontHires?Gauges_hires[x].index:Gauges[x].index)
440
441 //change MAX_GAUGE_BMS when adding gauges
442
443 //Coordinats for gauges
444
445 extern int Current_display_mode;
446
447 // cockpit keys
448
449 #define GAUGE_BLUE_KEY_X_L              272
450 #define GAUGE_BLUE_KEY_Y_L              152
451 #define GAUGE_BLUE_KEY_X_H              535
452 #define GAUGE_BLUE_KEY_Y_H              374
453 #define GAUGE_BLUE_KEY_X                (Current_display_mode?GAUGE_BLUE_KEY_X_H:GAUGE_BLUE_KEY_X_L)
454 #define GAUGE_BLUE_KEY_Y                (Current_display_mode?GAUGE_BLUE_KEY_Y_H:GAUGE_BLUE_KEY_Y_L)
455
456 #define GAUGE_GOLD_KEY_X_L              273
457 #define GAUGE_GOLD_KEY_Y_L              162
458 #define GAUGE_GOLD_KEY_X_H              537
459 #define GAUGE_GOLD_KEY_Y_H              395
460 #define GAUGE_GOLD_KEY_X                (Current_display_mode?GAUGE_GOLD_KEY_X_H:GAUGE_GOLD_KEY_X_L)
461 #define GAUGE_GOLD_KEY_Y                (Current_display_mode?GAUGE_GOLD_KEY_Y_H:GAUGE_GOLD_KEY_Y_L)
462
463 #define GAUGE_RED_KEY_X_L               274
464 #define GAUGE_RED_KEY_Y_L               172
465 #define GAUGE_RED_KEY_X_H               539
466 #define GAUGE_RED_KEY_Y_H               416
467 #define GAUGE_RED_KEY_X                 (Current_display_mode?GAUGE_RED_KEY_X_H:GAUGE_RED_KEY_X_L)
468 #define GAUGE_RED_KEY_Y                 (Current_display_mode?GAUGE_RED_KEY_Y_H:GAUGE_RED_KEY_Y_L)
469
470 // status bar keys
471
472 #define SB_GAUGE_KEYS_X_L          11
473 #define SB_GAUGE_KEYS_X_H               26
474 #define SB_GAUGE_KEYS_X                 (Current_display_mode?SB_GAUGE_KEYS_X_H:SB_GAUGE_KEYS_X_L)
475
476 #define SB_GAUGE_BLUE_KEY_Y_L           153
477 #define SB_GAUGE_GOLD_KEY_Y_L           169
478 #define SB_GAUGE_RED_KEY_Y_L            185
479
480 #define SB_GAUGE_BLUE_KEY_Y_H           390
481 #define SB_GAUGE_GOLD_KEY_Y_H           422
482 #define SB_GAUGE_RED_KEY_Y_H            454
483
484 #define SB_GAUGE_BLUE_KEY_Y     (Current_display_mode?SB_GAUGE_BLUE_KEY_Y_H:SB_GAUGE_BLUE_KEY_Y_L)
485 #define SB_GAUGE_GOLD_KEY_Y     (Current_display_mode?SB_GAUGE_GOLD_KEY_Y_H:SB_GAUGE_GOLD_KEY_Y_L)
486 #define SB_GAUGE_RED_KEY_Y              (Current_display_mode?SB_GAUGE_RED_KEY_Y_H:SB_GAUGE_RED_KEY_Y_L)
487
488 // cockpit enery gauges
489
490 #define LEFT_ENERGY_GAUGE_X_L   70
491 #define LEFT_ENERGY_GAUGE_Y_L   131
492 #define LEFT_ENERGY_GAUGE_W_L   64
493 #define LEFT_ENERGY_GAUGE_H_L   8
494
495 #define LEFT_ENERGY_GAUGE_X_H   137
496 #define LEFT_ENERGY_GAUGE_Y_H   314
497 #define LEFT_ENERGY_GAUGE_W_H   133
498 #define LEFT_ENERGY_GAUGE_H_H   21
499
500 #define LEFT_ENERGY_GAUGE_X     (Current_display_mode?LEFT_ENERGY_GAUGE_X_H:LEFT_ENERGY_GAUGE_X_L)
501 #define LEFT_ENERGY_GAUGE_Y     (Current_display_mode?LEFT_ENERGY_GAUGE_Y_H:LEFT_ENERGY_GAUGE_Y_L)
502 #define LEFT_ENERGY_GAUGE_W     (Current_display_mode?LEFT_ENERGY_GAUGE_W_H:LEFT_ENERGY_GAUGE_W_L)
503 #define LEFT_ENERGY_GAUGE_H     (Current_display_mode?LEFT_ENERGY_GAUGE_H_H:LEFT_ENERGY_GAUGE_H_L)
504
505 #define RIGHT_ENERGY_GAUGE_X    (Current_display_mode?380:190)
506 #define RIGHT_ENERGY_GAUGE_Y    (Current_display_mode?314:131)
507 #define RIGHT_ENERGY_GAUGE_W    (Current_display_mode?133:64)
508 #define RIGHT_ENERGY_GAUGE_H    (Current_display_mode?21:8)
509
510 // cockpit afterburner gauge
511
512 #define AFTERBURNER_GAUGE_X_L   45-1
513 #define AFTERBURNER_GAUGE_Y_L   158
514 #define AFTERBURNER_GAUGE_W_L   12
515 #define AFTERBURNER_GAUGE_H_L   32
516
517 #define AFTERBURNER_GAUGE_X_H   88
518 #define AFTERBURNER_GAUGE_Y_H   377
519 #define AFTERBURNER_GAUGE_W_H   21
520 #define AFTERBURNER_GAUGE_H_H   65
521
522 #define AFTERBURNER_GAUGE_X     (Current_display_mode?AFTERBURNER_GAUGE_X_H:AFTERBURNER_GAUGE_X_L)
523 #define AFTERBURNER_GAUGE_Y     (Current_display_mode?AFTERBURNER_GAUGE_Y_H:AFTERBURNER_GAUGE_Y_L)
524 #define AFTERBURNER_GAUGE_W     (Current_display_mode?AFTERBURNER_GAUGE_W_H:AFTERBURNER_GAUGE_W_L)
525 #define AFTERBURNER_GAUGE_H     (Current_display_mode?AFTERBURNER_GAUGE_H_H:AFTERBURNER_GAUGE_H_L)
526
527 // sb energy gauge
528
529 #define SB_ENERGY_GAUGE_X               (Current_display_mode?196:98)
530 #define SB_ENERGY_GAUGE_Y               (Current_display_mode?382:(155-2))
531 #define SB_ENERGY_GAUGE_W               (Current_display_mode?32:16)
532 #define SB_ENERGY_GAUGE_H               (Current_display_mode?60:29)
533
534 // sb afterburner gauge
535
536 #define SB_AFTERBURNER_GAUGE_X          (Current_display_mode?196:98)
537 #define SB_AFTERBURNER_GAUGE_Y          (Current_display_mode?446:184)
538 #define SB_AFTERBURNER_GAUGE_W          (Current_display_mode?33:16)
539 #define SB_AFTERBURNER_GAUGE_H          (Current_display_mode?29:13)
540
541 #define SB_ENERGY_NUM_X                 (SB_ENERGY_GAUGE_X+(Current_display_mode?4:2))
542 #define SB_ENERGY_NUM_Y                 (Current_display_mode?457:175)
543
544 #define SHIELD_GAUGE_X                  (Current_display_mode?292:146)
545 #define SHIELD_GAUGE_Y                  (Current_display_mode?374:155)
546 #define SHIELD_GAUGE_W                  (Current_display_mode?70:35)
547 #define SHIELD_GAUGE_H                  (Current_display_mode?77:32)
548
549 #define SHIP_GAUGE_X                    (SHIELD_GAUGE_X+(Current_display_mode?11:5))
550 #define SHIP_GAUGE_Y                            (SHIELD_GAUGE_Y+(Current_display_mode?10:5))
551
552 #define SB_SHIELD_GAUGE_X               (Current_display_mode?247:123)          //139
553 #define SB_SHIELD_GAUGE_Y               (Current_display_mode?395:163)
554
555 #define SB_SHIP_GAUGE_X                 (SB_SHIELD_GAUGE_X+(Current_display_mode?11:5))
556 #define SB_SHIP_GAUGE_Y                 (SB_SHIELD_GAUGE_Y+(Current_display_mode?10:5))
557
558 #define SB_SHIELD_NUM_X                 (SB_SHIELD_GAUGE_X+(Current_display_mode?21:12))        //151
559 #define SB_SHIELD_NUM_Y                 (SB_SHIELD_GAUGE_Y-(Current_display_mode?16:8))                 //156 -- MWA used to be hard coded to 156
560
561 #define NUMERICAL_GAUGE_X               (Current_display_mode?308:154)
562 #define NUMERICAL_GAUGE_Y               (Current_display_mode?316:130)
563 #define NUMERICAL_GAUGE_W               (Current_display_mode?38:19)
564 #define NUMERICAL_GAUGE_H               (Current_display_mode?55:22)
565
566 #define PRIMARY_W_PIC_X                 (Current_display_mode?(135-10):64)
567 #define PRIMARY_W_PIC_Y                 (Current_display_mode?370:154)
568 #define PRIMARY_W_TEXT_X                (Current_display_mode?182:87)
569 #define PRIMARY_W_TEXT_Y                (Current_display_mode?400:157)
570 #define PRIMARY_AMMO_X                  (Current_display_mode?186:(96-3))
571 #define PRIMARY_AMMO_Y                  (Current_display_mode?420:171)
572
573 #define SECONDARY_W_PIC_X               (Current_display_mode?466:234)
574 #define SECONDARY_W_PIC_Y               (Current_display_mode?374:154)
575 #define SECONDARY_W_TEXT_X              (Current_display_mode?413:207)
576 #define SECONDARY_W_TEXT_Y              (Current_display_mode?378:157)
577 #define SECONDARY_AMMO_X                (Current_display_mode?428:213)
578 #define SECONDARY_AMMO_Y                (Current_display_mode?407:171)
579
580 #define SB_LIVES_X                              (Current_display_mode?(550-10-3):266)
581 #define SB_LIVES_Y                              (Current_display_mode?450-3:185)
582 #define SB_LIVES_LABEL_X                (Current_display_mode?475:237)
583 #define SB_LIVES_LABEL_Y                (SB_LIVES_Y+1)
584
585 #define SB_SCORE_RIGHT_L                301
586 #define SB_SCORE_RIGHT_H                (605+8)
587 #define SB_SCORE_RIGHT                  (Current_display_mode?SB_SCORE_RIGHT_H:SB_SCORE_RIGHT_L)
588
589 #define SB_SCORE_Y                              (Current_display_mode?398:158)
590 #define SB_SCORE_LABEL_X                (Current_display_mode?475:237)
591
592 #define SB_SCORE_ADDED_RIGHT    (Current_display_mode?SB_SCORE_RIGHT_H:SB_SCORE_RIGHT_L)
593 #define SB_SCORE_ADDED_Y                (Current_display_mode?413:165)
594
595 #define HOMING_WARNING_X                (Current_display_mode?14:7)
596 #define HOMING_WARNING_Y                (Current_display_mode?415:171)
597
598 #define BOMB_COUNT_X                    (Current_display_mode?546:275)
599 #define BOMB_COUNT_Y                    (Current_display_mode?445:186)
600
601 #define SB_BOMB_COUNT_X                 (Current_display_mode?342:171)
602 #define SB_BOMB_COUNT_Y                 (Current_display_mode?458:191)
603
604 #ifdef WINDOWS
605 #define LHX(x)          ((x)*(Current_display_mode?2:1))
606 #define LHY(y)          ((y)*(Current_display_mode?2.4:1))
607 #else
608 #define LHX(x)          ((x)*(MenuHires?2:1))
609 #define LHY(y)          ((y)*(MenuHires?2.4:1))
610 #endif
611
612 static int score_display[2];
613 static fix score_time;
614
615 static int old_score[2]                         = { -1, -1 };
616 static int old_energy[2]                        = { -1, -1 };
617 static int old_shields[2]                       = { -1, -1 };
618 static int old_flags[2]                         = { -1, -1 };
619 static int old_weapon[2][2]             = {{ -1, -1 },{-1,-1}};
620 static int old_ammo_count[2][2] = {{ -1, -1 },{-1,-1}};
621 static int Old_Omega_charge[2]  = { -1, -1 };
622 static int old_laser_level[2]           = { -1, -1 };
623 static int old_cloak[2]                         = { 0, 0 };
624 static int old_lives[2]                         = { -1, -1 };
625 static fix old_afterburner[2]           = { -1, -1 };
626 static int old_bombcount[2]             = { 0, 0 };
627
628 static int invulnerable_frame = 0;
629
630 static int cloak_fade_state;            //0=steady, -1 fading out, 1 fading in 
631
632 #define WS_SET                          0               //in correct state
633 #define WS_FADING_OUT   1
634 #define WS_FADING_IN            2
635
636 int weapon_box_user[2]={WBU_WEAPON,WBU_WEAPON};         //see WBU_ constants in gauges.h
637 int weapon_box_states[2];
638 fix weapon_box_fade_values[2];
639
640 #define FADE_SCALE      (2*i2f(GR_FADE_LEVELS)/REARM_TIME)              // fade out and back in REARM_TIME, in fade levels per seconds (int)
641
642 typedef struct span {
643         sbyte l,r;
644 } span;
645
646 //store delta x values from left of box
647 span weapon_window_left[] = {           //first span 67,151
648                 {8,51},
649                 {6,53},
650                 {5,54},
651                 {4-1,53+2},
652                 {4-1,53+3},
653                 {4-1,53+3},
654                 {4-2,53+3},
655                 {4-2,53+3},
656                 {3-1,53+3},
657                 {3-1,53+3},
658                 {3-1,53+3},
659                 {3-1,53+3},
660                 {3-1,53+3},
661                 {3-1,53+3},
662                 {3-1,53+3},
663                 {3-2,53+3},
664                 {2-1,53+3},
665                 {2-1,53+3},
666                 {2-1,53+3},
667                 {2-1,53+3},
668                 {2-1,53+3},
669                 {2-1,53+3},
670                 {2-1,53+3},
671                 {2-1,53+3},
672                 {1-1,53+3},
673                 {1-1,53+2},
674                 {1-1,53+2},
675                 {1-1,53+2},
676                 {1-1,53+2},
677                 {1-1,53+2},
678                 {1-1,53+2},
679                 {1-1,53+2},
680                 {0,53+2},
681                 {0,53+2},
682                 {0,53+2},
683                 {0,53+2},
684                 {0,52+3},
685                 {1-1,52+2},
686                 {2-2,51+3},
687                 {3-2,51+2},
688                 {4-2,50+2},
689                 {5-2,50},
690                 {5-2+2,50-2},
691         };
692
693
694 //store delta x values from left of box
695 span weapon_window_right[] = {          //first span 207,154
696                 {208-202,255-202},
697                 {206-202,257-202},
698                 {205-202,258-202},
699                 {204-202,259-202},
700                 {203-202,260-202},
701                 {203-202,260-202},
702                 {203-202,260-202},
703                 {203-202,260-202},
704                 {203-202,260-202},
705                 {203-202,261-202},
706                 {203-202,261-202},
707                 {203-202,261-202},
708                 {203-202,261-202},
709                 {203-202,261-202},
710                 {203-202,261-202},
711                 {203-202,261-202},
712                 {203-202,261-202},
713                 {203-202,261-202},
714                 {203-202,262-202},
715                 {203-202,262-202},
716                 {203-202,262-202},
717                 {203-202,262-202},
718                 {203-202,262-202},
719                 {203-202,262-202},
720                 {203-202,262-202},
721                 {203-202,262-202},
722                 {204-202,263-202},
723                 {204-202,263-202},
724                 {204-202,263-202},
725                 {204-202,263-202},
726                 {204-202,263-202},
727                 {204-202,263-202},
728                 {204-202,263-202},
729                 {204-202,263-202},
730                 {204-202,263-202},
731                 {204-202,263-202},
732                 {204-202,263-202},
733                 {204-202,263-202},
734                 {205-202,263-202},
735                 {206-202,262-202},
736                 {207-202,261-202},
737                 {208-202,260-202},
738                 {211-202,255-202},
739         };
740
741 //store delta x values from left of box
742 span weapon_window_left_hires[] = {             //first span 67,154
743         {20,110},
744         {18,113},
745         {16,114},
746         {15,116},
747         {14,117},
748         {13,118},
749         {12,119},
750         {11,119},
751         {10,120},
752         {10,120},
753         {9,121},
754         {8,121},
755         {8,121},
756         {8,122},
757         {7,122},
758         {7,122},
759         {7,122},
760         {7,122},
761         {7,122},
762         {6,122},
763         {6,122},
764         {6,122},
765         {6,122},
766         {6,122},
767         {6,122},
768         {6,122},
769         {6,122},
770         {6,122},
771         {6,122},
772         {5,122},
773         {5,122},
774         {5,122},
775         {5,122},
776         {5,121},
777         {5,121},
778         {5,121},
779         {5,121},
780         {5,121},
781         {5,121},
782         {4,121},
783         {4,121},
784         {4,121},
785         {4,121},
786         {4,121},
787         {4,121},
788         {4,121},
789         {4,121},
790         {4,121},
791         {4,121},
792         {3,121},
793         {3,121},
794         {3,120},
795         {3,120},
796         {3,120},
797         {3,120},
798         {3,120},
799         {3,120},
800         {3,120},
801         {3,120},
802         {3,120},
803         {2,120},
804         {2,120},
805         {2,120},
806         {2,120},
807         {2,120},
808         {2,120},
809         {2,120},
810         {2,120},
811         {2,120},
812         {2,120},
813         {2,120},
814         {2,120},
815         {1,120},
816         {1,120},
817         {1,119},
818         {1,119},
819         {1,119},
820         {1,119},
821         {1,119},
822         {1,119},
823         {1,119},
824         {1,119},
825         {0,119},
826         {0,119},
827         {0,119},
828         {0,119},
829         {0,119},
830         {0,119},
831         {0,119},
832         {0,118},
833         {0,118},
834         {0,118},
835         {0,117},
836         {0,117},
837         {0,117},
838         {1,116},
839         {1,116},
840         {2,115},
841         {2,114},
842         {3,113},
843         {4,112},
844         {5,111},
845         {5,110},
846         {7,109},
847         {9,107},
848         {10,105},
849         {12,102},
850 };
851
852
853 //store delta x values from left of box
854 span weapon_window_right_hires[] = {            //first span 207,154
855         {12,105},
856         {9,107},
857         {8,109},
858         {6,110},
859         {5,111},
860         {4,112},
861         {3,113},
862         {3,114},
863         {2,115},
864         {2,115},
865         {1,116},
866         {1,117},
867         {1,117},
868         {0,117},
869         {0,118},
870         {0,118},
871         {0,118},
872         {0,118},
873         {0,118},
874         {0,119},
875         {0,119},
876         {0,119},
877         {0,119},
878         {0,119},
879         {0,119},
880         {0,119},
881         {0,119},
882         {0,119},
883         {0,119},
884         {0,120},
885         {0,120},
886         {0,120},
887         {0,120},
888         {1,120},
889         {1,120},
890         {1,120},
891         {1,120},
892         {1,120},
893         {1,120},
894         {1,121},
895         {1,121},
896         {1,121},
897         {1,121},
898         {1,121},
899         {1,121},
900         {1,121},
901         {1,121},
902         {1,121},
903         {1,121},
904         {1,122},
905         {1,122},
906         {2,122},
907         {2,122},
908         {2,122},
909         {2,122},
910         {2,122},
911         {2,122},
912         {2,122},
913         {2,122},
914         {2,123},
915         {2,123},
916         {2,123},
917         {2,123},
918         {2,123},
919         {2,123},
920         {2,123},
921         {2,123},
922         {2,123},
923         {2,123},
924         {2,123},
925         {2,123},
926         {2,123},
927         {2,124},
928         {2,124},
929         {3,124},
930         {3,124},
931         {3,124},
932         {3,124},
933         {3,124},
934         {3,124},
935         {3,124},
936         {3,125},
937         {3,125},
938         {3,125},
939         {3,125},
940         {3,125},
941         {3,125},
942         {3,125},
943         {3,125},
944         {4,125},
945         {4,125},
946         {4,125},
947         {5,125},
948         {5,125},
949         {5,125},
950         {6,125},
951         {6,124},
952         {7,123},
953         {8,123},
954         {9,122},
955         {10,121},
956         {11,120},
957         {12,120},
958         {13,118},
959         {15,117},
960         {18,115},
961         {20,114},
962 };
963
964                                                                                         
965 #define N_LEFT_WINDOW_SPANS  (sizeof(weapon_window_left)/sizeof(*weapon_window_left))
966 #define N_RIGHT_WINDOW_SPANS (sizeof(weapon_window_right)/sizeof(*weapon_window_right))
967
968 #define N_LEFT_WINDOW_SPANS_H  (sizeof(weapon_window_left_hires)/sizeof(*weapon_window_left_hires))
969 #define N_RIGHT_WINDOW_SPANS_H (sizeof(weapon_window_right_hires)/sizeof(*weapon_window_right_hires))
970
971 // defining box boundries for weapon pictures
972
973 #define PRIMARY_W_BOX_LEFT_L            63
974 #define PRIMARY_W_BOX_TOP_L             151             //154
975 #define PRIMARY_W_BOX_RIGHT_L           (PRIMARY_W_BOX_LEFT_L+58)
976 #define PRIMARY_W_BOX_BOT_L             (PRIMARY_W_BOX_TOP_L+N_LEFT_WINDOW_SPANS-1)
977                                                                                         
978 #define PRIMARY_W_BOX_LEFT_H            121
979 #define PRIMARY_W_BOX_TOP_H             364
980 #define PRIMARY_W_BOX_RIGHT_H           242
981 #define PRIMARY_W_BOX_BOT_H             (PRIMARY_W_BOX_TOP_H+N_LEFT_WINDOW_SPANS_H-1)           //470
982                                                                                         
983 #define PRIMARY_W_BOX_LEFT              (Current_display_mode?PRIMARY_W_BOX_LEFT_H:PRIMARY_W_BOX_LEFT_L)
984 #define PRIMARY_W_BOX_TOP               (Current_display_mode?PRIMARY_W_BOX_TOP_H:PRIMARY_W_BOX_TOP_L)
985 #define PRIMARY_W_BOX_RIGHT     (Current_display_mode?PRIMARY_W_BOX_RIGHT_H:PRIMARY_W_BOX_RIGHT_L)
986 #define PRIMARY_W_BOX_BOT               (Current_display_mode?PRIMARY_W_BOX_BOT_H:PRIMARY_W_BOX_BOT_L)
987
988 #define SECONDARY_W_BOX_LEFT_L  202     //207
989 #define SECONDARY_W_BOX_TOP_L           151
990 #define SECONDARY_W_BOX_RIGHT_L 263     //(SECONDARY_W_BOX_LEFT+54)
991 #define SECONDARY_W_BOX_BOT_L           (SECONDARY_W_BOX_TOP_L+N_RIGHT_WINDOW_SPANS-1)
992
993 #define SECONDARY_W_BOX_LEFT_H  404
994 #define SECONDARY_W_BOX_TOP_H           363
995 #define SECONDARY_W_BOX_RIGHT_H 529
996 #define SECONDARY_W_BOX_BOT_H           (SECONDARY_W_BOX_TOP_H+N_RIGHT_WINDOW_SPANS_H-1)                //470
997
998 #define SECONDARY_W_BOX_LEFT    (Current_display_mode?SECONDARY_W_BOX_LEFT_H:SECONDARY_W_BOX_LEFT_L)
999 #define SECONDARY_W_BOX_TOP     (Current_display_mode?SECONDARY_W_BOX_TOP_H:SECONDARY_W_BOX_TOP_L)
1000 #define SECONDARY_W_BOX_RIGHT   (Current_display_mode?SECONDARY_W_BOX_RIGHT_H:SECONDARY_W_BOX_RIGHT_L)
1001 #define SECONDARY_W_BOX_BOT     (Current_display_mode?SECONDARY_W_BOX_BOT_H:SECONDARY_W_BOX_BOT_L)
1002
1003 #define SB_PRIMARY_W_BOX_LEFT_L         34              //50
1004 #define SB_PRIMARY_W_BOX_TOP_L          153
1005 #define SB_PRIMARY_W_BOX_RIGHT_L                (SB_PRIMARY_W_BOX_LEFT_L+53+2)
1006 #define SB_PRIMARY_W_BOX_BOT_L          (195+1)
1007                                                                                         
1008 #define SB_PRIMARY_W_BOX_LEFT_H         68
1009 #define SB_PRIMARY_W_BOX_TOP_H          381
1010 #define SB_PRIMARY_W_BOX_RIGHT_H                179
1011 #define SB_PRIMARY_W_BOX_BOT_H          473
1012                                                                                         
1013 #define SB_PRIMARY_W_BOX_LEFT           (Current_display_mode?SB_PRIMARY_W_BOX_LEFT_H:SB_PRIMARY_W_BOX_LEFT_L)
1014 #define SB_PRIMARY_W_BOX_TOP            (Current_display_mode?SB_PRIMARY_W_BOX_TOP_H:SB_PRIMARY_W_BOX_TOP_L)
1015 #define SB_PRIMARY_W_BOX_RIGHT  (Current_display_mode?SB_PRIMARY_W_BOX_RIGHT_H:SB_PRIMARY_W_BOX_RIGHT_L)
1016 #define SB_PRIMARY_W_BOX_BOT            (Current_display_mode?SB_PRIMARY_W_BOX_BOT_H:SB_PRIMARY_W_BOX_BOT_L)
1017                                                                                         
1018 #define SB_SECONDARY_W_BOX_LEFT_L       169
1019 #define SB_SECONDARY_W_BOX_TOP_L                153
1020 #define SB_SECONDARY_W_BOX_RIGHT_L      (SB_SECONDARY_W_BOX_LEFT_L+54+1)
1021 #define SB_SECONDARY_W_BOX_BOT_L                (153+43)
1022
1023 #define SB_SECONDARY_W_BOX_LEFT_H       338
1024 #define SB_SECONDARY_W_BOX_TOP_H                381
1025 #define SB_SECONDARY_W_BOX_RIGHT_H      449
1026 #define SB_SECONDARY_W_BOX_BOT_H                473
1027
1028 #define SB_SECONDARY_W_BOX_LEFT (Current_display_mode?SB_SECONDARY_W_BOX_LEFT_H:SB_SECONDARY_W_BOX_LEFT_L)      //210
1029 #define SB_SECONDARY_W_BOX_TOP  (Current_display_mode?SB_SECONDARY_W_BOX_TOP_H:SB_SECONDARY_W_BOX_TOP_L)
1030 #define SB_SECONDARY_W_BOX_RIGHT        (Current_display_mode?SB_SECONDARY_W_BOX_RIGHT_H:SB_SECONDARY_W_BOX_RIGHT_L)
1031 #define SB_SECONDARY_W_BOX_BOT  (Current_display_mode?SB_SECONDARY_W_BOX_BOT_H:SB_SECONDARY_W_BOX_BOT_L)
1032
1033 #define SB_PRIMARY_W_PIC_X                      (SB_PRIMARY_W_BOX_LEFT+1)       //51
1034 #define SB_PRIMARY_W_PIC_Y                      (Current_display_mode?382:154)
1035 #define SB_PRIMARY_W_TEXT_X             (SB_PRIMARY_W_BOX_LEFT+(Current_display_mode?50:24))    //(51+23)
1036 #define SB_PRIMARY_W_TEXT_Y             (Current_display_mode?390:157)
1037 #define SB_PRIMARY_AMMO_X                       (SB_PRIMARY_W_BOX_LEFT+(Current_display_mode?(38+20):30))       //((SB_PRIMARY_W_BOX_LEFT+33)-3)        //(51+32)
1038 #define SB_PRIMARY_AMMO_Y                       (Current_display_mode?410:171)
1039
1040 #define SB_SECONDARY_W_PIC_X            (Current_display_mode?385:(SB_SECONDARY_W_BOX_LEFT+29)) //(212+27)
1041 #define SB_SECONDARY_W_PIC_Y            (Current_display_mode?382:154)
1042 #define SB_SECONDARY_W_TEXT_X           (SB_SECONDARY_W_BOX_LEFT+2)     //212
1043 #define SB_SECONDARY_W_TEXT_Y           (Current_display_mode?389:157)
1044 #define SB_SECONDARY_AMMO_X             (SB_SECONDARY_W_BOX_LEFT+(Current_display_mode?(14-4):11))      //(212+9)
1045 #define SB_SECONDARY_AMMO_Y             (Current_display_mode?414:171)
1046
1047 typedef struct gauge_box {
1048         int left,top;
1049         int right,bot;          //maximal box
1050         span *spanlist; //list of left,right spans for copy
1051 } gauge_box;
1052
1053 gauge_box gauge_boxes[] = {
1054
1055 // primary left/right low res
1056                 {PRIMARY_W_BOX_LEFT_L,PRIMARY_W_BOX_TOP_L,PRIMARY_W_BOX_RIGHT_L,PRIMARY_W_BOX_BOT_L,weapon_window_left},
1057                 {SECONDARY_W_BOX_LEFT_L,SECONDARY_W_BOX_TOP_L,SECONDARY_W_BOX_RIGHT_L,SECONDARY_W_BOX_BOT_L,weapon_window_right},
1058
1059 //sb left/right low res
1060                 {SB_PRIMARY_W_BOX_LEFT_L,SB_PRIMARY_W_BOX_TOP_L,SB_PRIMARY_W_BOX_RIGHT_L,SB_PRIMARY_W_BOX_BOT_L,NULL},
1061                 {SB_SECONDARY_W_BOX_LEFT_L,SB_SECONDARY_W_BOX_TOP_L,SB_SECONDARY_W_BOX_RIGHT_L,SB_SECONDARY_W_BOX_BOT_L,NULL},
1062
1063 // primary left/right hires
1064                 {PRIMARY_W_BOX_LEFT_H,PRIMARY_W_BOX_TOP_H,PRIMARY_W_BOX_RIGHT_H,PRIMARY_W_BOX_BOT_H,weapon_window_left_hires},
1065                 {SECONDARY_W_BOX_LEFT_H,SECONDARY_W_BOX_TOP_H,SECONDARY_W_BOX_RIGHT_H,SECONDARY_W_BOX_BOT_H,weapon_window_right_hires},
1066
1067 // sb left/right hires
1068                 {SB_PRIMARY_W_BOX_LEFT_H,SB_PRIMARY_W_BOX_TOP_H,SB_PRIMARY_W_BOX_RIGHT_H,SB_PRIMARY_W_BOX_BOT_H,NULL},
1069                 {SB_SECONDARY_W_BOX_LEFT_H,SB_SECONDARY_W_BOX_TOP_H,SB_SECONDARY_W_BOX_RIGHT_H,SB_SECONDARY_W_BOX_BOT_H,NULL},
1070         };
1071
1072 // these macros refer to arrays above
1073
1074 #define COCKPIT_PRIMARY_BOX             (!Current_display_mode?0:4)
1075 #define COCKPIT_SECONDARY_BOX           (!Current_display_mode?1:5)
1076 #define SB_PRIMARY_BOX                          (!Current_display_mode?2:6)
1077 #define SB_SECONDARY_BOX                        (!Current_display_mode?3:7)
1078
1079 int     Color_0_31_0 = -1;
1080
1081 //copy a box from the off-screen buffer to the visible page
1082 #ifdef WINDOWS
1083 void copy_gauge_box(gauge_box *box,dd_grs_canvas *cv)
1084 {
1085 //      This is kind of funny.  If we are in a full cockpit mode
1086 //      we have a system offscreen buffer for our canvas.
1087 //      Since this is true of cockpit mode only, we should do a 
1088 //      direct copy from system to video memory without blting.
1089
1090         if (box->spanlist) {
1091                 int n_spans = box->bot-box->top+1;
1092                 int cnt,y;
1093
1094                 if (Cockpit_mode==CM_FULL_COCKPIT && cv->sram) {
1095                         grs_bitmap *bm;
1096
1097                         Assert(cv->sram);
1098                 DDGRLOCK(cv);
1099                 DDGRLOCK(dd_grd_curcanv);
1100                         bm = &cv->canvas.cv_bitmap;             
1101         
1102                         for (cnt=0,y=box->top;cnt<n_spans;cnt++,y++)
1103                         {
1104                                 gr_bm_ubitblt(box->spanlist[cnt].r-box->spanlist[cnt].l+1,1,
1105                                                         box->left+box->spanlist[cnt].l,y,box->left+box->spanlist[cnt].l,y,bm,&grd_curcanv->cv_bitmap);
1106                         }
1107                 DDGRUNLOCK(dd_grd_curcanv);
1108                 DDGRUNLOCK(cv);
1109                 }
1110                 else {
1111                         for (cnt=0,y=box->top;cnt<n_spans;cnt++,y++)
1112                         {
1113                                 dd_gr_blt_notrans(cv, 
1114                                                                 box->left+box->spanlist[cnt].l,y,
1115                                                                 box->spanlist[cnt].r-box->spanlist[cnt].l+1,1,
1116                                                                 dd_grd_curcanv,
1117                                                                 box->left+box->spanlist[cnt].l,y,
1118                                                                 box->spanlist[cnt].r-box->spanlist[cnt].l+1,1);
1119                         }
1120                 }
1121         }
1122         else {
1123                 dd_gr_blt_notrans(cv, box->left, box->top, 
1124                                                 box->right-box->left+1, box->bot-box->top+1,
1125                                                 dd_grd_curcanv, box->left, box->top,
1126                                                 box->right-box->left+1, box->bot-box->top+1);
1127         }
1128 }
1129
1130 #else
1131
1132 void copy_gauge_box(gauge_box *box,grs_bitmap *bm)
1133 {
1134         if (box->spanlist) {
1135                 int n_spans = box->bot-box->top+1;
1136                 int cnt,y;
1137
1138 //gr_setcolor(BM_XRGB(31,0,0));
1139
1140                 for (cnt=0,y=box->top;cnt<n_spans;cnt++,y++) {
1141                         PA_DFX (pa_set_frontbuffer_current());
1142                         PA_DFX (pa_set_back_to_read());
1143
1144                         gr_bm_ubitblt(box->spanlist[cnt].r-box->spanlist[cnt].l+1,1,
1145                                                 box->left+box->spanlist[cnt].l,y,box->left+box->spanlist[cnt].l,y,bm,&grd_curcanv->cv_bitmap);
1146
1147                         //gr_scanline(box->left+box->spanlist[cnt].l,box->left+box->spanlist[cnt].r,y);
1148                         PA_DFX (pa_set_backbuffer_current());
1149                         PA_DFX (pa_set_front_to_read());
1150
1151                 }
1152         }
1153         else
1154          {
1155                 PA_DFX (pa_set_frontbuffer_current());
1156                 PA_DFX (pa_set_back_to_read());
1157         
1158                 gr_bm_ubitblt(box->right-box->left+1,box->bot-box->top+1,
1159                                                 box->left,box->top,box->left,box->top,
1160                                                 bm,&grd_curcanv->cv_bitmap);
1161                 PA_DFX (pa_set_backbuffer_current());
1162                 PA_DFX (pa_set_front_to_read());
1163          }
1164 }
1165 #endif
1166
1167 #ifdef MACINTOSH
1168
1169 extern int gr_bitblt_double;
1170
1171 int copy_whole_box = 0;
1172
1173 void copy_gauge_box_double(gauge_box *box,grs_bitmap *bm)
1174 {
1175
1176         if (!copy_whole_box && box->spanlist) {
1177                 int n_spans = box->bot-box->top+1;
1178                 int cnt, sx, dx, sy, dy;
1179
1180                 sy = dy = box->top;
1181                 for (cnt=0; cnt < n_spans; cnt++) {
1182                         ubyte * dbits;
1183                         ubyte * sbits;
1184                         int i, j;
1185                         
1186                         sx = box->left;
1187                         dx = box->left+box->spanlist[cnt].l;
1188
1189                         sbits = bm->bm_data  + (bm->bm_rowsize * sy) + sx;
1190                         dbits = grd_curcanv->cv_bitmap.bm_data + (grd_curcanv->cv_bitmap.bm_rowsize * dy) + dx;
1191                         
1192                         for (j = box->spanlist[cnt].l; j < box->spanlist[cnt].r+1; j++)
1193                                 *dbits++ = sbits[j/2];
1194                         
1195                         dy++;
1196                 
1197                         if (cnt & 1)
1198                                 sy++;
1199                 }
1200
1201         }
1202         else
1203                 gr_bm_ubitblt_double_slow(box->right-box->left+1,box->bot-box->top,
1204                                                         box->left,box->top,box->left,box->top,
1205                                                         bm,&grd_curcanv->cv_bitmap);
1206 }
1207 #endif
1208
1209
1210 //fills in the coords of the hostage video window
1211 void get_hostage_window_coords(int *x,int *y,int *w,int *h)
1212 {
1213         if (Cockpit_mode == CM_STATUS_BAR) {
1214                 *x = SB_SECONDARY_W_BOX_LEFT;
1215                 *y = SB_SECONDARY_W_BOX_TOP;
1216                 *w = SB_SECONDARY_W_BOX_RIGHT - SB_SECONDARY_W_BOX_LEFT + 1;
1217                 *h = SB_SECONDARY_W_BOX_BOT - SB_SECONDARY_W_BOX_TOP + 1;
1218         }
1219         else {
1220                 *x = SECONDARY_W_BOX_LEFT;
1221                 *y = SECONDARY_W_BOX_TOP;
1222                 *w = SECONDARY_W_BOX_RIGHT - SECONDARY_W_BOX_LEFT + 1;
1223                 *h = SECONDARY_W_BOX_BOT - SECONDARY_W_BOX_TOP + 1;
1224         }
1225
1226 }
1227
1228 //these should be in gr.h 
1229 #define cv_w  cv_bitmap.bm_w
1230 #define cv_h  cv_bitmap.bm_h
1231
1232 extern int HUD_nmessages, hud_first; // From hud.c
1233 extern char HUD_messages[HUD_MAX_NUM][HUD_MESSAGE_LENGTH+5]; 
1234 extern fix ThisLevelTime;
1235 extern fix Omega_charge;
1236
1237 void hud_show_score()
1238 {
1239         char    score_str[20];
1240         int     w, h, aw;
1241
1242         if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
1243                 return;
1244
1245         gr_set_curfont( GAME_FONT );
1246
1247         if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) ) {
1248                 sprintf(score_str, "%s: %5d", TXT_KILLS, Players[Player_num].net_kills_total);
1249         } else {
1250                 sprintf(score_str, "%s: %5d", TXT_SCORE, Players[Player_num].score);
1251         }
1252
1253         gr_get_string_size(score_str, &w, &h, &aw );
1254
1255         if (Color_0_31_0 == -1)
1256                 Color_0_31_0 = gr_getcolor(0,31,0);
1257         gr_set_fontcolor(Color_0_31_0, -1);
1258
1259         gr_printf(grd_curcanv->cv_w-w-LHX(2), 3, score_str);
1260  }
1261
1262 void hud_show_timer_count()
1263  {
1264 #ifdef NETWORK
1265         char    score_str[20];
1266         int     w, h, aw,i;
1267         fix timevar=0;
1268 #endif
1269
1270         if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
1271                 return;
1272
1273 #ifdef NETWORK
1274    if ((Game_mode & GM_NETWORK) && Netgame.PlayTimeAllowed)
1275     {
1276      timevar=i2f (Netgame.PlayTimeAllowed*5*60);
1277      i=f2i(timevar-ThisLevelTime);
1278      i++;
1279     
1280      sprintf(score_str, "T - %5d", i);
1281                                                                                                                                                                                                  
1282      gr_get_string_size(score_str, &w, &h, &aw );
1283
1284      if (Color_0_31_0 == -1)
1285                 Color_0_31_0 = gr_getcolor(0,31,0);
1286      gr_set_fontcolor(Color_0_31_0, -1);
1287
1288      if (i>-1 && !Control_center_destroyed)
1289              gr_printf(grd_curcanv->cv_w-w-LHX(10), LHX(11), score_str);
1290     }
1291 #endif
1292  }
1293
1294
1295 //y offset between lines on HUD
1296 int Line_spacing;
1297
1298 void hud_show_score_added()
1299 {
1300         int     color;
1301         int     w, h, aw;
1302         char    score_str[20];
1303
1304         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1305                 return;
1306
1307         if (score_display[0] == 0)
1308                 return;
1309
1310         gr_set_curfont( GAME_FONT );
1311
1312         score_time -= FrameTime;
1313         if (score_time > 0) {
1314                 color = f2i(score_time * 20) + 12;
1315
1316                 if (color < 10) color = 12;
1317                 if (color > 31) color = 30;
1318
1319                 color = color - (color % 4);    //      Only allowing colors 12,16,20,24,28 speeds up gr_getcolor, improves caching
1320
1321                 if (Cheats_enabled)
1322                         sprintf(score_str, "%s", TXT_CHEATER);
1323                 else
1324                         sprintf(score_str, "%5d", score_display[0]);
1325
1326                 gr_get_string_size(score_str, &w, &h, &aw );
1327                 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
1328                 gr_printf(grd_curcanv->cv_w-w-LHX(2+10), Line_spacing+4, score_str);
1329         } else {
1330                 score_time = 0;
1331                 score_display[0] = 0;
1332         }
1333         
1334 }
1335
1336 void sb_show_score()
1337 {                                                                                                                                                                                                                                                                    
1338         char    score_str[20];
1339         int x,y;
1340         int     w, h, aw;
1341         static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1342         int redraw_score;
1343
1344 WIN(DDGRLOCK(dd_grd_curcanv));
1345         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1346                 redraw_score = -99;
1347         else
1348                 redraw_score = -1;
1349
1350         if (old_score[VR_current_page]==redraw_score) {
1351                 gr_set_curfont( GAME_FONT );
1352                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1353
1354                 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1355                         {
1356                          PA_DFX(pa_set_frontbuffer_current()); 
1357           PA_DFX(gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS)); 
1358           PA_DFX(pa_set_backbuffer_current()); 
1359                          gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS);
1360                         }
1361                 else
1362                   {
1363                    PA_DFX (pa_set_frontbuffer_current() );
1364                         PA_DFX (gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE) );
1365          PA_DFX(pa_set_backbuffer_current()); 
1366                         gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE);
1367                   }
1368         }
1369
1370         gr_set_curfont( GAME_FONT );
1371         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1372                 sprintf(score_str, "%5d", Players[Player_num].net_kills_total);
1373         else
1374                 sprintf(score_str, "%5d", Players[Player_num].score);
1375         gr_get_string_size(score_str, &w, &h, &aw );
1376
1377         x = SB_SCORE_RIGHT-w-LHX(2);
1378         y = SB_SCORE_Y;
1379         
1380         //erase old score
1381         gr_setcolor(BM_XRGB(0,0,0));
1382    PA_DFX (pa_set_frontbuffer_current());
1383         PA_DFX (gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h));
1384    PA_DFX(pa_set_backbuffer_current()); 
1385         gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h);
1386
1387         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1388                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1389         else
1390                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );      
1391  
1392    PA_DFX (pa_set_frontbuffer_current());
1393         PA_DFX (gr_printf(x,y,score_str));
1394    PA_DFX(pa_set_backbuffer_current()); 
1395         gr_printf(x,y,score_str);
1396
1397         last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1398 WIN(DDGRUNLOCK(dd_grd_curcanv));
1399 }
1400
1401 void sb_show_score_added()
1402 {
1403         int     color;
1404         int w, h, aw;
1405         char    score_str[32];
1406         int x;
1407         static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1408         static  int last_score_display[2] = { -1, -1};
1409    int frc=0;
1410         PA_DFX (frc=0);
1411         
1412         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1413                 return;
1414
1415         if (score_display[VR_current_page] == 0)
1416                 return;
1417
1418 WIN(DDGRLOCK(dd_grd_curcanv));
1419         gr_set_curfont( GAME_FONT );
1420
1421         score_time -= FrameTime;
1422         if (score_time > 0) {
1423                 if (score_display[VR_current_page] != last_score_display[VR_current_page] || frc) {
1424                         gr_setcolor(BM_XRGB(0,0,0));
1425                         PA_DFX (pa_set_frontbuffer_current());
1426                         PA_DFX (gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h));
1427                    PA_DFX(pa_set_backbuffer_current()); 
1428                         gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h);
1429
1430                         last_score_display[VR_current_page] = score_display[VR_current_page];
1431                 }
1432
1433                 color = f2i(score_time * 20) + 10;
1434
1435                 if (color < 10) color = 10;
1436                 if (color > 31) color = 31;
1437
1438                 if (Cheats_enabled)
1439                         sprintf(score_str, "%s", TXT_CHEATER);
1440                 else
1441                         sprintf(score_str, "%5d", score_display[VR_current_page]);
1442
1443                 gr_get_string_size(score_str, &w, &h, &aw );
1444
1445                 x = SB_SCORE_ADDED_RIGHT-w-LHX(2);
1446
1447                 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
1448
1449                 PA_DFX (pa_set_frontbuffer_current());
1450                 PA_DFX (gr_printf(x, SB_SCORE_ADDED_Y, score_str));
1451       PA_DFX(pa_set_backbuffer_current()); 
1452                 gr_printf(x, SB_SCORE_ADDED_Y, score_str);
1453
1454
1455                 last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1456
1457         } else {
1458                 //erase old score
1459                 gr_setcolor(BM_XRGB(0,0,0));
1460                 PA_DFX (pa_set_frontbuffer_current());
1461                 PA_DFX (gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h));
1462            PA_DFX(pa_set_backbuffer_current()); 
1463                 gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],SB_SCORE_ADDED_Y,SB_SCORE_ADDED_RIGHT,SB_SCORE_ADDED_Y+GAME_FONT->ft_h);
1464
1465                 score_time = 0;
1466                 score_display[VR_current_page] = 0;
1467
1468         }
1469 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1470 }
1471
1472 fix     Last_warning_beep_time[2] = {0,0};              //      Time we last played homing missile warning beep.
1473
1474 //      -----------------------------------------------------------------------------
1475 void play_homing_warning(void)
1476 {
1477         fix     beep_delay;
1478
1479         if (Endlevel_sequence || Player_is_dead)
1480                 return;
1481
1482         if (Players[Player_num].homing_object_dist >= 0) {
1483                 beep_delay = Players[Player_num].homing_object_dist/128;
1484                 if (beep_delay > F1_0)
1485                         beep_delay = F1_0;
1486                 else if (beep_delay < F1_0/8)
1487                         beep_delay = F1_0/8;
1488
1489                 if (Last_warning_beep_time[VR_current_page] > GameTime)
1490                         Last_warning_beep_time[VR_current_page] = 0;
1491
1492                 if (GameTime - Last_warning_beep_time[VR_current_page] > beep_delay/2) {
1493                         digi_play_sample( SOUND_HOMING_WARNING, F1_0 );
1494                         Last_warning_beep_time[VR_current_page] = GameTime;
1495                 }
1496         }
1497 }
1498
1499 int     Last_homing_warning_shown[2]={-1,-1};
1500
1501 //      -----------------------------------------------------------------------------
1502 void show_homing_warning(void)
1503 {
1504         if ((Cockpit_mode == CM_STATUS_BAR) || (Endlevel_sequence)) {
1505                 if (Last_homing_warning_shown[VR_current_page] == 1) {
1506                         PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1507
1508                         WIN(DDGRLOCK(dd_grd_curcanv));
1509                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1510                         WIN(DDGRUNLOCK(dd_grd_curcanv));
1511
1512                         Last_homing_warning_shown[VR_current_page] = 0;
1513                 }
1514                 return;
1515         }
1516
1517         WINDOS(
1518                 dd_gr_set_current_canvas( get_current_game_screen() ),
1519                 gr_set_current_canvas( get_current_game_screen() )
1520         );
1521
1522
1523 WIN(DDGRLOCK(dd_grd_curcanv))
1524 {
1525         if (Players[Player_num].homing_object_dist >= 0) {
1526
1527                 if (GameTime & 0x4000) {
1528                         if (Last_homing_warning_shown[VR_current_page] != 1) {
1529                                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_ON );
1530                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_ON) ] );
1531                                 Last_homing_warning_shown[VR_current_page] = 1;
1532                         }
1533                 } else {
1534                         if (Last_homing_warning_shown[VR_current_page] != 0) {
1535                                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1536                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1537                                 Last_homing_warning_shown[VR_current_page] = 0;
1538                         }
1539                 }
1540         } else if (Last_homing_warning_shown[VR_current_page] != 0) {
1541                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1542                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1543                 Last_homing_warning_shown[VR_current_page] = 0;
1544         }
1545 }
1546 WIN(DDGRUNLOCK(dd_grd_curcanv));
1547
1548 }
1549
1550 #define MAX_SHOWN_LIVES 4
1551
1552 extern int Game_window_y;
1553 extern int SW_y[2];
1554
1555 void hud_show_homing_warning(void)
1556 {
1557         if (Players[Player_num].homing_object_dist >= 0) {
1558                 if (GameTime & 0x4000) {
1559                         int x=0x8000, y=grd_curcanv->cv_h-Line_spacing;
1560
1561                         if (weapon_box_user[0] != WBU_WEAPON || weapon_box_user[1] != WBU_WEAPON) {
1562                                 int wy = (weapon_box_user[0] != WBU_WEAPON)?SW_y[0]:SW_y[1];
1563                                 y = min(y,(wy - Line_spacing - Game_window_y));
1564                         }
1565
1566                         gr_set_curfont( GAME_FONT );
1567                         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1568                         gr_printf(x,y,TXT_LOCK);
1569                 }
1570         }
1571 }
1572
1573 void hud_show_keys(void)
1574 {
1575         int y = 3*Line_spacing;
1576         int dx = GAME_FONT->ft_w+GAME_FONT->ft_w/2;
1577
1578         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY) {
1579                 PAGE_IN_GAUGE( KEY_ICON_BLUE );
1580                 gr_ubitmapm(2,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_BLUE) ] );
1581
1582         }
1583
1584         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY) {
1585                 PAGE_IN_GAUGE( KEY_ICON_YELLOW );
1586                 gr_ubitmapm(2+dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_YELLOW) ] );
1587         }
1588
1589         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY) {
1590                 PAGE_IN_GAUGE( KEY_ICON_RED );
1591                 gr_ubitmapm(2+2*dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_RED) ] );
1592         }
1593
1594 }
1595
1596 #ifdef NETWORK
1597 extern grs_bitmap Orb_icons[2];
1598
1599 void hud_show_orbs (void)
1600 {
1601         if (Game_mode & GM_HOARD) {
1602                 int x,y;
1603                 grs_bitmap *bm;
1604
1605                 x=y=0;
1606
1607                 if (Cockpit_mode == CM_FULL_COCKPIT) {
1608                         y = 2*Line_spacing;
1609                         x = 4*GAME_FONT->ft_w;
1610                 }
1611                 else if (Cockpit_mode == CM_STATUS_BAR) {
1612                         y = Line_spacing;
1613                         x = GAME_FONT->ft_w;
1614                 }
1615                 else if (Cockpit_mode == CM_FULL_SCREEN) {
1616                         y = 5*Line_spacing;
1617                         x = GAME_FONT->ft_w;
1618                         if (FontHires)
1619                                 y += Line_spacing;
1620                 }
1621                 else
1622                         Int3();         //what sort of cockpit?
1623
1624                 bm = &Orb_icons[FontHires];
1625                 gr_ubitmapm(x,y,bm);
1626
1627                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1628                 gr_printf(x+bm->bm_w+bm->bm_w/2, y+(FontHires?2:1), "x %d", Players[Player_num].secondary_ammo[PROXIMITY_INDEX]);
1629
1630         }
1631 }
1632
1633 void hud_show_flag(void)
1634 {
1635         if ((Game_mode & GM_CAPTURE) && (Players[Player_num].flags & PLAYER_FLAGS_FLAG)) {
1636                 int x,y,icon;
1637
1638                 x=y=0;
1639
1640                 if (Cockpit_mode == CM_FULL_COCKPIT) {
1641                         y = 2*Line_spacing;
1642                         x = 4*GAME_FONT->ft_w;
1643                 }
1644                 else if (Cockpit_mode == CM_STATUS_BAR) {
1645                         y = Line_spacing;
1646                         x = GAME_FONT->ft_w;
1647                 }
1648                 else if (Cockpit_mode == CM_FULL_SCREEN) {
1649                         y = 5*Line_spacing;
1650                         x = GAME_FONT->ft_w;
1651                         if (FontHires)
1652                                 y += Line_spacing;
1653                 }
1654                 else
1655                         Int3();         //what sort of cockpit?
1656
1657
1658                 icon = (get_team(Player_num) == TEAM_BLUE)?FLAG_ICON_RED:FLAG_ICON_BLUE;
1659
1660                 PAGE_IN_GAUGE( icon );
1661                 gr_ubitmapm(x,y,&GameBitmaps[ GET_GAUGE_INDEX(icon) ] );
1662
1663         }
1664 }
1665 #endif
1666
1667 void hud_show_energy(void)
1668 {
1669         //gr_set_current_canvas(&VR_render_sub_buffer[0]);      //render off-screen
1670         gr_set_curfont( GAME_FONT );
1671         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1672         if (Game_mode & GM_MULTI)
1673                 gr_printf(2, grd_curcanv->cv_h-5*Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1674         else
1675                 gr_printf(2, grd_curcanv->cv_h-Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1676
1677         if (Newdemo_state==ND_STATE_RECORDING ) {
1678                 int energy = f2ir(Players[Player_num].energy);
1679
1680                 if (energy != old_energy[VR_current_page]) {
1681                         newdemo_record_player_energy(old_energy[VR_current_page], energy);
1682                         old_energy[VR_current_page] = energy;
1683                 }
1684         }
1685 }
1686
1687 void hud_show_afterburner(void)
1688 {
1689         int y;
1690
1691         if (! (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER))
1692                 return;         //don't draw if don't have
1693
1694         gr_set_curfont( GAME_FONT );
1695         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1696
1697         y = (Game_mode & GM_MULTI)?(-8*Line_spacing):(-3*Line_spacing);
1698
1699         gr_printf(2, grd_curcanv->cv_h+y, "burn: %d%%" , fixmul(Afterburner_charge,100));
1700
1701         if (Newdemo_state==ND_STATE_RECORDING ) {
1702
1703                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
1704                         newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
1705                         old_afterburner[VR_current_page] = Afterburner_charge;
1706                 }
1707         }
1708 }
1709
1710 char *d2_very_short_secondary_weapon_names[] =
1711                 {"Flash","Guided","SmrtMine","Mercury","Shaker"};
1712
1713 #define SECONDARY_WEAPON_NAMES_VERY_SHORT(weapon_num)                                   \
1714         ((weapon_num <= MEGA_INDEX)?(*(&TXT_CONCUSSION + (weapon_num))):        \
1715         d2_very_short_secondary_weapon_names[weapon_num-SMISSILE1_INDEX])
1716
1717 //return which bomb will be dropped next time the bomb key is pressed
1718 extern int which_bomb();
1719
1720 void show_bomb_count(int x,int y,int bg_color,int always_show)
1721 {
1722         int bomb,count,countx;
1723         char txt[5],*t;
1724
1725         bomb = which_bomb();
1726         count = Players[Player_num].secondary_ammo[bomb];
1727
1728         #ifndef RELEASE
1729         count = min(count,99);  //only have room for 2 digits - cheating give 200
1730         #endif
1731
1732         countx = (bomb==PROXIMITY_INDEX)?count:-count;
1733
1734         if (always_show && count == 0)          //no bombs, draw nothing on HUD
1735                 return;
1736
1737         if (!always_show && countx == old_bombcount[VR_current_page])
1738                 return;
1739
1740 WIN(DDGRLOCK(dd_grd_curcanv));
1741
1742 // I hate doing this off of hard coded coords!!!!
1743
1744         if (Cockpit_mode == CM_STATUS_BAR) {            //draw background
1745                 gr_setcolor(bg_color);
1746                 if (!Current_display_mode) {
1747                         gr_rect(169,189,189,196);
1748                         gr_setcolor(gr_find_closest_color(10,10,10));
1749                         gr_scanline(168,189,189);
1750                 } else {
1751                         PA_DFX (pa_set_frontbuffer_current());
1752                         PA_DFX (gr_rect(338,453,378,470));
1753          PA_DFX(pa_set_backbuffer_current()); 
1754                         gr_rect(338,453,378,470);
1755
1756                         gr_setcolor(gr_find_closest_color(10,10,10));
1757                         PA_DFX (pa_set_frontbuffer_current());
1758                         PA_DFX (gr_scanline(336,378,453));
1759          PA_DFX(pa_set_backbuffer_current()); 
1760                         gr_scanline(336,378,453);
1761                 }
1762         }
1763
1764         if (count)
1765                 gr_set_fontcolor((bomb==PROXIMITY_INDEX)?gr_find_closest_color(55,0,0):gr_getcolor(59,50,21),bg_color);
1766         else
1767                 gr_set_fontcolor(bg_color,bg_color);    //erase by drawing in background color
1768
1769         sprintf(txt,"B:%02d",count);
1770
1771         while ((t=strchr(txt,'1')) != NULL)
1772                 *t = '\x84';    //convert to wide '1'
1773
1774         PA_DFX (pa_set_frontbuffer_current());
1775         PA_DFX (gr_string(x,y,txt));
1776    PA_DFX(pa_set_backbuffer_current()); 
1777         gr_string(x,y,txt);
1778
1779 WIN(DDGRUNLOCK(dd_grd_curcanv));
1780
1781         old_bombcount[VR_current_page] = countx;
1782 }
1783
1784 void draw_primary_ammo_info(int ammo_count)
1785 {
1786         if (Cockpit_mode == CM_STATUS_BAR)
1787                 draw_ammo_info(SB_PRIMARY_AMMO_X,SB_PRIMARY_AMMO_Y,ammo_count,1);
1788         else
1789                 draw_ammo_info(PRIMARY_AMMO_X,PRIMARY_AMMO_Y,ammo_count,1);
1790 }
1791
1792 //convert '1' characters to special wide ones
1793 #define convert_1s(s) do {char *p=s; while ((p=strchr(p,'1')) != NULL) *p=132;} while(0)
1794
1795 void hud_show_weapons(void)
1796 {
1797         int     w, h, aw;
1798         int     y;
1799         char    *weapon_name;
1800         char    weapon_str[32];
1801
1802 //      gr_set_current_canvas(&VR_render_sub_buffer[0]);        //render off-screen
1803         gr_set_curfont( GAME_FONT );
1804         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1805
1806         y = grd_curcanv->cv_h;
1807
1808         if (Game_mode & GM_MULTI)
1809                 y -= 4*Line_spacing;
1810
1811         weapon_name = PRIMARY_WEAPON_NAMES_SHORT(Primary_weapon);
1812
1813         switch (Primary_weapon) {
1814                 case LASER_INDEX:
1815                         if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)
1816                                 sprintf(weapon_str, "%s %s %i", TXT_QUAD, weapon_name, Players[Player_num].laser_level+1);
1817                         else
1818                                 sprintf(weapon_str, "%s %i", weapon_name, Players[Player_num].laser_level+1);
1819                         break;
1820
1821                 case SUPER_LASER_INDEX: Int3(); break;  //no such thing as super laser
1822
1823                 case VULCAN_INDEX:              
1824                 case GAUSS_INDEX:                       
1825                         sprintf(weapon_str, "%s: %i", weapon_name, f2i((unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX] * (unsigned) VULCAN_AMMO_SCALE)); 
1826                         convert_1s(weapon_str);
1827                         break;
1828
1829                 case SPREADFIRE_INDEX:
1830                 case PLASMA_INDEX:
1831                 case FUSION_INDEX:
1832                 case HELIX_INDEX:
1833                 case PHOENIX_INDEX:
1834                         strcpy(weapon_str, weapon_name);
1835                         break;
1836                 case OMEGA_INDEX:
1837                         sprintf(weapon_str, "%s: %03i", weapon_name, Omega_charge * 100/MAX_OMEGA_CHARGE);
1838                         convert_1s(weapon_str);
1839                         break;
1840
1841                 default:                                                Int3(); weapon_str[0] = 0;      break;
1842         }
1843
1844         gr_get_string_size(weapon_str, &w, &h, &aw );
1845         gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-2*Line_spacing, weapon_str);
1846
1847         if (Primary_weapon == VULCAN_INDEX) {
1848                 if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0][VR_current_page]) {
1849                         if (Newdemo_state == ND_STATE_RECORDING)
1850                                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[Primary_weapon]);
1851                         old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[Primary_weapon];
1852                 }
1853         }
1854
1855         if (Primary_weapon == OMEGA_INDEX) {
1856                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
1857                         if (Newdemo_state == ND_STATE_RECORDING)
1858                                 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
1859                         Old_Omega_charge[VR_current_page] = Omega_charge;
1860                 }
1861         }
1862
1863         weapon_name = SECONDARY_WEAPON_NAMES_VERY_SHORT(Secondary_weapon);
1864
1865         sprintf(weapon_str, "%s %d",weapon_name,Players[Player_num].secondary_ammo[Secondary_weapon]);
1866         gr_get_string_size(weapon_str, &w, &h, &aw );
1867         gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-Line_spacing, weapon_str);
1868
1869         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
1870                 if (Newdemo_state == ND_STATE_RECORDING)
1871                         newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
1872                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
1873         }
1874
1875         show_bomb_count(grd_curcanv->cv_bitmap.bm_w-(3*GAME_FONT->ft_w+(FontHires?0:2)), y-3*Line_spacing,-1,1);
1876 }
1877
1878 void hud_show_cloak_invuln(void)
1879 {
1880         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1881
1882         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
1883                 int     y = grd_curcanv->cv_h;
1884
1885                 if (Game_mode & GM_MULTI)
1886                         y -= 7*Line_spacing;
1887                 else
1888                         y -= 4*Line_spacing;
1889
1890                 if ((Players[Player_num].cloak_time+CLOAK_TIME_MAX - GameTime > F1_0*3 ) || (GameTime & 0x8000))
1891                         gr_printf(2, y, "%s", TXT_CLOAKED);
1892         }
1893
1894         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
1895                 int     y = grd_curcanv->cv_h;
1896
1897                 if (Game_mode & GM_MULTI)
1898                         y -= 10*Line_spacing;
1899                 else
1900                         y -= 5*Line_spacing;
1901
1902                 if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000))
1903                         gr_printf(2, y, "%s", TXT_INVULNERABLE);
1904         }
1905
1906 }
1907
1908 void hud_show_shield(void)
1909 {
1910 //      gr_set_current_canvas(&VR_render_sub_buffer[0]);        //render off-screen
1911         gr_set_curfont( GAME_FONT );
1912         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1913
1914         if ( Players[Player_num].shields >= 0 ) {
1915                 if (Game_mode & GM_MULTI)
1916                         gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1917                 else
1918                         gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1919         } else {
1920                 if (Game_mode & GM_MULTI)
1921                         gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: 0", TXT_SHIELD );
1922                 else
1923                         gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: 0", TXT_SHIELD );
1924         }
1925
1926         if (Newdemo_state==ND_STATE_RECORDING ) {
1927                 int shields = f2ir(Players[Player_num].shields);
1928
1929                 if (shields != old_shields[VR_current_page]) {          // Draw the shield gauge
1930                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
1931                         old_shields[VR_current_page] = shields;
1932                 }
1933         }
1934 }
1935
1936 //draw the icons for number of lives
1937 void hud_show_lives()
1938 {
1939         if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
1940                 return;
1941
1942         if (Game_mode & GM_MULTI) {
1943                 gr_set_curfont( GAME_FONT );
1944                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1945                 gr_printf(10, 3, "%s: %d", TXT_DEATHS, Players[Player_num].net_killed_total);
1946         } 
1947         else if (Players[Player_num].lives > 1)  {
1948                 grs_bitmap *bm;
1949                 gr_set_curfont( GAME_FONT );
1950                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1951                 PAGE_IN_GAUGE( GAUGE_LIVES );
1952                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1953                 gr_ubitmapm(10,3,bm);
1954                 gr_printf(10+bm->bm_w+bm->bm_w/2, 4, "x %d", Players[Player_num].lives-1);
1955         }
1956
1957 }
1958
1959 void sb_show_lives()
1960 {
1961         int x,y;
1962         grs_bitmap * bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1963    int frc=0;
1964         x = SB_LIVES_X;
1965         y = SB_LIVES_Y;
1966   
1967    PA_DFX (frc=0);
1968
1969         WIN(DDGRLOCK(dd_grd_curcanv));
1970         if (old_lives[VR_current_page]==-1 || frc) {
1971                 gr_set_curfont( GAME_FONT );
1972                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1973                 if (Game_mode & GM_MULTI)
1974                  {
1975                    PA_DFX (pa_set_frontbuffer_current());
1976                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS));
1977                    PA_DFX (pa_set_backbuffer_current());
1978                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS);
1979
1980                  }
1981                 else
1982                   {
1983                    PA_DFX (pa_set_frontbuffer_current());
1984                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES));
1985                    PA_DFX (pa_set_backbuffer_current());
1986                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES);
1987                  }
1988
1989         }
1990 WIN(DDGRUNLOCK(dd_grd_curcanv));
1991
1992         if (Game_mode & GM_MULTI)
1993         {
1994                 char killed_str[20];
1995                 int w, h, aw;
1996                 static int last_x[4] = {SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1997                 int x;
1998
1999         WIN(DDGRLOCK(dd_grd_curcanv));
2000                 sprintf(killed_str, "%5d", Players[Player_num].net_killed_total);
2001                 gr_get_string_size(killed_str, &w, &h, &aw);
2002                 gr_setcolor(BM_XRGB(0,0,0));
2003                 gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page], y+1, SB_SCORE_RIGHT, y+GAME_FONT->ft_h);
2004                 gr_set_fontcolor(gr_getcolor(0,20,0),-1);
2005                 x = SB_SCORE_RIGHT-w-2;         
2006                 gr_printf(x, y+1, killed_str);
2007                 last_x[(Current_display_mode?2:0)+VR_current_page] = x;
2008         WIN(DDGRUNLOCK(dd_grd_curcanv));
2009                 return;
2010         }
2011
2012         if (frc || old_lives[VR_current_page]==-1 || Players[Player_num].lives != old_lives[VR_current_page]) {
2013         WIN(DDGRLOCK(dd_grd_curcanv));
2014
2015                 //erase old icons
2016
2017                 gr_setcolor(BM_XRGB(0,0,0));
2018       
2019       PA_DFX (pa_set_frontbuffer_current());
2020            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
2021       PA_DFX (pa_set_backbuffer_current());
2022            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
2023
2024                 if (Players[Player_num].lives-1 > 0) {
2025                         gr_set_curfont( GAME_FONT );
2026                         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2027                         PAGE_IN_GAUGE( GAUGE_LIVES );
2028                         #ifdef PA_3DFX_VOODOO
2029                       PA_DFX (pa_set_frontbuffer_current());
2030                                 gr_ubitmapm(x, y,bm);
2031                                 gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
2032                         #endif
2033
2034               PA_DFX (pa_set_backbuffer_current());
2035                         gr_ubitmapm(x, y,bm);
2036                         gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
2037
2038 //                      gr_printf(x+12, y, "x %d", Players[Player_num].lives-1);
2039                 }
2040         WIN(DDGRUNLOCK(dd_grd_curcanv));
2041         }
2042
2043 //      for (i=0;i<draw_count;i++,x+=bm->bm_w+2)
2044 //              gr_ubitmapm(x,y,bm);
2045
2046 }
2047
2048 #ifndef RELEASE
2049
2050 #ifdef PIGGY_USE_PAGING
2051 extern int Piggy_bitmap_cache_next;
2052 #endif
2053
2054 void show_time()
2055 {
2056         int secs = f2i(Players[Player_num].time_level) % 60;
2057         int mins = f2i(Players[Player_num].time_level) / 60;
2058
2059         gr_set_curfont( GAME_FONT );
2060
2061         if (Color_0_31_0 == -1)
2062                 Color_0_31_0 = gr_getcolor(0,31,0);
2063         gr_set_fontcolor(Color_0_31_0, -1 );
2064
2065         gr_printf(grd_curcanv->cv_w-4*GAME_FONT->ft_w,grd_curcanv->cv_h-4*Line_spacing,"%d:%02d", mins, secs);
2066
2067 //@@#ifdef PIGGY_USE_PAGING
2068 //@@    {
2069 //@@            char text[25];
2070 //@@            int w,h,aw;
2071 //@@            sprintf( text, "%d KB", Piggy_bitmap_cache_next/1024 );
2072 //@@            gr_get_string_size( text, &w, &h, &aw );        
2073 //@@            gr_printf(grd_curcanv->cv_w-10-w,grd_curcanv->cv_h/2, text );
2074 //@@    }
2075 //@@#endif
2076
2077 }
2078 #endif
2079
2080 #define EXTRA_SHIP_SCORE        50000           //get new ship every this many points
2081
2082 void add_points_to_score(int points) 
2083 {
2084         int prev_score;
2085
2086         score_time += f1_0*2;
2087         score_display[0] += points;
2088         score_display[1] += points;
2089         if (score_time > f1_0*4) score_time = f1_0*4;
2090
2091         if (points == 0 || Cheats_enabled)
2092                 return;
2093
2094         if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
2095                 return;
2096
2097         prev_score=Players[Player_num].score;
2098
2099         Players[Player_num].score += points;
2100
2101         if (Newdemo_state == ND_STATE_RECORDING)
2102                 newdemo_record_player_score(points);
2103
2104 #ifdef NETWORK
2105         if (Game_mode & GM_MULTI_COOP)
2106                 multi_send_score();
2107
2108         if (Game_mode & GM_MULTI)
2109                 return;
2110 #endif
2111
2112         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
2113                 int snd;
2114                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
2115                 powerup_basic(20, 20, 20, 0, TXT_EXTRA_LIFE);
2116                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
2117                         digi_play_sample( snd, F1_0 );
2118         }
2119 }
2120
2121 void add_bonus_points_to_score(int points) 
2122 {
2123         int prev_score;
2124
2125         if (points == 0 || Cheats_enabled)
2126                 return;
2127
2128         prev_score=Players[Player_num].score;
2129
2130         Players[Player_num].score += points;
2131
2132
2133         if (Newdemo_state == ND_STATE_RECORDING)
2134                 newdemo_record_player_score(points);
2135
2136         if (Game_mode & GM_MULTI)
2137                 return;
2138
2139         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
2140                 int snd;
2141                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
2142                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
2143                         digi_play_sample( snd, F1_0 );
2144         }
2145 }
2146
2147 #include "key.h"
2148
2149 void init_gauge_canvases()
2150 {
2151         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2152         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
2153
2154         Canv_LeftEnergyGauge = gr_create_canvas( LEFT_ENERGY_GAUGE_W, LEFT_ENERGY_GAUGE_H );
2155         Canv_SBEnergyGauge = gr_create_canvas( SB_ENERGY_GAUGE_W, SB_ENERGY_GAUGE_H );
2156         Canv_SBAfterburnerGauge = gr_create_canvas( SB_AFTERBURNER_GAUGE_W, SB_AFTERBURNER_GAUGE_H );
2157         Canv_RightEnergyGauge = gr_create_canvas( RIGHT_ENERGY_GAUGE_W, RIGHT_ENERGY_GAUGE_H );
2158         Canv_NumericalGauge = gr_create_canvas( NUMERICAL_GAUGE_W, NUMERICAL_GAUGE_H );
2159         Canv_AfterburnerGauge = gr_create_canvas( AFTERBURNER_GAUGE_W, AFTERBURNER_GAUGE_H );
2160
2161 }
2162
2163 void close_gauge_canvases()
2164 {
2165         gr_free_canvas( Canv_LeftEnergyGauge );
2166         gr_free_canvas( Canv_SBEnergyGauge );
2167         gr_free_canvas( Canv_SBAfterburnerGauge );
2168         gr_free_canvas( Canv_RightEnergyGauge );
2169         gr_free_canvas( Canv_NumericalGauge );
2170         gr_free_canvas( Canv_AfterburnerGauge );
2171 }
2172
2173 void init_gauges()
2174 {
2175         int i;
2176
2177         //draw_gauges_on        = 1;
2178
2179         for (i=0; i<2; i++ )    {
2180                 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)) ) 
2181                         old_score[i] = -99;
2182                 else
2183                         old_score[i]                    = -1;
2184                 old_energy[i]                   = -1;
2185                 old_shields[i]                  = -1;
2186                 old_flags[i]                    = -1;
2187                 old_cloak[i]                    = -1;
2188                 old_lives[i]                    = -1;
2189                 old_afterburner[i]      = -1;
2190                 old_bombcount[i]                = 0;
2191                 old_laser_level[i]      = 0;
2192         
2193                 old_weapon[0][i] = old_weapon[1][i] = -1;
2194                 old_ammo_count[0][i] = old_ammo_count[1][i] = -1;
2195                 Old_Omega_charge[i] = -1;
2196         }
2197
2198         cloak_fade_state = 0;
2199
2200         weapon_box_user[0] = weapon_box_user[1] = WBU_WEAPON;
2201 }
2202
2203 void draw_energy_bar(int energy)
2204 {
2205         int not_energy;
2206         int x1, x2, y;
2207
2208         // Draw left energy bar
2209         gr_set_current_canvas( Canv_LeftEnergyGauge );
2210         PAGE_IN_GAUGE( GAUGE_ENERGY_LEFT );
2211         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_LEFT)] );
2212         gr_setcolor( BM_XRGB(0,0,0) );
2213
2214         if ( !Current_display_mode )
2215                 not_energy = 61 - (energy*61)/100;
2216         else
2217                 not_energy = 125 - (energy*125)/100;
2218
2219         if (energy < 100)
2220                 for (y=0; y < LEFT_ENERGY_GAUGE_H; y++) {
2221                         x1 = LEFT_ENERGY_GAUGE_H - 1 - y;
2222                         x2 = LEFT_ENERGY_GAUGE_H - 1 - y + not_energy;
2223         
2224                         if ( y>=0 && y<(LEFT_ENERGY_GAUGE_H/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 1) x2 = LEFT_ENERGY_GAUGE_W - 1;
2225                         if ( y>=(LEFT_ENERGY_GAUGE_H/4) && y<((LEFT_ENERGY_GAUGE_H*3)/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 2) x2 = LEFT_ENERGY_GAUGE_W - 2;
2226                         if ( y>=((LEFT_ENERGY_GAUGE_H*3)/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 3) x2 = LEFT_ENERGY_GAUGE_W - 3;
2227                         
2228                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
2229                 }
2230         
2231         WINDOS(
2232                 dd_gr_set_current_canvas(get_current_game_screen()),
2233                 gr_set_current_canvas( get_current_game_screen() )
2234         );
2235         WIN(DDGRLOCK(dd_grd_curcanv));
2236                 gr_ubitmapm( LEFT_ENERGY_GAUGE_X, LEFT_ENERGY_GAUGE_Y, &Canv_LeftEnergyGauge->cv_bitmap );
2237         WIN(DDGRUNLOCK(dd_grd_curcanv));
2238
2239         // Draw right energy bar
2240         gr_set_current_canvas( Canv_RightEnergyGauge );
2241         PAGE_IN_GAUGE( GAUGE_ENERGY_RIGHT );
2242         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_RIGHT) ] );
2243         gr_setcolor( BM_XRGB(0,0,0) );
2244
2245         if (energy < 100)
2246                 for (y=0; y < RIGHT_ENERGY_GAUGE_H; y++) {
2247                         x1 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y - not_energy;
2248                         x2 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y;
2249         
2250                         if ( y>=0 && y<(RIGHT_ENERGY_GAUGE_H/4) ) if (x1 < 0) x1 = 0;
2251                         if ( y>=(RIGHT_ENERGY_GAUGE_H/4) && y<((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 1) x1 = 1;
2252                         if ( y>=((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 2) x1 = 2;
2253                         
2254                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
2255                 }
2256
2257         WINDOS(
2258                 dd_gr_set_current_canvas(get_current_game_screen()),
2259                 gr_set_current_canvas( get_current_game_screen() )
2260         );
2261         WIN(DDGRLOCK(dd_grd_curcanv));
2262                 gr_ubitmapm( RIGHT_ENERGY_GAUGE_X, RIGHT_ENERGY_GAUGE_Y, &Canv_RightEnergyGauge->cv_bitmap );
2263         WIN(DDGRUNLOCK(dd_grd_curcanv));
2264 }
2265
2266 ubyte afterburner_bar_table[AFTERBURNER_GAUGE_H_L*2] = {
2267                         3,11,
2268                         3,11,
2269                         3,11,
2270                         3,11,
2271                         3,11,
2272                         3,11,
2273                         2,11,
2274                         2,10,
2275                         2,10,
2276                         2,10,
2277                         2,10,
2278                         2,10,
2279                         2,10,
2280                         1,10,
2281                         1,10,
2282                         1,10,
2283                         1,9,
2284                         1,9,
2285                         1,9,
2286                         1,9,
2287                         0,9,
2288                         0,9,
2289                         0,8,
2290                         0,8,
2291                         0,8,
2292                         0,8,
2293                         1,8,
2294                         2,8,
2295                         3,8,
2296                         4,8,
2297                         5,8,
2298                         6,7,
2299 };
2300
2301 ubyte afterburner_bar_table_hires[AFTERBURNER_GAUGE_H_H*2] = {
2302         5,20,
2303         5,20,
2304         5,19,
2305         5,19,
2306         5,19,
2307         5,19,
2308         4,19,
2309         4,19,
2310         4,19,
2311         4,19,
2312
2313         4,19,
2314         4,18,
2315         4,18,
2316         4,18,
2317         4,18,
2318         3,18,
2319         3,18,
2320         3,18,
2321         3,18,
2322         3,18,
2323
2324         3,18,
2325         3,17,
2326         3,17,
2327         2,17,
2328         2,17,
2329         2,17,
2330         2,17,
2331         2,17,
2332         2,17,
2333         2,17,
2334
2335         2,17,
2336         2,16,
2337         2,16,
2338         1,16,
2339         1,16,
2340         1,16,
2341         1,16,
2342         1,16,
2343         1,16,
2344         1,16,
2345
2346         1,16,
2347         1,15,
2348         1,15,
2349         1,15,
2350         0,15,
2351         0,15,
2352         0,15,
2353         0,15,
2354         0,15,
2355         0,15,
2356
2357         0,14,
2358         0,14,
2359         0,14,
2360         1,14,
2361         2,14,
2362         3,14,
2363         4,14,
2364         5,14,
2365         6,13,
2366         7,13,
2367
2368         8,13,
2369         9,13,
2370         10,13,
2371         11,13,
2372         12,13
2373 };
2374
2375
2376 void draw_afterburner_bar(int afterburner)
2377 {
2378         int not_afterburner;
2379         int y;
2380
2381         // Draw afterburner bar
2382         gr_set_current_canvas( Canv_AfterburnerGauge );
2383         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
2384         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_AFTERBURNER) ] );
2385         gr_setcolor( BM_XRGB(0,0,0) );
2386
2387         not_afterburner = fixmul(f1_0 - afterburner,AFTERBURNER_GAUGE_H);
2388
2389         for (y=0;y<not_afterburner;y++) {
2390
2391                 gr_uscanline( (Current_display_mode?afterburner_bar_table_hires[y*2]:afterburner_bar_table[y*2]),
2392                                                 (Current_display_mode?afterburner_bar_table_hires[y*2+1]:afterburner_bar_table[y*2+1]), y ); 
2393         }
2394
2395         WINDOS(
2396                 dd_gr_set_current_canvas(get_current_game_screen()),
2397                 gr_set_current_canvas( get_current_game_screen() )
2398         );
2399         WIN(DDGRLOCK(dd_grd_curcanv));
2400                 gr_ubitmapm( AFTERBURNER_GAUGE_X, AFTERBURNER_GAUGE_Y, &Canv_AfterburnerGauge->cv_bitmap );
2401         WIN(DDGRUNLOCK(dd_grd_curcanv));
2402 }
2403
2404 void draw_shield_bar(int shield)
2405 {
2406         int bm_num = shield>=100?9:(shield / 10);
2407
2408         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num   );
2409         WIN(DDGRLOCK(dd_grd_curcanv));
2410         PA_DFX (pa_set_frontbuffer_current());
2411    PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
2412         PA_DFX (pa_set_backbuffer_current());
2413         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
2414
2415         WIN(DDGRUNLOCK(dd_grd_curcanv));
2416 }
2417
2418 #define CLOAK_FADE_WAIT_TIME  0x400
2419
2420 void draw_player_ship(int cloak_state,int old_cloak_state,int x, int y)
2421 {
2422         static fix cloak_fade_timer=0;
2423         static int cloak_fade_value=GR_FADE_LEVELS-1;
2424         static int refade = 0;
2425         grs_bitmap *bm = NULL;
2426
2427         if (Game_mode & GM_TEAM)        {
2428                 #ifdef NETWORK
2429                 PAGE_IN_GAUGE( GAUGE_SHIPS+get_team(Player_num) );
2430                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+get_team(Player_num)) ];
2431                 #endif
2432         } else {
2433                 PAGE_IN_GAUGE( GAUGE_SHIPS+Player_num );
2434                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+Player_num) ];
2435         }
2436         
2437
2438         if (old_cloak_state==-1 && cloak_state)
2439                         cloak_fade_value=0;
2440
2441 //      mprintf((0, "cloak/oldcloak %d/%d", cloak_state, old_cloak_state));
2442
2443         if (!cloak_state) {
2444                 cloak_fade_value=GR_FADE_LEVELS-1;
2445                 cloak_fade_state = 0;
2446         }
2447
2448         if (cloak_state==1 && old_cloak_state==0)
2449                 cloak_fade_state = -1;
2450         //else if (cloak_state==0 && old_cloak_state==1)
2451         //      cloak_fade_state = 1;
2452
2453         if (cloak_state==old_cloak_state)               //doing "about-to-uncloak" effect
2454                 if (cloak_fade_state==0)
2455                         cloak_fade_state = 2;
2456         
2457
2458         if (cloak_fade_state)
2459                 cloak_fade_timer -= FrameTime;
2460
2461         while (cloak_fade_state && cloak_fade_timer < 0) {
2462
2463                 cloak_fade_timer += CLOAK_FADE_WAIT_TIME;
2464
2465                 cloak_fade_value += cloak_fade_state;
2466
2467                 if (cloak_fade_value >= GR_FADE_LEVELS-1) {
2468                         cloak_fade_value = GR_FADE_LEVELS-1;
2469                         if (cloak_fade_state == 2 && cloak_state)
2470                                 cloak_fade_state = -2;
2471                         else
2472                                 cloak_fade_state = 0;
2473                 }
2474                 else if (cloak_fade_value <= 0) {
2475                         cloak_fade_value = 0;
2476                         if (cloak_fade_state == -2)
2477                                 cloak_fade_state = 2;
2478                         else
2479                                 cloak_fade_state = 0;
2480                 }
2481         }
2482
2483 //      To fade out both pages in a paged mode.
2484         if (refade) refade = 0;
2485         else if (cloak_state && old_cloak_state && !cloak_fade_state && !refade) {
2486                 cloak_fade_state = -1;
2487                 refade = 1;
2488         }
2489
2490 #if defined(POLY_ACC)
2491         #ifdef MACINTOSH
2492         if ( PAEnabled ) {
2493         #endif
2494             Gr_scanline_darkening_level = cloak_fade_value;
2495             gr_set_current_canvas( get_current_game_screen() );
2496             PA_DFX (pa_set_frontbuffer_current());      
2497             PA_DFX (pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h));
2498                  PA_DFX (pa_set_backbuffer_current());  
2499             pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h);
2500
2501             Gr_scanline_darkening_level = GR_FADE_LEVELS;
2502             return;
2503 //          }
2504 //          else
2505 //                  Gr_scanline_darkening_level = GR_FADE_LEVELS;
2506 //               mprintf ((1,"HEY! HIT THIS!\n"));      
2507 //               Int3();
2508         #ifdef MACINTOSH
2509         }
2510         #endif
2511 #endif
2512
2513         WINDOS(                 
2514                 dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2515                 gr_set_current_canvas(&VR_render_buffer[0])
2516         );
2517
2518         WIN(DDGRLOCK(dd_grd_curcanv));
2519                 gr_ubitmap( x, y, bm);
2520
2521                 Gr_scanline_darkening_level = cloak_fade_value;
2522                 gr_rect(x, y, x+bm->bm_w-1, y+bm->bm_h-1);
2523                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2524         WIN(DDGRUNLOCK(dd_grd_curcanv));
2525
2526         WINDOS(
2527                 dd_gr_set_current_canvas(get_current_game_screen()),
2528                 gr_set_current_canvas( get_current_game_screen() )
2529         );
2530
2531 #ifdef WINDOWS
2532         DDGRLOCK(dd_grd_curcanv);
2533         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2534                 DDGRLOCK(&dd_VR_render_buffer[0]);
2535         }
2536         else {
2537                 dd_gr_dup_hack(&dd_VR_render_buffer[0], dd_grd_curcanv);
2538         }
2539 #endif
2540         WINDOS(
2541                 gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &dd_VR_render_buffer[0].canvas.cv_bitmap, &grd_curcanv->cv_bitmap),
2542                 gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &VR_render_buffer[0].cv_bitmap, &grd_curcanv->cv_bitmap)
2543         );
2544 #ifdef WINDOWS
2545         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2546                 DDGRUNLOCK(&dd_VR_render_buffer[0]);
2547         }
2548         else {
2549                 dd_gr_dup_unhack(&dd_VR_render_buffer[0]);
2550         }
2551         DDGRUNLOCK(dd_grd_curcanv);
2552 #endif
2553 }
2554
2555 #define INV_FRAME_TIME  (f1_0/10)               //how long for each frame
2556
2557 void draw_numerical_display(int shield, int energy)
2558 {
2559         gr_set_current_canvas( Canv_NumericalGauge );
2560         gr_set_curfont( GAME_FONT );
2561         PAGE_IN_GAUGE( GAUGE_NUMERICAL );
2562         gr_ubitmap( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_NUMERICAL) ] );
2563
2564         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2565
2566         if (!Current_display_mode) {
2567                 gr_printf((shield>99)?3:((shield>9)?5:7),15,"%d",shield);
2568                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2569                 gr_printf((energy>99)?3:((energy>9)?5:7),2,"%d",energy);
2570         } else {
2571                 gr_printf((shield>99)?7:((shield>9)?11:15),33,"%d",shield);
2572                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2573                 gr_printf((energy>99)?7:((energy>9)?11:15),4,"%d",energy);
2574         }
2575         
2576         WINDOS(
2577                 dd_gr_set_current_canvas(get_current_game_screen()),
2578                 gr_set_current_canvas( get_current_game_screen() )
2579         );
2580         WIN(DDGRLOCK(dd_grd_curcanv));
2581                 gr_ubitmapm( NUMERICAL_GAUGE_X, NUMERICAL_GAUGE_Y, &Canv_NumericalGauge->cv_bitmap );
2582         WIN(DDGRUNLOCK(dd_grd_curcanv));
2583 }
2584
2585
2586 void draw_keys()
2587 {
2588 WINDOS(
2589         dd_gr_set_current_canvas( get_current_game_screen() ),
2590         gr_set_current_canvas( get_current_game_screen() )
2591 );
2592
2593 WIN(DDGRLOCK(dd_grd_curcanv));
2594         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY ) {
2595                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY );
2596                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY) ] );
2597         } else {
2598                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY_OFF );
2599                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY_OFF) ] );
2600         }
2601
2602         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)  {
2603                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY );
2604                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY) ] );
2605         } else {
2606                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY_OFF );
2607                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY_OFF) ] );
2608         }
2609
2610         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)   {
2611                 PAGE_IN_GAUGE( GAUGE_RED_KEY );
2612                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY) ] );
2613         } else {
2614                 PAGE_IN_GAUGE( GAUGE_RED_KEY_OFF );
2615                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY_OFF) ] );
2616         }
2617 WIN(DDGRUNLOCK(dd_grd_curcanv));
2618 }
2619
2620
2621 void draw_weapon_info_sub(int info_index,gauge_box *box,int pic_x,int pic_y,char *name,int text_x,int text_y)
2622 {
2623         grs_bitmap *bm;
2624         char *p;
2625
2626         //clear the window
2627         gr_setcolor(BM_XRGB(0,0,0));
2628         
2629   // PA_DFX (pa_set_frontbuffer_current());
2630 //      PA_DFX (gr_rect(box->left,box->top,box->right,box->bot));
2631    PA_DFX (pa_set_backbuffer_current());
2632         gr_rect(box->left,box->top,box->right,box->bot);
2633
2634         if (Piggy_hamfile_version >= 3 // !SHAREWARE
2635                 && Current_display_mode)
2636         {
2637                 bm=&GameBitmaps[Weapon_info[info_index].hires_picture.index];
2638                 PIGGY_PAGE_IN( Weapon_info[info_index].hires_picture );
2639         } else {
2640                 bm=&GameBitmaps[Weapon_info[info_index].picture.index];
2641                 PIGGY_PAGE_IN( Weapon_info[info_index].picture );
2642         }
2643
2644         Assert(bm != NULL);
2645
2646 //   PA_DFX (pa_set_frontbuffer_current());
2647 //      PA_DFX (gr_ubitmapm(pic_x,pic_y,bm));
2648    PA_DFX (pa_set_backbuffer_current());
2649         gr_ubitmapm(pic_x,pic_y,bm);
2650         
2651         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2652
2653         if ((p=strchr(name,'\n'))!=NULL) {
2654                 *p=0;
2655            #ifdef PA_3DFX_VOODOO
2656   //                    pa_set_frontbuffer_current();
2657 //                      gr_printf(text_x,text_y,name);
2658 //                      gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2659                 #endif
2660                 PA_DFX (pa_set_backbuffer_current());
2661                 gr_printf(text_x,text_y,name);
2662                 gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2663                 *p='\n';
2664         } else
2665          {
2666   //            PA_DFX(pa_set_frontbuffer_current());
2667 //              PA_DFX (gr_printf(text_x,text_y,name));
2668                 PA_DFX(pa_set_backbuffer_current());
2669                 gr_printf(text_x,text_y,name);
2670          }      
2671
2672         //      For laser, show level and quadness
2673         if (info_index == LASER_ID || info_index == SUPER_LASER_ID) {
2674                 char    temp_str[7];
2675
2676                 sprintf(temp_str, "%s: 0", TXT_LVL);
2677
2678                 temp_str[5] = Players[Player_num].laser_level+1 + '0';
2679
2680 //              PA_DFX(pa_set_frontbuffer_current());
2681 //              PA_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2682                 PA_DFX(pa_set_backbuffer_current());
2683                 NO_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2684                 PA_DFX (gr_printf(text_x,text_y+12, temp_str));
2685
2686                 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
2687                         strcpy(temp_str, TXT_QUAD);
2688 //                      PA_DFX(pa_set_frontbuffer_current());
2689 //                      PA_DFX (gr_printf(text_x,text_y+2*Line_spacing, temp_str));
2690                         PA_DFX(pa_set_backbuffer_current());
2691                         gr_printf(text_x,text_y+2*Line_spacing, temp_str);
2692
2693                 }
2694
2695         }
2696 }
2697
2698
2699 void draw_weapon_info(int weapon_type,int weapon_num,int laser_level)
2700 {
2701         int info_index;
2702
2703         if (weapon_type == 0) {
2704                 info_index = Primary_weapon_to_weapon_info[weapon_num];
2705
2706                 if (info_index == LASER_ID && laser_level > MAX_LASER_LEVEL)
2707                         info_index = SUPER_LASER_ID;
2708
2709                 if (Cockpit_mode == CM_STATUS_BAR)
2710                         draw_weapon_info_sub(info_index,
2711                                 &gauge_boxes[SB_PRIMARY_BOX],
2712                                 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
2713                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2714                                 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
2715                 else
2716                         draw_weapon_info_sub(info_index,
2717                                 &gauge_boxes[COCKPIT_PRIMARY_BOX],
2718                                 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
2719                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2720                                 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
2721
2722         }
2723         else {
2724                 info_index = Secondary_weapon_to_weapon_info[weapon_num];
2725
2726                 if (Cockpit_mode == CM_STATUS_BAR)
2727                         draw_weapon_info_sub(info_index,
2728                                 &gauge_boxes[SB_SECONDARY_BOX],
2729                                 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
2730                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2731                                 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
2732                 else
2733                         draw_weapon_info_sub(info_index,
2734                                 &gauge_boxes[COCKPIT_SECONDARY_BOX],
2735                                 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
2736                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2737                                 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
2738         }
2739 }
2740
2741 void draw_ammo_info(int x,int y,int ammo_count,int primary)
2742 {
2743         int w;
2744         char str[16];
2745
2746         if (primary)
2747                 w = (grd_curcanv->cv_font->ft_w*7)/2;
2748         else
2749                 w = (grd_curcanv->cv_font->ft_w*5)/2;
2750
2751 WIN(DDGRLOCK(dd_grd_curcanv));
2752 {
2753
2754         PA_DFX (pa_set_frontbuffer_current());
2755
2756         gr_setcolor(BM_XRGB(0,0,0));
2757         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2758         gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
2759         sprintf(str,"%03d",ammo_count);
2760         convert_1s(str);
2761         gr_printf(x,y,str);
2762
2763         PA_DFX (pa_set_backbuffer_current());
2764         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2765         gr_printf(x,y,str);
2766 }
2767
2768 WIN(DDGRUNLOCK(dd_grd_curcanv));
2769 }
2770
2771 void draw_secondary_ammo_info(int ammo_count)
2772 {
2773         if (Cockpit_mode == CM_STATUS_BAR)
2774                 draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
2775         else
2776                 draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
2777 }
2778
2779 //returns true if drew picture
2780 int draw_weapon_box(int weapon_type,int weapon_num)
2781 {
2782         int drew_flag=0;
2783         int laser_level_changed;
2784
2785 WINDOS(
2786         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2787         gr_set_current_canvas(&VR_render_buffer[0])
2788 );
2789
2790    PA_DFX (pa_set_backbuffer_current());
2791  
2792 WIN(DDGRLOCK(dd_grd_curcanv));
2793         gr_set_curfont( GAME_FONT );
2794
2795         laser_level_changed = (weapon_type==0 && weapon_num==LASER_INDEX && (Players[Player_num].laser_level != old_laser_level[VR_current_page]));
2796
2797         if ((weapon_num != old_weapon[weapon_type][VR_current_page] || laser_level_changed) && weapon_box_states[weapon_type] == WS_SET) {
2798                 weapon_box_states[weapon_type] = WS_FADING_OUT;
2799                 weapon_box_fade_values[weapon_type]=i2f(GR_FADE_LEVELS-1);
2800         }
2801                 
2802         if (old_weapon[weapon_type][VR_current_page] == -1) {
2803                 //@@if (laser_level_changed)
2804                 //@@    old_weapon[weapon_type][VR_current_page] = LASER_INDEX;
2805                 //@@else 
2806                 {
2807                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2808                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2809                         old_ammo_count[weapon_type][VR_current_page]=-1;
2810                         Old_Omega_charge[VR_current_page]=-1;
2811                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2812                         drew_flag=1;
2813                         weapon_box_states[weapon_type] = WS_SET;
2814                 }
2815         }
2816
2817         if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
2818                 draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page],old_laser_level[VR_current_page]);
2819                 old_ammo_count[weapon_type][VR_current_page]=-1;
2820                 Old_Omega_charge[VR_current_page]=-1;
2821                 drew_flag=1;
2822                 weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
2823                 if (weapon_box_fade_values[weapon_type] <= 0) {
2824                         weapon_box_states[weapon_type] = WS_FADING_IN;
2825                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2826                         old_weapon[weapon_type][!VR_current_page] = weapon_num;
2827                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2828                         old_laser_level[!VR_current_page] = Players[Player_num].laser_level;
2829                         weapon_box_fade_values[weapon_type] = 0;
2830                 }
2831         }
2832         else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
2833                 if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
2834                         weapon_box_states[weapon_type] = WS_FADING_OUT;
2835                 }
2836                 else {
2837                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2838                         old_ammo_count[weapon_type][VR_current_page]=-1;
2839                         Old_Omega_charge[VR_current_page]=-1;
2840                         drew_flag=1;
2841                         weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
2842                         if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
2843                                 weapon_box_states[weapon_type] = WS_SET;
2844                                 old_weapon[weapon_type][!VR_current_page] = -1;         //force redraw (at full fade-in) of other page
2845                         }
2846                 }
2847         }
2848
2849         if (weapon_box_states[weapon_type] != WS_SET) {         //fade gauge
2850                 int fade_value = f2i(weapon_box_fade_values[weapon_type]);
2851                 int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2852                 
2853                 Gr_scanline_darkening_level = fade_value;
2854 //         PA_DFX (pa_set_frontbuffer_current());
2855 //              PA_DFX (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));
2856            PA_DFX (pa_set_backbuffer_current());
2857                 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);
2858
2859                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2860         }
2861 WIN(DDGRUNLOCK(dd_grd_curcanv));
2862
2863 WINDOS(
2864         dd_gr_set_current_canvas(get_current_game_screen()),
2865         gr_set_current_canvas(get_current_game_screen())
2866 );
2867         return drew_flag;
2868 }
2869
2870 fix static_time[2];
2871
2872 void draw_static(int win)
2873 {
2874         vclip *vc = &Vclip[VCLIP_MONITOR_STATIC];
2875         grs_bitmap *bmp;
2876         int framenum;
2877         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2878         int x,y;
2879
2880         static_time[win] += FrameTime;
2881         if (static_time[win] >= vc->play_time) {
2882                 weapon_box_user[win] = WBU_WEAPON;
2883                 return;
2884         }
2885
2886         framenum = static_time[win] * vc->num_frames / vc->play_time;
2887
2888         PIGGY_PAGE_IN(vc->frames[framenum]);
2889
2890         bmp = &GameBitmaps[vc->frames[framenum].index];
2891
2892         WINDOS(
2893         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2894         gr_set_current_canvas(&VR_render_buffer[0])
2895         );
2896         WIN(DDGRLOCK(dd_grd_curcanv));
2897    PA_DFX (pa_set_backbuffer_current());
2898         PA_DFX (pa_bypass_mode (0));
2899         PA_DFX (pa_clip_window (gauge_boxes[boxofs+win].left,gauge_boxes[boxofs+win].top,
2900                                                                         gauge_boxes[boxofs+win].right,gauge_boxes[boxofs+win].bot));
2901    
2902         for (x=gauge_boxes[boxofs+win].left;x<gauge_boxes[boxofs+win].right;x+=bmp->bm_w)
2903                 for (y=gauge_boxes[boxofs+win].top;y<gauge_boxes[boxofs+win].bot;y+=bmp->bm_h)
2904                         gr_bitmap(x,y,bmp);
2905
2906         PA_DFX (pa_bypass_mode(1));
2907         PA_DFX (pa_clip_window (0,0,640,480));
2908
2909         WIN(DDGRUNLOCK(dd_grd_curcanv));
2910
2911         WINDOS(
2912         dd_gr_set_current_canvas(get_current_game_screen()),
2913         gr_set_current_canvas(get_current_game_screen())
2914         );
2915
2916 //   PA_DFX (return);
2917   
2918         WINDOS(
2919         copy_gauge_box(&gauge_boxes[boxofs+win],&dd_VR_render_buffer[0]),
2920         copy_gauge_box(&gauge_boxes[boxofs+win],&VR_render_buffer[0].cv_bitmap)
2921         );
2922 }
2923
2924 void draw_weapon_boxes()
2925 {
2926         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2927         int drew;
2928
2929         if (weapon_box_user[0] == WBU_WEAPON) {
2930                 drew = draw_weapon_box(0,Primary_weapon);
2931                 if (drew) 
2932                         WINDOS(
2933                                 copy_gauge_box(&gauge_boxes[boxofs+0],&dd_VR_render_buffer[0]),
2934                                 copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap)
2935                         );
2936
2937                 if (weapon_box_states[0] == WS_SET) {
2938                         if ((Primary_weapon == VULCAN_INDEX) || (Primary_weapon == GAUSS_INDEX)) {
2939                                 if (Players[Player_num].primary_ammo[VULCAN_INDEX] != old_ammo_count[0][VR_current_page]) {
2940                                         if (Newdemo_state == ND_STATE_RECORDING)
2941                                                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[VULCAN_INDEX]);
2942                                         draw_primary_ammo_info(f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX]));
2943                                         old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[VULCAN_INDEX];
2944                                 }
2945                         }
2946
2947                         if (Primary_weapon == OMEGA_INDEX) {
2948                                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
2949                                         if (Newdemo_state == ND_STATE_RECORDING)
2950                                                 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
2951                                         draw_primary_ammo_info(Omega_charge * 100/MAX_OMEGA_CHARGE);
2952                                         Old_Omega_charge[VR_current_page] = Omega_charge;
2953                                 }
2954                         }
2955                 }
2956         }
2957         else if (weapon_box_user[0] == WBU_STATIC)
2958                 draw_static(0);
2959
2960         if (weapon_box_user[1] == WBU_WEAPON) {
2961                 drew = draw_weapon_box(1,Secondary_weapon);
2962                 if (drew)
2963                         WINDOS(
2964                                 copy_gauge_box(&gauge_boxes[boxofs+1],&dd_VR_render_buffer[0]),
2965                                 copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap)
2966                         );
2967
2968                 if (weapon_box_states[1] == WS_SET)
2969                         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
2970                                 old_bombcount[VR_current_page] = 0x7fff;        //force redraw
2971                                 if (Newdemo_state == ND_STATE_RECORDING)
2972                                         newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
2973                                 draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
2974                                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
2975                         }
2976         }
2977         else if (weapon_box_user[1] == WBU_STATIC)
2978                 draw_static(1);
2979 }
2980
2981
2982 void sb_draw_energy_bar(energy)
2983 {
2984         int erase_height, w, h, aw;
2985         char energy_str[20];
2986
2987         gr_set_current_canvas( Canv_SBEnergyGauge );
2988
2989         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2990         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_ENERGY) ] );
2991
2992         erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
2993
2994         if (erase_height > 0) {
2995                 gr_setcolor( BM_XRGB(0,0,0) );
2996                 gr_rect(0,0,SB_ENERGY_GAUGE_W-1,erase_height-1);
2997         }
2998
2999         WINDOS(
3000         dd_gr_set_current_canvas(get_current_game_screen()),
3001         gr_set_current_canvas(get_current_game_screen())
3002         );
3003
3004         WIN(DDGRLOCK(dd_grd_curcanv));
3005    PA_DFX (pa_set_frontbuffer_current());
3006    PA_DFX (gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap));
3007    PA_DFX (pa_set_backbuffer_current());
3008         gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap );
3009
3010         //draw numbers
3011         sprintf(energy_str, "%d", energy);
3012         gr_get_string_size(energy_str, &w, &h, &aw );
3013         gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
3014    PA_DFX (pa_set_frontbuffer_current());
3015         PA_DFX (gr_printf(SB_ENERGY_GAUGE_X + ((SB_ENERGY_GAUGE_W - w)/2), SB_ENERGY_GAUGE_Y + SB_ENERGY_GAUGE_H - GAME_FONT->ft_h - (GAME_FONT->ft_h / 4), "%d", energy));
3016    PA_DFX (pa_set_backbuffer_current());
3017         gr_printf(SB_ENERGY_GAUGE_X + ((SB_ENERGY_GAUGE_W - w)/2), SB_ENERGY_GAUGE_Y + SB_ENERGY_GAUGE_H - GAME_FONT->ft_h - (GAME_FONT->ft_h / 4), "%d", energy);
3018         WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3019 }
3020
3021 void sb_draw_afterburner()
3022 {
3023         int erase_height, w, h, aw;
3024         char ab_str[3] = "AB";
3025
3026         gr_set_current_canvas( Canv_SBAfterburnerGauge );
3027         PAGE_IN_GAUGE( SB_GAUGE_AFTERBURNER );
3028         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_AFTERBURNER) ] );
3029
3030         erase_height = fixmul((f1_0 - Afterburner_charge),SB_AFTERBURNER_GAUGE_H);
3031
3032         if (erase_height > 0) {
3033                 gr_setcolor( BM_XRGB(0,0,0) );
3034                 gr_rect(0,0,SB_AFTERBURNER_GAUGE_W-1,erase_height-1);
3035         }
3036
3037 WINDOS(
3038         dd_gr_set_current_canvas(get_current_game_screen()),
3039         gr_set_current_canvas(get_current_game_screen())
3040 );
3041 WIN(DDGRLOCK(dd_grd_curcanv));
3042    PA_DFX (pa_set_frontbuffer_current());
3043         gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap );
3044    PA_DFX (pa_set_backbuffer_current());
3045         PA_DFX (gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap ));
3046
3047         //draw legend
3048         if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
3049                 gr_set_fontcolor(gr_getcolor(45,0,0),-1 );
3050         else 
3051                 gr_set_fontcolor(gr_getcolor(12,12,12),-1 );
3052
3053         gr_get_string_size(ab_str, &w, &h, &aw );
3054    PA_DFX (pa_set_frontbuffer_current());
3055         PA_DFX (gr_printf(SB_AFTERBURNER_GAUGE_X + ((SB_AFTERBURNER_GAUGE_W - w)/2),SB_AFTERBURNER_GAUGE_Y+SB_AFTERBURNER_GAUGE_H-GAME_FONT->ft_h - (GAME_FONT->ft_h / 4),"AB"));
3056    PA_DFX (pa_set_backbuffer_current());
3057         gr_printf(SB_AFTERBURNER_GAUGE_X + ((SB_AFTERBURNER_GAUGE_W - w)/2),SB_AFTERBURNER_GAUGE_Y+SB_AFTERBURNER_GAUGE_H-GAME_FONT->ft_h - (GAME_FONT->ft_h / 4),"AB");
3058
3059 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3060 }
3061
3062 void sb_draw_shield_num(int shield)
3063 {
3064         //draw numbers
3065
3066         gr_set_curfont( GAME_FONT );
3067         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
3068
3069         //erase old one
3070         PIGGY_PAGE_IN( cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)] );
3071
3072 WIN(DDGRLOCK(dd_grd_curcanv));
3073    PA_DFX (pa_set_back_to_read());
3074         gr_setcolor(gr_gpixel(&grd_curcanv->cv_bitmap,SB_SHIELD_NUM_X-1,SB_SHIELD_NUM_Y-1));
3075    PA_DFX (pa_set_front_to_read());
3076
3077         PA_DFX (pa_set_frontbuffer_current());
3078
3079         gr_rect(SB_SHIELD_NUM_X,SB_SHIELD_NUM_Y,SB_SHIELD_NUM_X+(Current_display_mode?27:13),SB_SHIELD_NUM_Y+GAME_FONT->ft_h);
3080         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);
3081
3082         PA_DFX (pa_set_backbuffer_current());
3083         PA_DFX (gr_rect(SB_SHIELD_NUM_X,SB_SHIELD_NUM_Y,SB_SHIELD_NUM_X+(Current_display_mode?27:13),SB_SHIELD_NUM_Y+GAME_FONT->ft_h));
3084         PA_DFX (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));
3085
3086 WIN(DDGRUNLOCK(dd_grd_curcanv));
3087 }
3088
3089 void sb_draw_shield_bar(int shield)
3090 {
3091         int bm_num = shield>=100?9:(shield / 10);
3092
3093 WINDOS(
3094         dd_gr_set_current_canvas(get_current_game_screen()),
3095         gr_set_current_canvas(get_current_game_screen())
3096 );
3097 WIN(DDGRLOCK(dd_grd_curcanv));
3098         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num );
3099    PA_DFX (pa_set_frontbuffer_current());               
3100         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
3101    PA_DFX (pa_set_backbuffer_current());                
3102         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
3103         
3104 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3105 }
3106
3107 void sb_draw_keys()
3108 {
3109         grs_bitmap * bm;
3110         int flags = Players[Player_num].flags;
3111
3112 WINDOS(
3113         dd_gr_set_current_canvas(get_current_game_screen()),
3114         gr_set_current_canvas(get_current_game_screen())
3115 );
3116 WIN(DDGRLOCK(dd_grd_curcanv));
3117    PA_DFX (pa_set_frontbuffer_current());
3118         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
3119         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
3120         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
3121         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
3122         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
3123         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
3124         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
3125         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
3126         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
3127         #ifdef PA_3DFX_VOODOO
3128            PA_DFX (pa_set_backbuffer_current());
3129                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
3130                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
3131                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
3132                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
3133                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
3134                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
3135                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
3136                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
3137                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
3138         #endif
3139
3140 WIN(DDGRUNLOCK(dd_grd_curcanv));
3141 }
3142
3143 //      Draws invulnerable ship, or maybe the flashing ship, depending on invulnerability time left.
3144 void draw_invulnerable_ship()
3145 {
3146         static fix time=0;
3147
3148 WINDOS(
3149         dd_gr_set_current_canvas(get_current_game_screen()),
3150         gr_set_current_canvas(get_current_game_screen())
3151 );
3152 WIN(DDGRLOCK(dd_grd_curcanv));
3153
3154         if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000)) {
3155
3156                 if (Cockpit_mode == CM_STATUS_BAR)      {
3157                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
3158                         PA_DFX (pa_set_frontbuffer_current());
3159                         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] );
3160                         PA_DFX (pa_set_backbuffer_current());
3161                         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] ));
3162                 } else {
3163                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
3164                         PA_DFX (pa_set_frontbuffer_current());
3165                         PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] ));
3166                         PA_DFX (pa_set_backbuffer_current());
3167                         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] );
3168                 }
3169
3170                 time += FrameTime;
3171
3172                 while (time > INV_FRAME_TIME) {
3173                         time -= INV_FRAME_TIME;
3174                         if (++invulnerable_frame == N_INVULNERABLE_FRAMES)
3175                                 invulnerable_frame=0;
3176                 }
3177         } else if (Cockpit_mode == CM_STATUS_BAR)
3178                 sb_draw_shield_bar(f2ir(Players[Player_num].shields));
3179         else
3180                 draw_shield_bar(f2ir(Players[Player_num].shields));
3181 WIN(DDGRUNLOCK(dd_grd_curcanv));
3182 }
3183
3184 extern int Missile_gun;
3185 extern int allowed_to_fire_laser(void);
3186 extern int allowed_to_fire_missile(void);
3187
3188 rgb player_rgb[] = {
3189                                                         {15,15,23},
3190                                                         {27,0,0},
3191                                                         {0,23,0},
3192                                                         {30,11,31},
3193                                                         {31,16,0},
3194                                                         {24,17,6},
3195                                                         {14,21,12},
3196                                                         {29,29,0},
3197                                                 };
3198
3199 extern ubyte Newdemo_flying_guided;
3200 extern int max_window_w;
3201
3202 typedef struct {
3203         sbyte x, y;
3204 } xy;
3205
3206 //offsets for reticle parts: high-big  high-sml  low-big  low-sml
3207 xy cross_offsets[4] =           { {-8,-5},      {-4,-2},        {-4,-2}, {-2,-1} };
3208 xy primary_offsets[4] =         { {-30,14}, {-16,6},    {-15,6}, {-8, 2} };
3209 xy secondary_offsets[4] =       { {-24,2},      {-12,0}, {-12,1}, {-6,-2} };
3210
3211 //draw the reticle
3212 void show_reticle(int force_big_one)
3213 {
3214         int x,y;
3215         int laser_ready,missile_ready,laser_ammo,missile_ammo;
3216         int cross_bm_num,primary_bm_num,secondary_bm_num;
3217         int use_hires_reticle,small_reticle,ofs,gauge_index;
3218
3219    if (Newdemo_state==ND_STATE_PLAYBACK && Newdemo_flying_guided)
3220                 {
3221                 WIN(DDGRLOCK(dd_grd_curcanv));
3222                  draw_guided_crosshair();
3223                 WIN(DDGRUNLOCK(dd_grd_curcanv));
3224                  return;
3225            }
3226
3227         x = grd_curcanv->cv_w/2;
3228         y = grd_curcanv->cv_h/2;
3229
3230         laser_ready = allowed_to_fire_laser();
3231         missile_ready = allowed_to_fire_missile();
3232
3233         laser_ammo = player_has_weapon(Primary_weapon,0);
3234         missile_ammo = player_has_weapon(Secondary_weapon,1);
3235
3236         primary_bm_num = (laser_ready && laser_ammo==HAS_ALL);
3237         secondary_bm_num = (missile_ready && missile_ammo==HAS_ALL);
3238
3239         if (primary_bm_num && Primary_weapon==LASER_INDEX && (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS))
3240                 primary_bm_num++;
3241
3242         if (Secondary_weapon_to_gun_num[Secondary_weapon]==7)
3243                 secondary_bm_num += 3;          //now value is 0,1 or 3,4
3244         else if (secondary_bm_num && !(Missile_gun&1))
3245                         secondary_bm_num++;
3246
3247         cross_bm_num = ((primary_bm_num > 0) || (secondary_bm_num > 0));
3248
3249         Assert(primary_bm_num <= 2);
3250         Assert(secondary_bm_num <= 4);
3251         Assert(cross_bm_num <= 1);
3252 #ifdef OGL
3253       if (gl_reticle==2 || (gl_reticle && grd_curcanv->cv_bitmap.bm_w > 320)){                ogl_draw_reticle(cross_bm_num,primary_bm_num,secondary_bm_num);
3254        } else {
3255 #endif
3256
3257
3258         #ifndef MACINTOSH
3259                 use_hires_reticle = (FontHires != 0);
3260         #else
3261                 use_hires_reticle = !Scanline_double;
3262         #endif
3263
3264         WIN(DDGRLOCK(dd_grd_curcanv));
3265
3266 #ifndef MACINTOSH
3267         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*2 || force_big_one);
3268 #else
3269         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*(Scanline_double?1:2) || force_big_one);
3270 #endif
3271         ofs = (use_hires_reticle?0:2) + small_reticle;
3272
3273         gauge_index = (small_reticle?SML_RETICLE_CROSS:RETICLE_CROSS) + cross_bm_num;
3274         PAGE_IN_GAUGE( gauge_index );
3275         gr_ubitmapm(x+cross_offsets[ofs].x,y+cross_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3276
3277         gauge_index = (small_reticle?SML_RETICLE_PRIMARY:RETICLE_PRIMARY) + primary_bm_num;
3278         PAGE_IN_GAUGE( gauge_index );
3279         gr_ubitmapm(x+primary_offsets[ofs].x,y+primary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3280
3281         gauge_index = (small_reticle?SML_RETICLE_SECONDARY:RETICLE_SECONDARY) + secondary_bm_num;
3282         PAGE_IN_GAUGE( gauge_index );
3283         gr_ubitmapm(x+secondary_offsets[ofs].x,y+secondary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3284
3285         WIN(DDGRUNLOCK(dd_grd_curcanv));
3286 #ifdef OGL
3287        }
3288 #endif
3289 }
3290
3291 #ifdef NETWORK
3292 void hud_show_kill_list()
3293 {
3294         int n_players,player_list[MAX_NUM_NET_PLAYERS];
3295         int n_left,i,x0,x1,y,save_y,fth;
3296
3297 // ugly hack since placement of netgame players and kills is based off of
3298 // menuhires (which is always 1 for mac).  This throws off placement of
3299 // players in pixel double mode.
3300
3301 #ifdef MACINTOSH
3302         MenuHires = !(Scanline_double);
3303 #endif
3304
3305         if (Show_kill_list_timer > 0)
3306         {
3307                 Show_kill_list_timer -= FrameTime;
3308                 if (Show_kill_list_timer < 0)
3309                         Show_kill_list = 0;
3310         }
3311         
3312         gr_set_curfont( GAME_FONT );
3313
3314         n_players = multi_get_kill_list(player_list);
3315
3316         if (Show_kill_list == 3)
3317                 n_players = 2;
3318
3319         if (n_players <= 4)
3320                 n_left = n_players;
3321         else
3322                 n_left = (n_players+1)/2;
3323
3324         //If font size changes, this code might not work right anymore 
3325         //Assert(GAME_FONT->ft_h==5 && GAME_FONT->ft_w==7);
3326
3327         fth = GAME_FONT->ft_h;
3328
3329         x0 = LHX(1); x1 = LHX(43);
3330
3331         if (Game_mode & GM_MULTI_COOP)
3332                 x1 = LHX(31);
3333
3334         save_y = y = grd_curcanv->cv_h - n_left*(fth+1);
3335
3336         if (Cockpit_mode == CM_FULL_COCKPIT) {
3337                 save_y = y -= LHX(6);
3338                 if (Game_mode & GM_MULTI_COOP)
3339                         x1 = LHX(33);
3340                 else
3341                         x1 = LHX(43);
3342         }
3343
3344         for (i=0;i<n_players;i++) {
3345                 int player_num;
3346                 char name[9];
3347                 int sw,sh,aw;
3348
3349                 if (i>=n_left) {
3350                         if (Cockpit_mode == CM_FULL_COCKPIT)
3351                                 x0 = grd_curcanv->cv_w - LHX(53);
3352                         else
3353                                 x0 = grd_curcanv->cv_w - LHX(60);
3354                         if (Game_mode & GM_MULTI_COOP)
3355                                 x1 = grd_curcanv->cv_w - LHX(27);
3356                         else
3357                                 x1 = grd_curcanv->cv_w - LHX(15);  // Right edge of name, change this for width problems
3358                         if (i==n_left)
3359                                 y = save_y;
3360
3361         if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3362            {
3363              x1-=LHX(18);
3364             // x0-=LHX(18);
3365            }
3366                 }
3367      else  if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3368            {
3369                                  x1 = LHX(43);
3370              x1-=LHX(18);
3371             // x0-=LHX(18);
3372            }
3373
3374         
3375                 if (Show_kill_list == 3)
3376                         player_num = i;
3377                 else
3378                         player_num = player_list[i];
3379
3380                 if (Show_kill_list == 1 || Show_kill_list==2)
3381                 {
3382                         int color;
3383
3384                         if (Players[player_num].connected != 1)
3385                                 gr_set_fontcolor(gr_getcolor(12, 12, 12), -1);
3386                         else if (Game_mode & GM_TEAM) {
3387                                 color = get_team(player_num);
3388                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3389                         }
3390                         else {
3391                                 color = player_num;
3392                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3393                         }
3394                 }       
3395
3396                 else 
3397                 {
3398                         gr_set_fontcolor(gr_getcolor(player_rgb[player_num].r,player_rgb[player_num].g,player_rgb[player_num].b),-1 );
3399                 }
3400
3401                 if (Show_kill_list == 3)
3402                         strcpy(name, Netgame.team_name[i]);
3403                 else
3404                         strcpy(name,Players[player_num].callsign);      // Note link to above if!!
3405                 gr_get_string_size(name,&sw,&sh,&aw);
3406                 while (sw > (x1-x0-LHX(2))) {
3407                         name[strlen(name)-1]=0;
3408                         gr_get_string_size(name,&sw,&sh,&aw);
3409                 }
3410                 gr_printf(x0,y,"%s",name);
3411
3412                 if (Show_kill_list==2)
3413                  {
3414                   if (Players[player_num].net_killed_total+Players[player_num].net_kills_total==0)
3415                         gr_printf (x1,y,"NA");
3416                   else
3417                    gr_printf (x1,y,"%d%%",(int)((float)((float)Players[player_num].net_kills_total/((float)Players[player_num].net_killed_total+(float)Players[player_num].net_kills_total))*100.0));           
3418                  }
3419                 else if (Show_kill_list == 3)   
3420                         gr_printf(x1,y,"%3d",team_kills[i]);
3421                 else if (Game_mode & GM_MULTI_COOP)
3422                         gr_printf(x1,y,"%-6d",Players[player_num].score);
3423       else if (Netgame.PlayTimeAllowed || Netgame.KillGoal)
3424          gr_printf(x1,y,"%3d(%d)",Players[player_num].net_kills_total,Players[player_num].KillGoalCount);
3425       else
3426                         gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
3427                         
3428                 y += fth+1;
3429
3430         }
3431
3432 #ifdef MACINTOSH
3433         MenuHires = 1;
3434 #endif
3435 }
3436 #endif
3437
3438 #ifndef RELEASE
3439 extern int Saving_movie_frames;
3440 #else
3441 #define Saving_movie_frames 0
3442 #endif
3443
3444 //returns true if viewer can see object
3445 int see_object(int objnum)
3446 {
3447         fvi_query fq;
3448         int hit_type;
3449         fvi_info hit_data;
3450
3451         //see if we can see this player
3452
3453         fq.p0                                   = &Viewer->pos;
3454         fq.p1                                   = &Objects[objnum].pos;
3455         fq.rad                                  = 0;
3456         fq.thisobjnum                   = Viewer - Objects;
3457         fq.flags                                = FQ_TRANSWALL | FQ_CHECK_OBJS;
3458         fq.startseg                             = Viewer->segnum;
3459         fq.ignore_obj_list      = NULL;
3460
3461         hit_type = find_vector_intersection(&fq, &hit_data);
3462
3463         return (hit_type == HIT_OBJECT && hit_data.hit_object == objnum);
3464 }
3465
3466 #ifdef NETWORK
3467 //show names of teammates & players carrying flags
3468 void show_HUD_names()
3469 {
3470         int show_team_names,show_all_names,show_flags,player_team;
3471         int p;
3472
3473         show_all_names = ((Newdemo_state == ND_STATE_PLAYBACK) || (Netgame.ShowAllNames && Show_reticle_name));
3474         show_team_names = (((Game_mode & GM_MULTI_COOP) || (Game_mode & GM_TEAM)) && Show_reticle_name);
3475         show_flags = (Game_mode & GM_CAPTURE) | (Game_mode & GM_HOARD);
3476
3477         if (! (show_all_names || show_team_names || show_flags))
3478                 return;
3479
3480         player_team = get_team(Player_num);
3481
3482         for (p=0;p<N_players;p++) {     //check all players
3483                 int objnum;
3484                 int show_name,has_flag;
3485
3486                 show_name = ((show_all_names && !(Players[p].flags & PLAYER_FLAGS_CLOAKED)) || (show_team_names && get_team(p)==player_team));
3487                 has_flag = (Players[p].connected && Players[p].flags & PLAYER_FLAGS_FLAG);
3488
3489                 if (Newdemo_state == ND_STATE_PLAYBACK) {
3490                         //if this is a demo, the objnum in the player struct is wrong,
3491                         //so we search the object list for the objnum
3492
3493                         for (objnum=0;objnum<=Highest_object_index;objnum++)
3494                                 if (Objects[objnum].type==OBJ_PLAYER && Objects[objnum].id == p)
3495                                         break;
3496                         if (objnum > Highest_object_index)              //not in list, thus not visible
3497                                 show_name = has_flag = 0;                               //..so don't show name
3498                 }
3499                 else
3500                         objnum = Players[p].objnum;
3501
3502                 if ((show_name || has_flag) && see_object(objnum)) {
3503                         g3s_point player_point;
3504
3505                         g3_rotate_point(&player_point,&Objects[objnum].pos);
3506
3507                         if (player_point.p3_codes == 0) {       //on screen
3508
3509                                 g3_project_point(&player_point);
3510
3511                                 if (! (player_point.p3_flags & PF_OVERFLOW)) {
3512                                         fix x,y;
3513                         
3514                                         x = player_point.p3_sx;
3515                                         y = player_point.p3_sy;
3516                         
3517                                         if (show_name) {                                // Draw callsign on HUD
3518                                                 char s[CALLSIGN_LEN+1];
3519                                                 int w, h, aw;
3520                                                 int x1, y1;
3521                                                 int color_num;
3522                         
3523                                                 color_num = (Game_mode & GM_TEAM)?get_team(p):p;
3524
3525                                                 sprintf(s, "%s", Players[p].callsign);
3526                                                 gr_get_string_size(s, &w, &h, &aw);
3527                                                 gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
3528                                                 x1 = f2i(x)-w/2;
3529                                                 y1 = f2i(y)-h/2;
3530                                                 gr_string (x1, y1, s);
3531                                         }
3532                 
3533                                         if (has_flag) {                         // Draw box on HUD
3534                                                 fix dx,dy,w,h;
3535                         
3536                                                 dy = -fixmuldiv(fixmul(Objects[objnum].size,Matrix_scale.y),i2f(grd_curcanv->cv_h)/2,player_point.p3_z);
3537                                                 dx = fixmul(dy,grd_curscreen->sc_aspect);
3538         
3539                                                 w = dx/4;
3540                                                 h = dy/4;
3541         
3542                                                 if (Game_mode & GM_CAPTURE)
3543                                                         gr_setcolor((get_team(p) == TEAM_BLUE)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3544                                                 else if (Game_mode & GM_HOARD)
3545                                                 {
3546                                                         if (Game_mode & GM_TEAM)
3547                                                                 gr_setcolor((get_team(p) == TEAM_RED)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3548                                                         else
3549                                                                 gr_setcolor(BM_XRGB(0,31,0));
3550                                                 }
3551
3552                                                 gr_line(x+dx-w,y-dy,x+dx,y-dy);
3553                                                 gr_line(x+dx,y-dy,x+dx,y-dy+h);
3554         
3555                                                 gr_line(x-dx,y-dy,x-dx+w,y-dy);
3556                                                 gr_line(x-dx,y-dy,x-dx,y-dy+h);
3557         
3558                                                 gr_line(x+dx-w,y+dy,x+dx,y+dy);
3559                                                 gr_line(x+dx,y+dy,x+dx,y+dy-h);
3560         
3561                                                 gr_line(x-dx,y+dy,x-dx+w,y+dy);
3562                                                 gr_line(x-dx,y+dy,x-dx,y+dy-h);
3563                                         }
3564                                 }
3565                         }
3566                 }
3567         }
3568 }
3569 #endif
3570
3571
3572 extern int last_drawn_cockpit[2];
3573
3574 //draw all the things on the HUD
3575 void draw_hud()
3576 {
3577
3578 #ifdef OGL
3579         if (Cockpit_mode==CM_STATUS_BAR){
3580                 //ogl needs to redraw every frame, at least currently.
3581                 //              init_cockpit();
3582                         last_drawn_cockpit[0]=-1;
3583                         last_drawn_cockpit[1]=-1;
3584                                   init_gauges();
3585                 
3586                                //              vr_reset_display();
3587         }
3588 #endif
3589                                           
3590
3591 #ifdef MACINTOSH
3592         if (Scanline_double)            // I should be shot for this ugly hack....
3593                 FontHires = 1;
3594 #endif
3595         Line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
3596 #ifdef MACINTOSH
3597         if (Scanline_double)
3598                 FontHires = 0;
3599 #endif
3600
3601 WIN(DDGRLOCK(dd_grd_curcanv));
3602         //      Show score so long as not in rearview
3603         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames) {
3604                 hud_show_score();
3605                 if (score_time)
3606                         hud_show_score_added();
3607         }
3608
3609         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && !Saving_movie_frames) 
3610          hud_show_timer_count();
3611
3612         //      Show other stuff if not in rearview or letterbox.
3613         if (!Rear_view && Cockpit_mode!=CM_REAR_VIEW) { // && Cockpit_mode!=CM_LETTERBOX) {
3614                 if (Cockpit_mode==CM_STATUS_BAR || Cockpit_mode==CM_FULL_SCREEN)
3615                         hud_show_homing_warning();
3616
3617                 if (Cockpit_mode==CM_FULL_SCREEN) {
3618                         hud_show_energy();
3619                         hud_show_shield();
3620                         hud_show_afterburner();
3621                         hud_show_weapons();
3622                         if (!Saving_movie_frames)
3623                                 hud_show_keys();
3624                         hud_show_cloak_invuln();
3625
3626                         if ( ( Newdemo_state==ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags[VR_current_page] )) {
3627                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3628                                 old_flags[VR_current_page] = Players[Player_num].flags;
3629                         }
3630                 }
3631
3632                 #ifdef NETWORK
3633                 #ifndef RELEASE
3634                 if (!(Game_mode&GM_MULTI && Show_kill_list) && !Saving_movie_frames)
3635                         show_time();
3636                 #endif
3637                 #endif
3638                 if (Reticle_on && Cockpit_mode != CM_LETTERBOX && (!Use_player_head_angles))
3639                         show_reticle(0);
3640
3641 #ifdef NETWORK
3642                 show_HUD_names();
3643
3644                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3645                         hud_show_flag();
3646
3647                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3648                         hud_show_orbs();
3649
3650 #endif
3651                 if (!Saving_movie_frames)
3652                         HUD_render_message_frame();
3653
3654                 if (Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames)
3655                         hud_show_lives();
3656
3657                 #ifdef NETWORK
3658                 if (Game_mode&GM_MULTI && Show_kill_list)
3659                         hud_show_kill_list();
3660                 #endif
3661         }
3662
3663         if (Rear_view && Cockpit_mode!=CM_REAR_VIEW) {
3664                 HUD_render_message_frame();
3665                 gr_set_curfont( GAME_FONT );
3666                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
3667                 if (Newdemo_state == ND_STATE_PLAYBACK)
3668                         gr_printf(0x8000,grd_curcanv->cv_h-14,TXT_REAR_VIEW);
3669                 else
3670                         gr_printf(0x8000,grd_curcanv->cv_h-10,TXT_REAR_VIEW);
3671         }
3672 WIN(DDGRUNLOCK(dd_grd_curcanv));
3673 }
3674
3675 extern short *BackBuffer;
3676
3677 //print out some player statistics
3678 void render_gauges()
3679 {
3680 #ifndef MACINTOSH
3681         static int old_display_mode = 0;
3682 #else
3683         static int old_display_mode = 1;
3684 #endif
3685         int energy = f2ir(Players[Player_num].energy);
3686         int shields = f2ir(Players[Player_num].shields);
3687         int cloak = ((Players[Player_num].flags&PLAYER_FLAGS_CLOAKED) != 0);
3688         int frc=0;
3689  
3690    PA_DFX (frc=0);
3691    PA_DFX (pa_set_backbuffer_current());
3692
3693         Assert(Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR);
3694
3695 // check to see if our display mode has changed since last render time --
3696 // if so, then we need to make new gauge canvases.
3697
3698   
3699         if (old_display_mode != Current_display_mode) {
3700                 close_gauge_canvases();
3701                 init_gauge_canvases();
3702                 old_display_mode = Current_display_mode;
3703         }
3704
3705         if (shields < 0 ) shields = 0;
3706
3707         WINDOS(
3708                 dd_gr_set_current_canvas(get_current_game_screen()),
3709                 gr_set_current_canvas(get_current_game_screen())
3710         );
3711         gr_set_curfont( GAME_FONT );
3712
3713         if (Newdemo_state == ND_STATE_RECORDING)
3714                 if (Players[Player_num].homing_object_dist >= 0)
3715                         newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
3716
3717         if (Cockpit_mode == CM_FULL_COCKPIT) {
3718                 if (energy != old_energy[VR_current_page]) {
3719                         if (Newdemo_state==ND_STATE_RECORDING ) {
3720                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3721                         }
3722                         draw_energy_bar(energy);
3723                         draw_numerical_display(shields, energy);
3724                         old_energy[VR_current_page] = energy;
3725                 }
3726
3727                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
3728                         if (Newdemo_state==ND_STATE_RECORDING ) {
3729                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3730                         }
3731                         draw_afterburner_bar(Afterburner_charge);
3732                         old_afterburner[VR_current_page] = Afterburner_charge;
3733                 }
3734
3735                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3736                         draw_numerical_display(shields, energy);
3737                         draw_invulnerable_ship();
3738                         old_shields[VR_current_page] = shields ^ 1;
3739                 } else if (shields != old_shields[VR_current_page]) {           // Draw the shield gauge
3740                         if (Newdemo_state==ND_STATE_RECORDING ) {
3741                                 newdemo_record_player_shields(old_shields[VR_current_page], shields);
3742                         }
3743                         draw_shield_bar(shields);
3744                         draw_numerical_display(shields, energy);
3745                         old_shields[VR_current_page] = shields;
3746                 }
3747         
3748                 if (Players[Player_num].flags != old_flags[VR_current_page]) {
3749                         if (Newdemo_state==ND_STATE_RECORDING )
3750                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3751                         draw_keys();
3752                         old_flags[VR_current_page] = Players[Player_num].flags;
3753                 }
3754
3755                 show_homing_warning();
3756
3757                 show_bomb_count(BOMB_COUNT_X,BOMB_COUNT_Y,gr_find_closest_color(0,0,0),0);
3758         
3759         } else if (Cockpit_mode == CM_STATUS_BAR) {
3760
3761                 if (energy != old_energy[VR_current_page] || frc)  {
3762                         if (Newdemo_state==ND_STATE_RECORDING ) {
3763                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3764                         }
3765                         sb_draw_energy_bar(energy);
3766                         old_energy[VR_current_page] = energy;
3767                 }
3768
3769                 if (Afterburner_charge != old_afterburner[VR_current_page] || frc) {
3770                         if (Newdemo_state==ND_STATE_RECORDING ) {
3771                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3772                         }
3773                         sb_draw_afterburner();
3774                         old_afterburner[VR_current_page] = Afterburner_charge;
3775                 }
3776         
3777                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3778                         draw_invulnerable_ship();
3779                         old_shields[VR_current_page] = shields ^ 1;
3780                         sb_draw_shield_num(shields);
3781                 } 
3782                 else 
3783                         if (shields != old_shields[VR_current_page] || frc) {           // Draw the shield gauge
3784                                 if (Newdemo_state==ND_STATE_RECORDING ) {
3785                                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
3786                                 }
3787                                 sb_draw_shield_bar(shields);
3788                                 old_shields[VR_current_page] = shields;
3789                                 sb_draw_shield_num(shields);
3790                         }
3791
3792                 if (Players[Player_num].flags != old_flags[VR_current_page] || frc) {
3793                         if (Newdemo_state==ND_STATE_RECORDING )
3794                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3795                         sb_draw_keys();
3796                         old_flags[VR_current_page] = Players[Player_num].flags;
3797                 }
3798         
3799
3800                 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3801                 {
3802                         if (Players[Player_num].net_killed_total != old_lives[VR_current_page] || frc) {
3803                                 sb_show_lives();
3804                                 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
3805                         }
3806                 }
3807                 else
3808                 {
3809                         if (Players[Player_num].lives != old_lives[VR_current_page] || frc) {
3810                                 sb_show_lives();
3811                                 old_lives[VR_current_page] = Players[Player_num].lives;
3812                         }
3813                 }
3814
3815                 if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) {
3816                         if (Players[Player_num].net_kills_total != old_score[VR_current_page] || frc) {
3817                                 sb_show_score();
3818                                 old_score[VR_current_page] = Players[Player_num].net_kills_total;
3819                         }
3820                 }
3821                 else {
3822                         if (Players[Player_num].score != old_score[VR_current_page] || frc) {
3823                                 sb_show_score();
3824                                 old_score[VR_current_page] = Players[Player_num].score;
3825                         }
3826
3827                         //if (score_time)
3828                                 sb_show_score_added();
3829                 }
3830
3831                 show_bomb_count(SB_BOMB_COUNT_X,SB_BOMB_COUNT_Y,gr_find_closest_color(5,5,5),0);
3832         }
3833
3834         if (frc || cloak != old_cloak[VR_current_page] || cloak_fade_state || (cloak && GameTime>Players[Player_num].cloak_time+CLOAK_TIME_MAX-i2f(3))) {
3835                 if (Cockpit_mode == CM_FULL_COCKPIT)
3836                         draw_player_ship(cloak,old_cloak[VR_current_page],SHIP_GAUGE_X,SHIP_GAUGE_Y);
3837                 else
3838                         draw_player_ship(cloak,old_cloak[VR_current_page],SB_SHIP_GAUGE_X,SB_SHIP_GAUGE_Y);
3839
3840                 old_cloak[VR_current_page]=cloak;
3841         }
3842
3843
3844         draw_weapon_boxes();
3845
3846 }
3847
3848 //      ---------------------------------------------------------------------------------------------------------
3849 //      Call when picked up a laser powerup.
3850 //      If laser is active, set old_weapon[0] to -1 to force redraw.
3851 void update_laser_weapon_info(void)
3852 {
3853         if (old_weapon[0][VR_current_page] == 0)
3854                 if (! (Players[Player_num].laser_level > MAX_LASER_LEVEL && old_laser_level[VR_current_page] <= MAX_LASER_LEVEL))
3855                         old_weapon[0][VR_current_page] = -1;
3856 }
3857
3858 extern int Game_window_y;
3859 void fill_background(void);
3860
3861 int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
3862
3863 //draws a 3d view into one of the cockpit windows.  win is 0 for left,
3864 //1 for right.  viewer is object.  NULL object means give up window
3865 //user is one of the WBU_ constants.  If rear_view_flag is set, show a
3866 //rear view.  If label is non-NULL, print the label at the top of the
3867 //window.
3868 void do_cockpit_window_view(int win,object *viewer,int rear_view_flag,int user,char *label)
3869 {
3870         WINDOS(
3871                 dd_grs_canvas window_canv,
3872                 grs_canvas window_canv
3873         );
3874         WINDOS(
3875                 static dd_grs_canvas overlap_canv,
3876                 static grs_canvas overlap_canv
3877         );
3878
3879 #ifdef WINDOWS
3880         int saved_window_x, saved_window_y;
3881 #endif
3882
3883         object *viewer_save = Viewer;
3884         static int overlap_dirty[2]={0,0};
3885         int boxnum;
3886         static int window_x,window_y;
3887         gauge_box *box;
3888         int rear_view_save = Rear_view;
3889         int w,h,dx;
3890
3891         box = NULL;
3892
3893         if (viewer == NULL) {                                                           //this user is done
3894
3895                 Assert(user == WBU_WEAPON || user == WBU_STATIC);
3896
3897                 if (user == WBU_STATIC && weapon_box_user[win] != WBU_STATIC)
3898                         static_time[win] = 0;
3899
3900                 if (weapon_box_user[win] == WBU_WEAPON || weapon_box_user[win] == WBU_STATIC)
3901                         return;         //already set
3902
3903                 weapon_box_user[win] = user;
3904
3905                 if (overlap_dirty[win]) {
3906                 WINDOS(
3907                         dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
3908                         gr_set_current_canvas(&VR_screen_pages[VR_current_page])
3909                 );
3910                         fill_background();
3911                         overlap_dirty[win] = 0;
3912                 }
3913
3914                 return;
3915         }
3916
3917         update_rendered_data(win+1, viewer, rear_view_flag, user);
3918
3919         weapon_box_user[win] = user;                                            //say who's using window
3920                 
3921         Viewer = viewer;
3922         Rear_view = rear_view_flag;
3923
3924         if (Cockpit_mode == CM_FULL_SCREEN)
3925         {
3926
3927                 w = VR_render_buffer[0].cv_bitmap.bm_w/6;                       // hmm.  I could probably do the sub_buffer assigment for all macines, but I aint gonna chance it
3928                 #ifdef MACINTOSH
3929                 if (Scanline_double)
3930                         w /= 2;
3931                 #endif
3932
3933                 h = i2f(w) / grd_curscreen->sc_aspect;
3934
3935                 dx = (win==0)?-(w+(w/10)):(w/10);
3936
3937                 window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3938                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3939
3940         #ifdef WINDOWS
3941                 saved_window_x = window_x;
3942                 saved_window_y = window_y;
3943                 window_x = dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w/2+dx;
3944                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10)-dd_VR_render_sub_buffer[0].yoff;
3945         #endif
3946
3947                 #ifdef MACINTOSH
3948                 if (Scanline_double) {
3949                         window_x = (VR_render_buffer[0].cv_bitmap.bm_w/2+VR_render_sub_buffer[0].cv_bitmap.bm_x)/2+dx;
3950                         window_y = ((VR_render_buffer[0].cv_bitmap.bm_h+VR_render_sub_buffer[0].cv_bitmap.bm_y)/2)-h-(h/10);
3951                 }
3952                 #endif
3953
3954                 //copy these vars so stereo code can get at them
3955                 SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3956
3957         WINDOS(
3958                 dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,w,h),
3959                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],window_x,window_y,w,h)
3960         );
3961         }
3962         else {
3963                 if (Cockpit_mode == CM_FULL_COCKPIT)
3964                         boxnum = (COCKPIT_PRIMARY_BOX)+win;
3965                 else if (Cockpit_mode == CM_STATUS_BAR)
3966                         boxnum = (SB_PRIMARY_BOX)+win;
3967                 else
3968                         goto abort;
3969
3970                 box = &gauge_boxes[boxnum];
3971
3972                 #ifndef MACINTOSH
3973         WINDOS(                                                           
3974                 dd_gr_init_sub_canvas(&window_canv,&dd_VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1),
3975                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1)
3976         );
3977                 #else
3978                 if (Scanline_double)
3979                         gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,(box->right-box->left+1)/2,(box->bot-box->top+1)/2);
3980                 else
3981                         gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1);
3982                 #endif
3983         }
3984
3985 WINDOS(
3986         dd_gr_set_current_canvas(&window_canv),
3987         gr_set_current_canvas(&window_canv)
3988 );
3989         
3990         #if defined(MACINTOSH) && defined(POLY_ACC)
3991         if ( PAEnabled )
3992         {
3993                 switch (Cockpit_mode)
3994                 {
3995                 // copy these vars so stereo code can get at them
3996                 // SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3997                         case CM_FULL_SCREEN:
3998                                 ;       // do not switch contexts
3999                                 pa_set_3d_window_offsets(window_x, window_y);
4000                                 break;
4001                         case CM_FULL_COCKPIT:
4002                         case CM_STATUS_BAR:
4003                                 if (win == 0)
4004                                 {
4005                                         pa_set_context(kSubViewZeroDrawContextID, NULL);
4006                                 }
4007                                 else
4008                                 {
4009                                         pa_set_context(kSubViewOneDrawContextID, NULL);
4010                                 }
4011                                 break;
4012                         default:
4013                                 Int3(); // invalid cockpit mode
4014                 };
4015         }
4016         #endif
4017
4018         WIN(DDGRLOCK(dd_grd_curcanv));
4019         
4020                 #ifdef MACINTOSH
4021                         #ifdef POLY_ACC
4022                                 if (PAEnabled)
4023                                 {
4024                                         if (Cockpit_mode != CM_FULL_SCREEN)
4025                                         {
4026                                                 pa_render_start();
4027                                         }
4028                                 }
4029                         #endif
4030                 #endif 
4031                 
4032                 render_frame(0, win+1);
4033                 
4034                 #ifdef MACINTOSH
4035                         #ifdef POLY_ACC
4036                                 if (PAEnabled)
4037                                 {
4038                                         if (Cockpit_mode != CM_FULL_SCREEN)
4039                                         {
4040                                                 pa_render_end();
4041                                         }
4042                                 }
4043                         #endif
4044                 #endif 
4045
4046         WIN(DDGRUNLOCK(dd_grd_curcanv));
4047
4048         //      HACK! If guided missile, wake up robots as necessary.
4049         if (viewer->type == OBJ_WEAPON) {
4050                 // -- Used to require to be GUIDED -- if (viewer->id == GUIDEDMISS_ID)
4051                 wake_up_rendered_objects(viewer, win+1);
4052         }
4053
4054         if (label) {
4055         WIN(DDGRLOCK(dd_grd_curcanv));
4056         MAC(if (Scanline_double) FontHires = 0;)                // get the right font size
4057