]> icculus.org git repositories - btb/d2x.git/blob - main/gauges.c
fixes d1 still textures which are animated in d2, refactorizes d1 texture reading
[btb/d2x.git] / main / gauges.c
1 /* $Id: gauges.c,v 1.9 2003-10-04 02:58:23 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 #ifndef SHAREWARE
2635         if (Current_display_mode) {
2636                 bm=&GameBitmaps[Weapon_info[info_index].hires_picture.index];
2637                 PIGGY_PAGE_IN( Weapon_info[info_index].hires_picture );
2638         } else {
2639 #endif
2640                 bm=&GameBitmaps[Weapon_info[info_index].picture.index];
2641                 PIGGY_PAGE_IN( Weapon_info[info_index].picture );
2642 #ifndef SHAREWARE
2643         }
2644 #endif
2645         
2646         Assert(bm != NULL);
2647
2648 //   PA_DFX (pa_set_frontbuffer_current());
2649 //      PA_DFX (gr_ubitmapm(pic_x,pic_y,bm));
2650    PA_DFX (pa_set_backbuffer_current());
2651         gr_ubitmapm(pic_x,pic_y,bm);
2652         
2653         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2654
2655         if ((p=strchr(name,'\n'))!=NULL) {
2656                 *p=0;
2657            #ifdef PA_3DFX_VOODOO
2658   //                    pa_set_frontbuffer_current();
2659 //                      gr_printf(text_x,text_y,name);
2660 //                      gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2661                 #endif
2662                 PA_DFX (pa_set_backbuffer_current());
2663                 gr_printf(text_x,text_y,name);
2664                 gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2665                 *p='\n';
2666         } else
2667          {
2668   //            PA_DFX(pa_set_frontbuffer_current());
2669 //              PA_DFX (gr_printf(text_x,text_y,name));
2670                 PA_DFX(pa_set_backbuffer_current());
2671                 gr_printf(text_x,text_y,name);
2672          }      
2673
2674         //      For laser, show level and quadness
2675         if (info_index == LASER_ID || info_index == SUPER_LASER_ID) {
2676                 char    temp_str[7];
2677
2678                 sprintf(temp_str, "%s: 0", TXT_LVL);
2679
2680                 temp_str[5] = Players[Player_num].laser_level+1 + '0';
2681
2682 //              PA_DFX(pa_set_frontbuffer_current());
2683 //              PA_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2684                 PA_DFX(pa_set_backbuffer_current());
2685                 NO_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2686                 PA_DFX (gr_printf(text_x,text_y+12, temp_str));
2687
2688                 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
2689                         strcpy(temp_str, TXT_QUAD);
2690 //                      PA_DFX(pa_set_frontbuffer_current());
2691 //                      PA_DFX (gr_printf(text_x,text_y+2*Line_spacing, temp_str));
2692                         PA_DFX(pa_set_backbuffer_current());
2693                         gr_printf(text_x,text_y+2*Line_spacing, temp_str);
2694
2695                 }
2696
2697         }
2698 }
2699
2700
2701 void draw_weapon_info(int weapon_type,int weapon_num,int laser_level)
2702 {
2703         int info_index;
2704
2705         if (weapon_type == 0) {
2706                 info_index = Primary_weapon_to_weapon_info[weapon_num];
2707
2708                 if (info_index == LASER_ID && laser_level > MAX_LASER_LEVEL)
2709                         info_index = SUPER_LASER_ID;
2710
2711                 if (Cockpit_mode == CM_STATUS_BAR)
2712                         draw_weapon_info_sub(info_index,
2713                                 &gauge_boxes[SB_PRIMARY_BOX],
2714                                 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
2715                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2716                                 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
2717                 else
2718                         draw_weapon_info_sub(info_index,
2719                                 &gauge_boxes[COCKPIT_PRIMARY_BOX],
2720                                 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
2721                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2722                                 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
2723
2724         }
2725         else {
2726                 info_index = Secondary_weapon_to_weapon_info[weapon_num];
2727
2728                 if (Cockpit_mode == CM_STATUS_BAR)
2729                         draw_weapon_info_sub(info_index,
2730                                 &gauge_boxes[SB_SECONDARY_BOX],
2731                                 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
2732                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2733                                 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
2734                 else
2735                         draw_weapon_info_sub(info_index,
2736                                 &gauge_boxes[COCKPIT_SECONDARY_BOX],
2737                                 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
2738                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2739                                 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
2740         }
2741 }
2742
2743 void draw_ammo_info(int x,int y,int ammo_count,int primary)
2744 {
2745         int w;
2746         char str[16];
2747
2748         if (primary)
2749                 w = (grd_curcanv->cv_font->ft_w*7)/2;
2750         else
2751                 w = (grd_curcanv->cv_font->ft_w*5)/2;
2752
2753 WIN(DDGRLOCK(dd_grd_curcanv));
2754 {
2755
2756         PA_DFX (pa_set_frontbuffer_current());
2757
2758         gr_setcolor(BM_XRGB(0,0,0));
2759         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2760         gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
2761         sprintf(str,"%03d",ammo_count);
2762         convert_1s(str);
2763         gr_printf(x,y,str);
2764
2765         PA_DFX (pa_set_backbuffer_current());
2766         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2767         gr_printf(x,y,str);
2768 }
2769
2770 WIN(DDGRUNLOCK(dd_grd_curcanv));
2771 }
2772
2773 void draw_secondary_ammo_info(int ammo_count)
2774 {
2775         if (Cockpit_mode == CM_STATUS_BAR)
2776                 draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
2777         else
2778                 draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
2779 }
2780
2781 //returns true if drew picture
2782 int draw_weapon_box(int weapon_type,int weapon_num)
2783 {
2784         int drew_flag=0;
2785         int laser_level_changed;
2786
2787 WINDOS(
2788         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2789         gr_set_current_canvas(&VR_render_buffer[0])
2790 );
2791
2792    PA_DFX (pa_set_backbuffer_current());
2793  
2794 WIN(DDGRLOCK(dd_grd_curcanv));
2795         gr_set_curfont( GAME_FONT );
2796
2797         laser_level_changed = (weapon_type==0 && weapon_num==LASER_INDEX && (Players[Player_num].laser_level != old_laser_level[VR_current_page]));
2798
2799         if ((weapon_num != old_weapon[weapon_type][VR_current_page] || laser_level_changed) && weapon_box_states[weapon_type] == WS_SET) {
2800                 weapon_box_states[weapon_type] = WS_FADING_OUT;
2801                 weapon_box_fade_values[weapon_type]=i2f(GR_FADE_LEVELS-1);
2802         }
2803                 
2804         if (old_weapon[weapon_type][VR_current_page] == -1) {
2805                 //@@if (laser_level_changed)
2806                 //@@    old_weapon[weapon_type][VR_current_page] = LASER_INDEX;
2807                 //@@else 
2808                 {
2809                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2810                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2811                         old_ammo_count[weapon_type][VR_current_page]=-1;
2812                         Old_Omega_charge[VR_current_page]=-1;
2813                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2814                         drew_flag=1;
2815                         weapon_box_states[weapon_type] = WS_SET;
2816                 }
2817         }
2818
2819         if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
2820                 draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page],old_laser_level[VR_current_page]);
2821                 old_ammo_count[weapon_type][VR_current_page]=-1;
2822                 Old_Omega_charge[VR_current_page]=-1;
2823                 drew_flag=1;
2824                 weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
2825                 if (weapon_box_fade_values[weapon_type] <= 0) {
2826                         weapon_box_states[weapon_type] = WS_FADING_IN;
2827                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2828                         old_weapon[weapon_type][!VR_current_page] = weapon_num;
2829                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2830                         old_laser_level[!VR_current_page] = Players[Player_num].laser_level;
2831                         weapon_box_fade_values[weapon_type] = 0;
2832                 }
2833         }
2834         else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
2835                 if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
2836                         weapon_box_states[weapon_type] = WS_FADING_OUT;
2837                 }
2838                 else {
2839                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2840                         old_ammo_count[weapon_type][VR_current_page]=-1;
2841                         Old_Omega_charge[VR_current_page]=-1;
2842                         drew_flag=1;
2843                         weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
2844                         if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
2845                                 weapon_box_states[weapon_type] = WS_SET;
2846                                 old_weapon[weapon_type][!VR_current_page] = -1;         //force redraw (at full fade-in) of other page
2847                         }
2848                 }
2849         }
2850
2851         if (weapon_box_states[weapon_type] != WS_SET) {         //fade gauge
2852                 int fade_value = f2i(weapon_box_fade_values[weapon_type]);
2853                 int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2854                 
2855                 Gr_scanline_darkening_level = fade_value;
2856 //         PA_DFX (pa_set_frontbuffer_current());
2857 //              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));
2858            PA_DFX (pa_set_backbuffer_current());
2859                 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);
2860
2861                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2862         }
2863 WIN(DDGRUNLOCK(dd_grd_curcanv));
2864
2865 WINDOS(
2866         dd_gr_set_current_canvas(get_current_game_screen()),
2867         gr_set_current_canvas(get_current_game_screen())
2868 );
2869         return drew_flag;
2870 }
2871
2872 fix static_time[2];
2873
2874 void draw_static(int win)
2875 {
2876         vclip *vc = &Vclip[VCLIP_MONITOR_STATIC];
2877         grs_bitmap *bmp;
2878         int framenum;
2879         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2880         int x,y;
2881
2882         static_time[win] += FrameTime;
2883         if (static_time[win] >= vc->play_time) {
2884                 weapon_box_user[win] = WBU_WEAPON;
2885                 return;
2886         }
2887
2888         framenum = static_time[win] * vc->num_frames / vc->play_time;
2889
2890         PIGGY_PAGE_IN(vc->frames[framenum]);
2891
2892         bmp = &GameBitmaps[vc->frames[framenum].index];
2893
2894         WINDOS(
2895         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2896         gr_set_current_canvas(&VR_render_buffer[0])
2897         );
2898         WIN(DDGRLOCK(dd_grd_curcanv));
2899    PA_DFX (pa_set_backbuffer_current());
2900         PA_DFX (pa_bypass_mode (0));
2901         PA_DFX (pa_clip_window (gauge_boxes[boxofs+win].left,gauge_boxes[boxofs+win].top,
2902                                                                         gauge_boxes[boxofs+win].right,gauge_boxes[boxofs+win].bot));
2903    
2904         for (x=gauge_boxes[boxofs+win].left;x<gauge_boxes[boxofs+win].right;x+=bmp->bm_w)
2905                 for (y=gauge_boxes[boxofs+win].top;y<gauge_boxes[boxofs+win].bot;y+=bmp->bm_h)
2906                         gr_bitmap(x,y,bmp);
2907
2908         PA_DFX (pa_bypass_mode(1));
2909         PA_DFX (pa_clip_window (0,0,640,480));
2910
2911         WIN(DDGRUNLOCK(dd_grd_curcanv));
2912
2913         WINDOS(
2914         dd_gr_set_current_canvas(get_current_game_screen()),
2915         gr_set_current_canvas(get_current_game_screen())
2916         );
2917
2918 //   PA_DFX (return);
2919   
2920         WINDOS(
2921         copy_gauge_box(&gauge_boxes[boxofs+win],&dd_VR_render_buffer[0]),
2922         copy_gauge_box(&gauge_boxes[boxofs+win],&VR_render_buffer[0].cv_bitmap)
2923         );
2924 }
2925
2926 void draw_weapon_boxes()
2927 {
2928         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2929         int drew;
2930
2931         if (weapon_box_user[0] == WBU_WEAPON) {
2932                 drew = draw_weapon_box(0,Primary_weapon);
2933                 if (drew) 
2934                         WINDOS(
2935                                 copy_gauge_box(&gauge_boxes[boxofs+0],&dd_VR_render_buffer[0]),
2936                                 copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap)
2937                         );
2938
2939                 if (weapon_box_states[0] == WS_SET) {
2940                         if ((Primary_weapon == VULCAN_INDEX) || (Primary_weapon == GAUSS_INDEX)) {
2941                                 if (Players[Player_num].primary_ammo[VULCAN_INDEX] != old_ammo_count[0][VR_current_page]) {
2942                                         if (Newdemo_state == ND_STATE_RECORDING)
2943                                                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[VULCAN_INDEX]);
2944                                         draw_primary_ammo_info(f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX]));
2945                                         old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[VULCAN_INDEX];
2946                                 }
2947                         }
2948
2949                         if (Primary_weapon == OMEGA_INDEX) {
2950                                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
2951                                         if (Newdemo_state == ND_STATE_RECORDING)
2952                                                 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
2953                                         draw_primary_ammo_info(Omega_charge * 100/MAX_OMEGA_CHARGE);
2954                                         Old_Omega_charge[VR_current_page] = Omega_charge;
2955                                 }
2956                         }
2957                 }
2958         }
2959         else if (weapon_box_user[0] == WBU_STATIC)
2960                 draw_static(0);
2961
2962         if (weapon_box_user[1] == WBU_WEAPON) {
2963                 drew = draw_weapon_box(1,Secondary_weapon);
2964                 if (drew)
2965                         WINDOS(
2966                                 copy_gauge_box(&gauge_boxes[boxofs+1],&dd_VR_render_buffer[0]),
2967                                 copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap)
2968                         );
2969
2970                 if (weapon_box_states[1] == WS_SET)
2971                         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
2972                                 old_bombcount[VR_current_page] = 0x7fff;        //force redraw
2973                                 if (Newdemo_state == ND_STATE_RECORDING)
2974                                         newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
2975                                 draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
2976                                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
2977                         }
2978         }
2979         else if (weapon_box_user[1] == WBU_STATIC)
2980                 draw_static(1);
2981 }
2982
2983
2984 void sb_draw_energy_bar(energy)
2985 {
2986         int erase_height, w, h, aw;
2987         char energy_str[20];
2988
2989         gr_set_current_canvas( Canv_SBEnergyGauge );
2990
2991         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2992         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_ENERGY) ] );
2993
2994         erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
2995
2996         if (erase_height > 0) {
2997                 gr_setcolor( BM_XRGB(0,0,0) );
2998                 gr_rect(0,0,SB_ENERGY_GAUGE_W-1,erase_height-1);
2999         }
3000
3001         WINDOS(
3002         dd_gr_set_current_canvas(get_current_game_screen()),
3003         gr_set_current_canvas(get_current_game_screen())
3004         );
3005
3006         WIN(DDGRLOCK(dd_grd_curcanv));
3007    PA_DFX (pa_set_frontbuffer_current());
3008    PA_DFX (gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap));
3009    PA_DFX (pa_set_backbuffer_current());
3010         gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap );
3011
3012         //draw numbers
3013         sprintf(energy_str, "%d", energy);
3014         gr_get_string_size(energy_str, &w, &h, &aw );
3015         gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
3016    PA_DFX (pa_set_frontbuffer_current());
3017         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));
3018    PA_DFX (pa_set_backbuffer_current());
3019         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);
3020         WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3021 }
3022
3023 void sb_draw_afterburner()
3024 {
3025         int erase_height, w, h, aw;
3026         char ab_str[3] = "AB";
3027
3028         gr_set_current_canvas( Canv_SBAfterburnerGauge );
3029         PAGE_IN_GAUGE( SB_GAUGE_AFTERBURNER );
3030         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_AFTERBURNER) ] );
3031
3032         erase_height = fixmul((f1_0 - Afterburner_charge),SB_AFTERBURNER_GAUGE_H);
3033
3034         if (erase_height > 0) {
3035                 gr_setcolor( BM_XRGB(0,0,0) );
3036                 gr_rect(0,0,SB_AFTERBURNER_GAUGE_W-1,erase_height-1);
3037         }
3038
3039 WINDOS(
3040         dd_gr_set_current_canvas(get_current_game_screen()),
3041         gr_set_current_canvas(get_current_game_screen())
3042 );
3043 WIN(DDGRLOCK(dd_grd_curcanv));
3044    PA_DFX (pa_set_frontbuffer_current());
3045         gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap );
3046    PA_DFX (pa_set_backbuffer_current());
3047         PA_DFX (gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap ));
3048
3049         //draw legend
3050         if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
3051                 gr_set_fontcolor(gr_getcolor(45,0,0),-1 );
3052         else 
3053                 gr_set_fontcolor(gr_getcolor(12,12,12),-1 );
3054
3055         gr_get_string_size(ab_str, &w, &h, &aw );
3056    PA_DFX (pa_set_frontbuffer_current());
3057         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"));
3058    PA_DFX (pa_set_backbuffer_current());
3059         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");
3060
3061 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3062 }
3063
3064 void sb_draw_shield_num(int shield)
3065 {
3066         //draw numbers
3067
3068         gr_set_curfont( GAME_FONT );
3069         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
3070
3071         //erase old one
3072         PIGGY_PAGE_IN( cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)] );
3073
3074 WIN(DDGRLOCK(dd_grd_curcanv));
3075    PA_DFX (pa_set_back_to_read());
3076         gr_setcolor(gr_gpixel(&grd_curcanv->cv_bitmap,SB_SHIELD_NUM_X-1,SB_SHIELD_NUM_Y-1));
3077    PA_DFX (pa_set_front_to_read());
3078
3079         PA_DFX (pa_set_frontbuffer_current());
3080
3081         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);
3082         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);
3083
3084         PA_DFX (pa_set_backbuffer_current());
3085         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));
3086         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));
3087
3088 WIN(DDGRUNLOCK(dd_grd_curcanv));
3089 }
3090
3091 void sb_draw_shield_bar(int shield)
3092 {
3093         int bm_num = shield>=100?9:(shield / 10);
3094
3095 WINDOS(
3096         dd_gr_set_current_canvas(get_current_game_screen()),
3097         gr_set_current_canvas(get_current_game_screen())
3098 );
3099 WIN(DDGRLOCK(dd_grd_curcanv));
3100         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num );
3101    PA_DFX (pa_set_frontbuffer_current());               
3102         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
3103    PA_DFX (pa_set_backbuffer_current());                
3104         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
3105         
3106 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
3107 }
3108
3109 void sb_draw_keys()
3110 {
3111         grs_bitmap * bm;
3112         int flags = Players[Player_num].flags;
3113
3114 WINDOS(
3115         dd_gr_set_current_canvas(get_current_game_screen()),
3116         gr_set_current_canvas(get_current_game_screen())
3117 );
3118 WIN(DDGRLOCK(dd_grd_curcanv));
3119    PA_DFX (pa_set_frontbuffer_current());
3120         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
3121         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
3122         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
3123         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
3124         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
3125         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
3126         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
3127         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
3128         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
3129         #ifdef PA_3DFX_VOODOO
3130            PA_DFX (pa_set_backbuffer_current());
3131                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
3132                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
3133                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
3134                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
3135                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
3136                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
3137                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
3138                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
3139                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
3140         #endif
3141
3142 WIN(DDGRUNLOCK(dd_grd_curcanv));
3143 }
3144
3145 //      Draws invulnerable ship, or maybe the flashing ship, depending on invulnerability time left.
3146 void draw_invulnerable_ship()
3147 {
3148         static fix time=0;
3149
3150 WINDOS(
3151         dd_gr_set_current_canvas(get_current_game_screen()),
3152         gr_set_current_canvas(get_current_game_screen())
3153 );
3154 WIN(DDGRLOCK(dd_grd_curcanv));
3155
3156         if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000)) {
3157
3158                 if (Cockpit_mode == CM_STATUS_BAR)      {
3159                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
3160                         PA_DFX (pa_set_frontbuffer_current());
3161                         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] );
3162                         PA_DFX (pa_set_backbuffer_current());
3163                         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] ));
3164                 } else {
3165                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
3166                         PA_DFX (pa_set_frontbuffer_current());
3167                         PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] ));
3168                         PA_DFX (pa_set_backbuffer_current());
3169                         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] );
3170                 }
3171
3172                 time += FrameTime;
3173
3174                 while (time > INV_FRAME_TIME) {
3175                         time -= INV_FRAME_TIME;
3176                         if (++invulnerable_frame == N_INVULNERABLE_FRAMES)
3177                                 invulnerable_frame=0;
3178                 }
3179         } else if (Cockpit_mode == CM_STATUS_BAR)
3180                 sb_draw_shield_bar(f2ir(Players[Player_num].shields));
3181         else
3182                 draw_shield_bar(f2ir(Players[Player_num].shields));
3183 WIN(DDGRUNLOCK(dd_grd_curcanv));
3184 }
3185
3186 extern int Missile_gun;
3187 extern int allowed_to_fire_laser(void);
3188 extern int allowed_to_fire_missile(void);
3189
3190 rgb player_rgb[] = {
3191                                                         {15,15,23},
3192                                                         {27,0,0},
3193                                                         {0,23,0},
3194                                                         {30,11,31},
3195                                                         {31,16,0},
3196                                                         {24,17,6},
3197                                                         {14,21,12},
3198                                                         {29,29,0},
3199                                                 };
3200
3201 extern ubyte Newdemo_flying_guided;
3202 extern int max_window_w;
3203
3204 typedef struct {
3205         sbyte x, y;
3206 } xy;
3207
3208 //offsets for reticle parts: high-big  high-sml  low-big  low-sml
3209 xy cross_offsets[4] =           { {-8,-5},      {-4,-2},        {-4,-2}, {-2,-1} };
3210 xy primary_offsets[4] =         { {-30,14}, {-16,6},    {-15,6}, {-8, 2} };
3211 xy secondary_offsets[4] =       { {-24,2},      {-12,0}, {-12,1}, {-6,-2} };
3212
3213 //draw the reticle
3214 void show_reticle(int force_big_one)
3215 {
3216         int x,y;
3217         int laser_ready,missile_ready,laser_ammo,missile_ammo;
3218         int cross_bm_num,primary_bm_num,secondary_bm_num;
3219         int use_hires_reticle,small_reticle,ofs,gauge_index;
3220
3221    if (Newdemo_state==ND_STATE_PLAYBACK && Newdemo_flying_guided)
3222                 {
3223                 WIN(DDGRLOCK(dd_grd_curcanv));
3224                  draw_guided_crosshair();
3225                 WIN(DDGRUNLOCK(dd_grd_curcanv));
3226                  return;
3227            }
3228
3229         x = grd_curcanv->cv_w/2;
3230         y = grd_curcanv->cv_h/2;
3231
3232         laser_ready = allowed_to_fire_laser();
3233         missile_ready = allowed_to_fire_missile();
3234
3235         laser_ammo = player_has_weapon(Primary_weapon,0);
3236         missile_ammo = player_has_weapon(Secondary_weapon,1);
3237
3238         primary_bm_num = (laser_ready && laser_ammo==HAS_ALL);
3239         secondary_bm_num = (missile_ready && missile_ammo==HAS_ALL);
3240
3241         if (primary_bm_num && Primary_weapon==LASER_INDEX && (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS))
3242                 primary_bm_num++;
3243
3244         if (Secondary_weapon_to_gun_num[Secondary_weapon]==7)
3245                 secondary_bm_num += 3;          //now value is 0,1 or 3,4
3246         else if (secondary_bm_num && !(Missile_gun&1))
3247                         secondary_bm_num++;
3248
3249         cross_bm_num = ((primary_bm_num > 0) || (secondary_bm_num > 0));
3250
3251         Assert(primary_bm_num <= 2);
3252         Assert(secondary_bm_num <= 4);
3253         Assert(cross_bm_num <= 1);
3254 #ifdef OGL
3255       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);
3256        } else {
3257 #endif
3258
3259
3260         #ifndef MACINTOSH
3261                 use_hires_reticle = (FontHires != 0);
3262         #else
3263                 use_hires_reticle = !Scanline_double;
3264         #endif
3265
3266         WIN(DDGRLOCK(dd_grd_curcanv));
3267
3268 #ifndef MACINTOSH
3269         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*2 || force_big_one);
3270 #else
3271         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*(Scanline_double?1:2) || force_big_one);
3272 #endif
3273         ofs = (use_hires_reticle?0:2) + small_reticle;
3274
3275         gauge_index = (small_reticle?SML_RETICLE_CROSS:RETICLE_CROSS) + cross_bm_num;
3276         PAGE_IN_GAUGE( gauge_index );
3277         gr_ubitmapm(x+cross_offsets[ofs].x,y+cross_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3278
3279         gauge_index = (small_reticle?SML_RETICLE_PRIMARY:RETICLE_PRIMARY) + primary_bm_num;
3280         PAGE_IN_GAUGE( gauge_index );
3281         gr_ubitmapm(x+primary_offsets[ofs].x,y+primary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3282
3283         gauge_index = (small_reticle?SML_RETICLE_SECONDARY:RETICLE_SECONDARY) + secondary_bm_num;
3284         PAGE_IN_GAUGE( gauge_index );
3285         gr_ubitmapm(x+secondary_offsets[ofs].x,y+secondary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3286
3287         WIN(DDGRUNLOCK(dd_grd_curcanv));
3288 #ifdef OGL
3289        }
3290 #endif
3291 }
3292
3293 #ifdef NETWORK
3294 void hud_show_kill_list()
3295 {
3296         int n_players,player_list[MAX_NUM_NET_PLAYERS];
3297         int n_left,i,x0,x1,y,save_y,fth;
3298
3299 // ugly hack since placement of netgame players and kills is based off of
3300 // menuhires (which is always 1 for mac).  This throws off placement of
3301 // players in pixel double mode.
3302
3303 #ifdef MACINTOSH
3304         MenuHires = !(Scanline_double);
3305 #endif
3306
3307         if (Show_kill_list_timer > 0)
3308         {
3309                 Show_kill_list_timer -= FrameTime;
3310                 if (Show_kill_list_timer < 0)
3311                         Show_kill_list = 0;
3312         }
3313         
3314         gr_set_curfont( GAME_FONT );
3315
3316         n_players = multi_get_kill_list(player_list);
3317
3318         if (Show_kill_list == 3)
3319                 n_players = 2;
3320
3321         if (n_players <= 4)
3322                 n_left = n_players;
3323         else
3324                 n_left = (n_players+1)/2;
3325
3326         //If font size changes, this code might not work right anymore 
3327         //Assert(GAME_FONT->ft_h==5 && GAME_FONT->ft_w==7);
3328
3329         fth = GAME_FONT->ft_h;
3330
3331         x0 = LHX(1); x1 = LHX(43);
3332
3333         if (Game_mode & GM_MULTI_COOP)
3334                 x1 = LHX(31);
3335
3336         save_y = y = grd_curcanv->cv_h - n_left*(fth+1);
3337
3338         if (Cockpit_mode == CM_FULL_COCKPIT) {
3339                 save_y = y -= LHX(6);
3340                 if (Game_mode & GM_MULTI_COOP)
3341                         x1 = LHX(33);
3342                 else
3343                         x1 = LHX(43);
3344         }
3345
3346         for (i=0;i<n_players;i++) {
3347                 int player_num;
3348                 char name[9];
3349                 int sw,sh,aw;
3350
3351                 if (i>=n_left) {
3352                         if (Cockpit_mode == CM_FULL_COCKPIT)
3353                                 x0 = grd_curcanv->cv_w - LHX(53);
3354                         else
3355                                 x0 = grd_curcanv->cv_w - LHX(60);
3356                         if (Game_mode & GM_MULTI_COOP)
3357                                 x1 = grd_curcanv->cv_w - LHX(27);
3358                         else
3359                                 x1 = grd_curcanv->cv_w - LHX(15);  // Right edge of name, change this for width problems
3360                         if (i==n_left)
3361                                 y = save_y;
3362
3363         if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3364            {
3365              x1-=LHX(18);
3366             // x0-=LHX(18);
3367            }
3368                 }
3369      else  if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3370            {
3371                                  x1 = LHX(43);
3372              x1-=LHX(18);
3373             // x0-=LHX(18);
3374            }
3375
3376         
3377                 if (Show_kill_list == 3)
3378                         player_num = i;
3379                 else
3380                         player_num = player_list[i];
3381
3382                 if (Show_kill_list == 1 || Show_kill_list==2)
3383                 {
3384                         int color;
3385
3386                         if (Players[player_num].connected != 1)
3387                                 gr_set_fontcolor(gr_getcolor(12, 12, 12), -1);
3388                         else if (Game_mode & GM_TEAM) {
3389                                 color = get_team(player_num);
3390                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3391                         }
3392                         else {
3393                                 color = player_num;
3394                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3395                         }
3396                 }       
3397
3398                 else 
3399                 {
3400                         gr_set_fontcolor(gr_getcolor(player_rgb[player_num].r,player_rgb[player_num].g,player_rgb[player_num].b),-1 );
3401                 }
3402
3403                 if (Show_kill_list == 3)
3404                         strcpy(name, Netgame.team_name[i]);
3405                 else
3406                         strcpy(name,Players[player_num].callsign);      // Note link to above if!!
3407                 gr_get_string_size(name,&sw,&sh,&aw);
3408                 while (sw > (x1-x0-LHX(2))) {
3409                         name[strlen(name)-1]=0;
3410                         gr_get_string_size(name,&sw,&sh,&aw);
3411                 }
3412                 gr_printf(x0,y,"%s",name);
3413
3414                 if (Show_kill_list==2)
3415                  {
3416                   if (Players[player_num].net_killed_total+Players[player_num].net_kills_total==0)
3417                         gr_printf (x1,y,"NA");
3418                   else
3419                    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));           
3420                  }
3421                 else if (Show_kill_list == 3)   
3422                         gr_printf(x1,y,"%3d",team_kills[i]);
3423                 else if (Game_mode & GM_MULTI_COOP)
3424                         gr_printf(x1,y,"%-6d",Players[player_num].score);
3425       else if (Netgame.PlayTimeAllowed || Netgame.KillGoal)
3426          gr_printf(x1,y,"%3d(%d)",Players[player_num].net_kills_total,Players[player_num].KillGoalCount);
3427       else
3428                         gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
3429                         
3430                 y += fth+1;
3431
3432         }
3433
3434 #ifdef MACINTOSH
3435         MenuHires = 1;
3436 #endif
3437 }
3438 #endif
3439
3440 #ifndef RELEASE
3441 extern int Saving_movie_frames;
3442 #else
3443 #define Saving_movie_frames 0
3444 #endif
3445
3446 //returns true if viewer can see object
3447 int see_object(int objnum)
3448 {
3449         fvi_query fq;
3450         int hit_type;
3451         fvi_info hit_data;
3452
3453         //see if we can see this player
3454
3455         fq.p0                                   = &Viewer->pos;
3456         fq.p1                                   = &Objects[objnum].pos;
3457         fq.rad                                  = 0;
3458         fq.thisobjnum                   = Viewer - Objects;
3459         fq.flags                                = FQ_TRANSWALL | FQ_CHECK_OBJS;
3460         fq.startseg                             = Viewer->segnum;
3461         fq.ignore_obj_list      = NULL;
3462
3463         hit_type = find_vector_intersection(&fq, &hit_data);
3464
3465         return (hit_type == HIT_OBJECT && hit_data.hit_object == objnum);
3466 }
3467
3468 #ifdef NETWORK
3469 //show names of teammates & players carrying flags
3470 void show_HUD_names()
3471 {
3472         int show_team_names,show_all_names,show_flags,player_team;
3473         int p;
3474
3475         show_all_names = ((Newdemo_state == ND_STATE_PLAYBACK) || (Netgame.ShowAllNames && Show_reticle_name));
3476         show_team_names = (((Game_mode & GM_MULTI_COOP) || (Game_mode & GM_TEAM)) && Show_reticle_name);
3477         show_flags = (Game_mode & GM_CAPTURE) | (Game_mode & GM_HOARD);
3478
3479         if (! (show_all_names || show_team_names || show_flags))
3480                 return;
3481
3482         player_team = get_team(Player_num);
3483
3484         for (p=0;p<N_players;p++) {     //check all players
3485                 int objnum;
3486                 int show_name,has_flag;
3487
3488                 show_name = ((show_all_names && !(Players[p].flags & PLAYER_FLAGS_CLOAKED)) || (show_team_names && get_team(p)==player_team));
3489                 has_flag = (Players[p].connected && Players[p].flags & PLAYER_FLAGS_FLAG);
3490
3491                 if (Newdemo_state == ND_STATE_PLAYBACK) {
3492                         //if this is a demo, the objnum in the player struct is wrong,
3493                         //so we search the object list for the objnum
3494
3495                         for (objnum=0;objnum<=Highest_object_index;objnum++)
3496                                 if (Objects[objnum].type==OBJ_PLAYER && Objects[objnum].id == p)
3497                                         break;
3498                         if (objnum > Highest_object_index)              //not in list, thus not visible
3499                                 show_name = has_flag = 0;                               //..so don't show name
3500                 }
3501                 else
3502                         objnum = Players[p].objnum;
3503
3504                 if ((show_name || has_flag) && see_object(objnum)) {
3505                         g3s_point player_point;
3506
3507                         g3_rotate_point(&player_point,&Objects[objnum].pos);
3508
3509                         if (player_point.p3_codes == 0) {       //on screen
3510
3511                                 g3_project_point(&player_point);
3512
3513                                 if (! (player_point.p3_flags & PF_OVERFLOW)) {
3514                                         fix x,y;
3515                         
3516                                         x = player_point.p3_sx;
3517                                         y = player_point.p3_sy;
3518                         
3519                                         if (show_name) {                                // Draw callsign on HUD
3520                                                 char s[CALLSIGN_LEN+1];
3521                                                 int w, h, aw;
3522                                                 int x1, y1;
3523                                                 int color_num;
3524                         
3525                                                 color_num = (Game_mode & GM_TEAM)?get_team(p):p;
3526
3527                                                 sprintf(s, "%s", Players[p].callsign);
3528                                                 gr_get_string_size(s, &w, &h, &aw);
3529                                                 gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
3530                                                 x1 = f2i(x)-w/2;
3531                                                 y1 = f2i(y)-h/2;
3532                                                 gr_string (x1, y1, s);
3533                                         }
3534                 
3535                                         if (has_flag) {                         // Draw box on HUD
3536                                                 fix dx,dy,w,h;
3537                         
3538                                                 dy = -fixmuldiv(fixmul(Objects[objnum].size,Matrix_scale.y),i2f(grd_curcanv->cv_h)/2,player_point.p3_z);
3539                                                 dx = fixmul(dy,grd_curscreen->sc_aspect);
3540         
3541                                                 w = dx/4;
3542                                                 h = dy/4;
3543         
3544                                                 if (Game_mode & GM_CAPTURE)
3545                                                         gr_setcolor((get_team(p) == TEAM_BLUE)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3546                                                 else if (Game_mode & GM_HOARD)
3547                                                 {
3548                                                         if (Game_mode & GM_TEAM)
3549                                                                 gr_setcolor((get_team(p) == TEAM_RED)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3550                                                         else
3551                                                                 gr_setcolor(BM_XRGB(0,31,0));
3552                                                 }
3553
3554                                                 gr_line(x+dx-w,y-dy,x+dx,y-dy);
3555                                                 gr_line(x+dx,y-dy,x+dx,y-dy+h);
3556         
3557                                                 gr_line(x-dx,y-dy,x-dx+w,y-dy);
3558                                                 gr_line(x-dx,y-dy,x-dx,y-dy+h);
3559         
3560                                                 gr_line(x+dx-w,y+dy,x+dx,y+dy);
3561                                                 gr_line(x+dx,y+dy,x+dx,y+dy-h);
3562         
3563                                                 gr_line(x-dx,y+dy,x-dx+w,y+dy);
3564                                                 gr_line(x-dx,y+dy,x-dx,y+dy-h);
3565                                         }
3566                                 }
3567                         }
3568                 }
3569         }
3570 }
3571 #endif
3572
3573
3574 extern int last_drawn_cockpit[2];
3575
3576 //draw all the things on the HUD
3577 void draw_hud()
3578 {
3579
3580 #ifdef OGL
3581         if (Cockpit_mode==CM_STATUS_BAR){
3582                 //ogl needs to redraw every frame, at least currently.
3583                 //              init_cockpit();
3584                         last_drawn_cockpit[0]=-1;
3585                         last_drawn_cockpit[1]=-1;
3586                                   init_gauges();
3587                 
3588                                //              vr_reset_display();
3589         }
3590 #endif
3591                                           
3592
3593 #ifdef MACINTOSH
3594         if (Scanline_double)            // I should be shot for this ugly hack....
3595                 FontHires = 1;
3596 #endif
3597         Line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
3598 #ifdef MACINTOSH
3599         if (Scanline_double)
3600                 FontHires = 0;
3601 #endif
3602
3603 WIN(DDGRLOCK(dd_grd_curcanv));
3604         //      Show score so long as not in rearview
3605         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames) {
3606                 hud_show_score();
3607                 if (score_time)
3608                         hud_show_score_added();
3609         }
3610
3611         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && !Saving_movie_frames) 
3612          hud_show_timer_count();
3613
3614         //      Show other stuff if not in rearview or letterbox.
3615         if (!Rear_view && Cockpit_mode!=CM_REAR_VIEW) { // && Cockpit_mode!=CM_LETTERBOX) {
3616                 if (Cockpit_mode==CM_STATUS_BAR || Cockpit_mode==CM_FULL_SCREEN)
3617                         hud_show_homing_warning();
3618
3619                 if (Cockpit_mode==CM_FULL_SCREEN) {
3620                         hud_show_energy();
3621                         hud_show_shield();
3622                         hud_show_afterburner();
3623                         hud_show_weapons();
3624                         if (!Saving_movie_frames)
3625                                 hud_show_keys();
3626                         hud_show_cloak_invuln();
3627
3628                         if ( ( Newdemo_state==ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags[VR_current_page] )) {
3629                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3630                                 old_flags[VR_current_page] = Players[Player_num].flags;
3631                         }
3632                 }
3633
3634                 #ifdef NETWORK
3635                 #ifndef RELEASE
3636                 if (!(Game_mode&GM_MULTI && Show_kill_list) && !Saving_movie_frames)
3637                         show_time();
3638                 #endif
3639                 #endif
3640                 if (Reticle_on && Cockpit_mode != CM_LETTERBOX && (!Use_player_head_angles))
3641                         show_reticle(0);
3642
3643 #ifdef NETWORK
3644                 show_HUD_names();
3645
3646                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3647                         hud_show_flag();
3648
3649                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3650                         hud_show_orbs();
3651
3652 #endif
3653                 if (!Saving_movie_frames)
3654                         HUD_render_message_frame();
3655
3656                 if (Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames)
3657                         hud_show_lives();
3658
3659                 #ifdef NETWORK
3660                 if (Game_mode&GM_MULTI && Show_kill_list)
3661                         hud_show_kill_list();
3662                 #endif
3663         }
3664
3665         if (Rear_view && Cockpit_mode!=CM_REAR_VIEW) {
3666                 HUD_render_message_frame();
3667                 gr_set_curfont( GAME_FONT );
3668                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
3669                 if (Newdemo_state == ND_STATE_PLAYBACK)
3670                         gr_printf(0x8000,grd_curcanv->cv_h-14,TXT_REAR_VIEW);
3671                 else
3672                         gr_printf(0x8000,grd_curcanv->cv_h-10,TXT_REAR_VIEW);
3673         }
3674 WIN(DDGRUNLOCK(dd_grd_curcanv));
3675 }
3676
3677 extern short *BackBuffer;
3678
3679 //print out some player statistics
3680 void render_gauges()
3681 {
3682 #ifndef MACINTOSH
3683         static int old_display_mode = 0;
3684 #else
3685         static int old_display_mode = 1;
3686 #endif
3687         int energy = f2ir(Players[Player_num].energy);
3688         int shields = f2ir(Players[Player_num].shields);
3689         int cloak = ((Players[Player_num].flags&PLAYER_FLAGS_CLOAKED) != 0);
3690         int frc=0;
3691  
3692    PA_DFX (frc=0);
3693    PA_DFX (pa_set_backbuffer_current());
3694
3695         Assert(Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR);
3696
3697 // check to see if our display mode has changed since last render time --
3698 // if so, then we need to make new gauge canvases.
3699
3700   
3701         if (old_display_mode != Current_display_mode) {
3702                 close_gauge_canvases();
3703                 init_gauge_canvases();
3704                 old_display_mode = Current_display_mode;
3705         }
3706
3707         if (shields < 0 ) shields = 0;
3708
3709         WINDOS(
3710                 dd_gr_set_current_canvas(get_current_game_screen()),
3711                 gr_set_current_canvas(get_current_game_screen())
3712         );
3713         gr_set_curfont( GAME_FONT );
3714
3715         if (Newdemo_state == ND_STATE_RECORDING)
3716                 if (Players[Player_num].homing_object_dist >= 0)
3717                         newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
3718
3719         if (Cockpit_mode == CM_FULL_COCKPIT) {
3720                 if (energy != old_energy[VR_current_page]) {
3721                         if (Newdemo_state==ND_STATE_RECORDING ) {
3722                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3723                         }
3724                         draw_energy_bar(energy);
3725                         draw_numerical_display(shields, energy);
3726                         old_energy[VR_current_page] = energy;
3727                 }
3728
3729                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
3730                         if (Newdemo_state==ND_STATE_RECORDING ) {
3731                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3732                         }
3733                         draw_afterburner_bar(Afterburner_charge);
3734                         old_afterburner[VR_current_page] = Afterburner_charge;
3735                 }
3736
3737                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3738                         draw_numerical_display(shields, energy);
3739                         draw_invulnerable_ship();
3740                         old_shields[VR_current_page] = shields ^ 1;
3741                 } else if (shields != old_shields[VR_current_page]) {           // Draw the shield gauge
3742                         if (Newdemo_state==ND_STATE_RECORDING ) {
3743                                 newdemo_record_player_shields(old_shields[VR_current_page], shields);
3744                         }
3745                         draw_shield_bar(shields);
3746                         draw_numerical_display(shields, energy);
3747                         old_shields[VR_current_page] = shields;
3748                 }
3749         
3750                 if (Players[Player_num].flags != old_flags[VR_current_page]) {
3751                         if (Newdemo_state==ND_STATE_RECORDING )
3752                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3753                         draw_keys();
3754                         old_flags[VR_current_page] = Players[Player_num].flags;
3755                 }
3756
3757                 show_homing_warning();
3758
3759                 show_bomb_count(BOMB_COUNT_X,BOMB_COUNT_Y,gr_find_closest_color(0,0,0),0);
3760         
3761         } else if (Cockpit_mode == CM_STATUS_BAR) {
3762
3763                 if (energy != old_energy[VR_current_page] || frc)  {
3764                         if (Newdemo_state==ND_STATE_RECORDING ) {
3765                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3766                         }
3767                         sb_draw_energy_bar(energy);
3768                         old_energy[VR_current_page] = energy;
3769                 }
3770
3771                 if (Afterburner_charge != old_afterburner[VR_current_page] || frc) {
3772                         if (Newdemo_state==ND_STATE_RECORDING ) {
3773                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3774                         }
3775                         sb_draw_afterburner();
3776                         old_afterburner[VR_current_page] = Afterburner_charge;
3777                 }
3778         
3779                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3780                         draw_invulnerable_ship();
3781                         old_shields[VR_current_page] = shields ^ 1;
3782                         sb_draw_shield_num(shields);
3783                 } 
3784                 else 
3785                         if (shields != old_shields[VR_current_page] || frc) {           // Draw the shield gauge
3786                                 if (Newdemo_state==ND_STATE_RECORDING ) {
3787                                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
3788                                 }
3789                                 sb_draw_shield_bar(shields);
3790                                 old_shields[VR_current_page] = shields;
3791                                 sb_draw_shield_num(shields);
3792                         }
3793
3794                 if (Players[Player_num].flags != old_flags[VR_current_page] || frc) {
3795                         if (Newdemo_state==ND_STATE_RECORDING )
3796                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3797                         sb_draw_keys();
3798                         old_flags[VR_current_page] = Players[Player_num].flags;
3799                 }
3800         
3801
3802                 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3803                 {
3804                         if (Players[Player_num].net_killed_total != old_lives[VR_current_page] || frc) {
3805                                 sb_show_lives();
3806                                 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
3807                         }
3808                 }
3809                 else
3810                 {
3811                         if (Players[Player_num].lives != old_lives[VR_current_page] || frc) {
3812                                 sb_show_lives();
3813                                 old_lives[VR_current_page] = Players[Player_num].lives;
3814                         }
3815                 }
3816
3817                 if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) {
3818                         if (Players[Player_num].net_kills_total != old_score[VR_current_page] || frc) {
3819                                 sb_show_score();
3820                                 old_score[VR_current_page] = Players[Player_num].net_kills_total;
3821                         }
3822                 }
3823                 else {
3824                         if (Players[Player_num].score != old_score[VR_current_page] || frc) {
3825                                 sb_show_score();
3826                                 old_score[VR_current_page] = Players[Player_num].score;
3827                         }
3828
3829                         //if (score_time)
3830                                 sb_show_score_added();
3831                 }
3832
3833                 show_bomb_count(SB_BOMB_COUNT_X,SB_BOMB_COUNT_Y,gr_find_closest_color(5,5,5),0);
3834         }
3835
3836         if (frc || cloak != old_cloak[VR_current_page] || cloak_fade_state || (cloak && GameTime>Players[Player_num].cloak_time+CLOAK_TIME_MAX-i2f(3))) {
3837                 if (Cockpit_mode == CM_FULL_COCKPIT)
3838                         draw_player_ship(cloak,old_cloak[VR_current_page],SHIP_GAUGE_X,SHIP_GAUGE_Y);
3839                 else
3840                         draw_player_ship(cloak,old_cloak[VR_current_page],SB_SHIP_GAUGE_X,SB_SHIP_GAUGE_Y);
3841
3842                 old_cloak[VR_current_page]=cloak;
3843         }
3844
3845
3846         draw_weapon_boxes();
3847
3848 }
3849
3850 //      ---------------------------------------------------------------------------------------------------------
3851 //      Call when picked up a laser powerup.
3852 //      If laser is active, set old_weapon[0] to -1 to force redraw.
3853 void update_laser_weapon_info(void)
3854 {
3855         if (old_weapon[0][VR_current_page] == 0)
3856                 if (! (Players[Player_num].laser_level > MAX_LASER_LEVEL && old_laser_level[VR_current_page] <= MAX_LASER_LEVEL))
3857                         old_weapon[0][VR_current_page] = -1;
3858 }
3859
3860 extern int Game_window_y;
3861 void fill_background(void);
3862
3863 int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
3864
3865 //draws a 3d view into one of the cockpit windows.  win is 0 for left,
3866 //1 for right.  viewer is object.  NULL object means give up window
3867 //user is one of the WBU_ constants.  If rear_view_flag is set, show a
3868 //rear view.  If label is non-NULL, print the label at the top of the
3869 //window.
3870 void do_cockpit_window_view(int win,object *viewer,int rear_view_flag,int user,char *label)
3871 {
3872         WINDOS(
3873                 dd_grs_canvas window_canv,
3874                 grs_canvas window_canv
3875         );
3876         WINDOS(
3877                 static dd_grs_canvas overlap_canv,
3878                 static grs_canvas overlap_canv
3879         );
3880
3881 #ifdef WINDOWS
3882         int saved_window_x, saved_window_y;
3883 #endif
3884
3885         object *viewer_save = Viewer;
3886         static int overlap_dirty[2]={0,0};
3887         int boxnum;
3888         static int window_x,window_y;
3889         gauge_box *box;
3890         int rear_view_save = Rear_view;
3891         int w,h,dx;
3892
3893         box = NULL;
3894
3895         if (viewer == NULL) {                                                           //this user is done
3896
3897                 Assert(user == WBU_WEAPON || user == WBU_STATIC);
3898
3899                 if (user == WBU_STATIC && weapon_box_user[win] != WBU_STATIC)
3900                         static_time[win] = 0;
3901
3902                 if (weapon_box_user[win] == WBU_WEAPON || weapon_box_user[win] == WBU_STATIC)
3903                         return;         //already set
3904
3905                 weapon_box_user[win] = user;
3906
3907                 if (overlap_dirty[win]) {
3908                 WINDOS(
3909                         dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
3910                         gr_set_current_canvas(&VR_screen_pages[VR_current_page])
3911                 );
3912                         fill_background();
3913                         overlap_dirty[win] = 0;
3914                 }
3915
3916                 return;
3917         }
3918
3919         update_rendered_data(win+1, viewer, rear_view_flag, user);
3920
3921         weapon_box_user[win] = user;                                            //say who's using window
3922                 
3923         Viewer = viewer;
3924         Rear_view = rear_view_flag;
3925
3926         if (Cockpit_mode == CM_FULL_SCREEN)
3927         {
3928
3929                 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
3930                 #ifdef MACINTOSH
3931                 if (Scanline_double)
3932                         w /= 2;
3933                 #endif
3934
3935                 h = i2f(w) / grd_curscreen->sc_aspect;
3936
3937                 dx = (win==0)?-(w+(w/10)):(w/10);
3938
3939                 window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3940                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3941
3942         #ifdef WINDOWS
3943                 saved_window_x = window_x;
3944                 saved_window_y = window_y;
3945                 window_x = dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w/2+dx;
3946                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10)-dd_VR_render_sub_buffer[0].yoff;
3947         #endif
3948
3949                 #ifdef MACINTOSH
3950                 if (Scanline_double) {
3951                         window_x = (VR_render_buffer[0].cv_bitmap.bm_w/2+VR_render_sub_buffer[0].cv_bitmap.bm_x)/2+dx;
3952                         window_y = ((VR_render_buffer[0].cv_bitmap.bm_h+VR_render_sub_buffer[0].cv_bitmap.bm_y)/2)-h-(h/10);
3953                 }
3954                 #endif
3955
3956                 //copy these vars so stereo code can get at them
3957                 SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3958
3959         WINDOS(
3960                 dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,w,h),
3961                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],window_x,window_y,w,h)
3962         );
3963         }
3964         else {
3965                 if (Cockpit_mode == CM_FULL_COCKPIT)
3966                         boxnum = (COCKPIT_PRIMARY_BOX)+win;
3967                 else if (Cockpit_mode == CM_STATUS_BAR)
3968                         boxnum = (SB_PRIMARY_BOX)+win;
3969                 else
3970                         goto abort;
3971
3972                 box = &gauge_boxes[boxnum];
3973
3974                 #ifndef MACINTOSH
3975         WINDOS(                                                           
3976                 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),
3977                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1)
3978         );
3979                 #else
3980                 if (Scanline_double)
3981                         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);
3982                 else
3983                         gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1);
3984                 #endif
3985         }
3986
3987 WINDOS(
3988         dd_gr_set_current_canvas(&window_canv),
3989         gr_set_current_canvas(&window_canv)
3990 );
3991         
3992         #if defined(MACINTOSH) && defined(POLY_ACC)
3993         if ( PAEnabled )
3994         {
3995                 switch (Cockpit_mode)
3996                 {
3997                 // copy these vars so stereo code can get at them
3998                 // SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3999                         case CM_FULL_SCREEN:
4000                                 ;       // do not switch contexts
4001                                 pa_set_3d_window_offsets(window_x, window_y);
4002                                 break;
4003                         case CM_FULL_COCKPIT:
4004                         case CM_STATUS_BAR:
4005                                 if (win == 0)
4006                                 {
4007                                         pa_set_context(kSubViewZeroDrawContextID, NULL);
4008                                 }
4009                                 else
4010                                 {
4011                                         pa_set_context(kSubViewOneDrawContextID, NULL);
4012                                 }
4013                                 break;
4014                         default:
4015                                 Int3(); // invalid cockpit mode
4016                 };
4017         }
4018         #endif
4019
4020         WIN(DDGRLOCK(dd_grd_curcanv));
4021         
4022                 #ifdef MACINTOSH
4023                         #ifdef POLY_ACC
4024                                 if (PAEnabled)
4025                                 {
4026                                         if (Cockpit_mode != CM_FULL_SCREEN)
4027                                         {
4028                                                 pa_render_start();
4029                                         }
4030                                 }
4031                         #endif
4032                 #endif 
4033                 
4034                 render_frame(0, win+1);
4035                 
4036                 #ifdef MACINTOSH
4037                         #ifdef POLY_ACC
4038                                 if (PAEnabled)
4039                                 {
4040                                         if (Cockpit_mode != CM_FULL_SCREEN)
4041                                         {
4042                                                 pa_render_end();
4043                                         }
4044                                 }
4045                         #endif
4046                 #endif 
4047
4048         WIN(DDGRUNLOCK(dd_grd_curcanv));
4049
4050         //      HACK! If guided missile, wake up robots as necessary.
4051         if (viewer->type == OBJ_WEAPON) {
4052                 // -- Used to require to be GUIDED -- if (viewer->id == GUIDEDMISS_ID)
4053                 wake_up_rendered_objects(viewer, win+1);
4054         }
4055
4056         if (label) {
4057         WIN(DDGRLOCK(dd_grd_curcanv));
4058         MAC(if (Scanline_double) FontHires = 0;)                // get the right font size
4059                 gr_set_curfont( GAME_FONT );
4060                 if (Color_0_31_0 == -1)
4061                         Color_0_31_0 = gr_getcolor(0,31,0);
4062                 gr_set_fontcolor(Color_0_31_0, -1);
4063                 gr_printf(0x8000,2,label);
4064         MAC(if (Scanline_double) FontHires = 1;)                // get the right font size back to normal
4065         WIN(DDGRUNLOCK(dd_grd_curcanv));
4066         }
4067
4068         if (user == WBU_GUIDED) {
4069         WIN(DDGRLOCK(dd_grd_curcanv));
4070                 draw_guided_crosshair();
4071         WIN(DDGRUNLOCK(dd_grd_curcanv));
4072         }
4073
4074         if (Cockpit_mode == CM_FULL_SCREEN) {
4075                 int small_window_bottom,big_window_bottom,extra_part_h;
4076                 
4077                 WIN(DDGRLOCK(dd_grd_curcanv));
4078                 {
4079                         gr_setcolor(BM_XRGB(0,0,32));
4080                         gr_ubox(0,0,grd_curcanv->cv_bitmap.bm_w-1,grd_curcanv->cv_bitmap.bm_h-1);
4081                 }
4082                 WIN(DDGRUNLOCK(dd_grd_curcanv));
4083
4084                 //if the window only partially overlaps the big 3d window, copy
4085                 //the extra part to the visible screen
4086
4087                 #ifdef MACINTOSH                // recalc window_x and window_y because of scanline doubling problems
4088                 {
4089                         int w, h, dx;
4090                         
4091                         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
4092                         h = i2f(w) / grd_curscreen->sc_aspect;
4093                         dx = (win==0)?-(w+(w/10)):(w/10);
4094                         window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
4095                         window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
4096                         if (Scanline_double)
4097                                 window_x += ((win==0)?2:-1);            // a real hack here....
4098                 }
4099                 #endif
4100                 big_window_bottom = Game_window_y + Game_window_h - 1;
4101
4102         #ifdef WINDOWS
4103                 window_x = saved_window_x;
4104                 window_y = saved_window_y;
4105 //              dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,
4106 //                                              VR_render_buffer[0].cv_bitmap.bm_w/6,
4107 //                                              i2f(VR_render_buffer[0].cv_bitmap.bm_w/6) / grd_curscreen->sc_aspect);
4108
4109         #endif
4110
4111                 if (window_y > big_window_bottom) {
4112
4113                         //the small window is completely outside the big 3d window, so
4114                         //copy it to the visible screen
4115
4116                         if (VR_screen_flags & VRF_USE_PAGING)
4117                                 WINDOS(
4118                                         dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
4119                                         gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
4120                                 );
4121                         else
4122                                 WINDOS(
4123                                         dd_gr_set_current_canvas(get_current_game_screen()),
4124                                         gr_set_current_canvas(get_current_game_screen())
4125                                 );
4126
4127                         #ifdef MACINTOSH
4128                         if (Scanline_double)
4129                                 gr_bm_ubitblt_double_slow(window_canv.cv_bitmap.bm_w*2, window_canv.cv_bitmap.bm_h*2, window_x, window_y, 0, 0, &window_canv.cv_bitmap, &grd_curcanv->cv_bitmap);
4130                         else
4131                         #endif          // note link to above if
4132                         WINDOS(
4133                                 dd_gr_blt_notrans(&window_canv, 0,0,0,0,
4134                                                                                 dd_grd_curcanv, window_x, window_y, 0,0),
4135                                 gr_bitmap(window_x,window_y,&window_canv.cv_bitmap)
4136                         );
4137
4138                         overlap_dirty[win] = 1;
4139                 }
4140                 else {
4141
4142                 WINDOS(
4143                         small_window_bottom = window_y + window_canv.canvas.cv_bitmap.bm_h - 1,
4144                         small_window_bottom = window_y + window_canv.cv_bitmap.bm_h - 1
4145                 );
4146                         #ifdef MACINTOSH
4147                         if (Scanline_double)
4148                                 small_window_bottom = window_y + (window_canv.cv_bitmap.bm_h*2) - 1;
4149                         #endif
4150                         
4151                         extra_part_h = small_window_bottom - big_window_bottom;
4152
4153                         if (extra_part_h > 0) {
4154                         
4155                                 #ifdef MACINTOSH
4156                                 if (Scanline_double)
4157                                         extra_part_h /= 2;
4158                                 #endif
4159         
4160                                 WINDOS(
4161                                         dd_gr_init_sub_canvas(&overlap_canv,&window_canv,0,
4162                                                 window_canv.canvas.cv_bitmap.bm_h-extra_part_h,
4163                                                 window_canv.canvas.cv_bitmap.bm_w,extra_part_h),
4164                                         gr_init_sub_canvas(&overlap_canv,&window_canv,0,window_canv.cv_bitmap.bm_h-extra_part_h,window_canv.cv_bitmap.bm_w,extra_part_h)
4165                                 );
4166
4167                                 if (VR_screen_flags & VRF_USE_PAGING)
4168                                         WINDOS(
4169                                                 dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
4170                                                 gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
4171                                         );
4172                                 else
4173                                         WINDOS(
4174                                                 dd_gr_set_current_canvas(get_current_game_screen()),
4175                                                 gr_set_current_canvas(get_current_game_screen())
4176                                         );
4177
4178                                 #ifdef MACINTOSH
4179                                 if (Scanline_double)
4180                                         gr_bm_ubitblt_double_slow(window_canv.cv_bitmap.bm_w*2, extra_part_h*2, window_x, big_window_bottom+1, 0, window_canv.cv_bitmap.bm_h-extra_part_h, &window_canv.cv_bitmap, &grd_curcanv->cv_bitmap);
4181                                 else
4182                                 #endif          // note link to above if
4183                                 WINDOS(
4184                                         dd_gr_blt_notrans(&overlap_canv, 0,0,0,0,
4185                                                                                         dd_grd_curcanv, window_x, big_window_bottom+1, 0,0),
4186                                         gr_bitmap(window_x,big_window_bottom+1,&overlap_canv.cv_bitmap)
4187                                 );
4188                                 
4189                                 overlap_dirty[win] = 1;
4190                         }
4191                 }
4192         }
4193         else {
4194         PA_DFX (goto skip_this_junk);
4195         
4196         WINDOS(
4197                 dd_gr_set_current_canvas(get_current_game_screen()),
4198                 gr_set_current_canvas(get_current_game_screen())
4199         );
4200         #ifndef MACINTOSH
4201         WINDOS(
4202                 copy_gauge_box(box,&dd_VR_render_buffer[0]),
4203                 copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap)
4204         );
4205         #else
4206         if (Scanline_double)
4207                 copy_gauge_box_double(box,&VR_render_buffer[0].cv_bitmap);              // pixel double the external view
4208         else
4209                 // Only do this if we are not running under RAVE, otherwise we erase all of the rendering RAVE has done.
4210                 if (!PAEnabled)
4211                 {
4212                         copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap);
4213                 }
4214         #endif
4215         }
4216
4217   PA_DFX(skip_this_junk:)
4218   
4219         #if defined(MACINTOSH) && defined(POLY_ACC)
4220         if ( PAEnabled )
4221         {
4222                 pa_set_context(kGamePlayDrawContextID, NULL);
4223         }
4224         #endif
4225
4226         //force redraw when done
4227         old_weapon[win][VR_current_page] = old_ammo_count[win][VR_current_page] = -1;
4228
4229 abort:;
4230
4231         Viewer = viewer_save;
4232
4233         Rear_view = rear_view_save;
4234 }
4235
4236 #ifdef MACINTOSH
4237         void calculate_sub_view_window_bounds(int inSubWindowNum, TQARect* outBoundsRect)
4238         {
4239                 int             boxNumber               = 0;
4240                 gauge_box*      currentGaugeBox = NULL;
4241                 int w   = 0;
4242                 int h   = 0;
4243                 int dx  = 0;
4244                 int window_x = 0;
4245                 int window_y = 0;
4246
4247                 Assert(outBoundsRect);
4248                 Assert((inSubWindowNum == 0) || (inSubWindowNum == 1));
4249                 Assert(!Scanline_double);
4250                 
4251                 switch (Cockpit_mode)
4252                 {
4253                         case CM_FULL_SCREEN:
4254                                 // note: this calculation is taken from do_cockpit_window_view for the full
4255                                 // screen mode case
4256                 
4257                                 w = (VR_render_buffer[0].cv_bitmap.bm_w) / 6;
4258                                 h = (i2f(w)) / (grd_curscreen->sc_aspect);
4259                 
4260                                 dx = (inSubWindowNum==0)?-(w+(w/10)):(w/10);
4261                 
4262                                 window_x = ((VR_render_buffer[0].cv_bitmap.bm_w) / 2) + dx;
4263                                 window_y = (VR_render_buffer[0].cv_bitmap.bm_h) - h - (h/10);
4264                                 
4265                                 outBoundsRect->top              = window_x;
4266                                 outBoundsRect->left             = window_y;
4267                                 outBoundsRect->bottom   = window_x + w;
4268                                 outBoundsRect->right    = window_y + h;
4269                                 break;
4270         
4271                         case CM_FULL_COCKPIT:
4272                         case CM_STATUS_BAR:
4273                                 if (inSubWindowNum == 0)
4274                                 {
4275                                         boxNumber = SB_PRIMARY_BOX;
4276                                 }
4277                                 else
4278                                 {
4279                                         boxNumber = SB_SECONDARY_BOX;
4280                                 }
4281                                 
4282                                 //boxNumber = (Current_display_mode * 4) + (Cockpit_mode * 2) + inSubWindowNum;
4283                                 currentGaugeBox = &gauge_boxes[boxNumber];
4284                                 Assert(currentGaugeBox);
4285                                 
4286                                 outBoundsRect->top              = currentGaugeBox->top;
4287                                 outBoundsRect->left             = currentGaugeBox->left;
4288                                 outBoundsRect->bottom   = currentGaugeBox->bot + 1;
4289                                 outBoundsRect->right    = currentGaugeBox->right + 1;
4290                                 
4291                                 break;
4292         
4293                         default:
4294                                 Int3();
4295                                 return;
4296                 }
4297         }
4298
4299 #endif
4300
4301