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