Got rid of all compiler warnings, for non-OpenGL on linux, anyway...
[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         char    score_str[20];
987         int     w, h, aw,i;
988         fix timevar=0;
989
990         if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
991                 return;
992
993 #ifdef NETWORK
994    if ((Game_mode & GM_NETWORK) && Netgame.PlayTimeAllowed)
995     {
996      timevar=i2f (Netgame.PlayTimeAllowed*5*60);
997      i=f2i(timevar-ThisLevelTime);
998      i++;
999     
1000      sprintf(score_str, "T - %5d", i);
1001                                                                                                                                                                                                  
1002      gr_get_string_size(score_str, &w, &h, &aw );
1003
1004      if (Color_0_31_0 == -1)
1005                 Color_0_31_0 = gr_getcolor(0,31,0);
1006      gr_set_fontcolor(Color_0_31_0, -1);
1007
1008      if (i>-1 && !Control_center_destroyed)
1009              gr_printf(grd_curcanv->cv_w-w-LHX(10), LHX(11), score_str);
1010     }
1011 #endif
1012  }
1013
1014
1015 //y offset between lines on HUD
1016 int Line_spacing;
1017
1018 void hud_show_score_added()
1019 {
1020         int     color;
1021         int     w, h, aw;
1022         char    score_str[20];
1023
1024         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1025                 return;
1026
1027         if (score_display[0] == 0)
1028                 return;
1029
1030         gr_set_curfont( GAME_FONT );
1031
1032         score_time -= FrameTime;
1033         if (score_time > 0) {
1034                 color = f2i(score_time * 20) + 12;
1035
1036                 if (color < 10) color = 12;
1037                 if (color > 31) color = 30;
1038
1039                 color = color - (color % 4);    //      Only allowing colors 12,16,20,24,28 speeds up gr_getcolor, improves caching
1040
1041                 if (Cheats_enabled)
1042                         sprintf(score_str, "%s", TXT_CHEATER);
1043                 else
1044                         sprintf(score_str, "%5d", score_display[0]);
1045
1046                 gr_get_string_size(score_str, &w, &h, &aw );
1047                 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
1048                 gr_printf(grd_curcanv->cv_w-w-LHX(2+10), Line_spacing+4, score_str);
1049         } else {
1050                 score_time = 0;
1051                 score_display[0] = 0;
1052         }
1053         
1054 }
1055
1056 void sb_show_score()
1057 {                                                                                                                                                                                                                                                                    
1058         char    score_str[20];
1059         int x,y;
1060         int     w, h, aw;
1061         static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1062         int redraw_score;
1063
1064 WIN(DDGRLOCK(dd_grd_curcanv));
1065         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1066                 redraw_score = -99;
1067         else
1068                 redraw_score = -1;
1069
1070         if (old_score[VR_current_page]==redraw_score) {
1071                 gr_set_curfont( GAME_FONT );
1072                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1073
1074                 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1075                         {
1076                          PA_DFX(pa_set_frontbuffer_current()); 
1077           PA_DFX(gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS)); 
1078           PA_DFX(pa_set_backbuffer_current()); 
1079                          gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS);
1080                         }
1081                 else
1082                   {
1083                    PA_DFX (pa_set_frontbuffer_current() );
1084                         PA_DFX (gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE) );
1085          PA_DFX(pa_set_backbuffer_current()); 
1086                         gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE);
1087                   }
1088         }
1089
1090         gr_set_curfont( GAME_FONT );
1091         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1092                 sprintf(score_str, "%5d", Players[Player_num].net_kills_total);
1093         else
1094                 sprintf(score_str, "%5d", Players[Player_num].score);
1095         gr_get_string_size(score_str, &w, &h, &aw );
1096
1097         x = SB_SCORE_RIGHT-w-LHX(2);
1098         y = SB_SCORE_Y;
1099         
1100         //erase old score
1101         gr_setcolor(BM_XRGB(0,0,0));
1102    PA_DFX (pa_set_frontbuffer_current());
1103         PA_DFX (gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h));
1104    PA_DFX(pa_set_backbuffer_current()); 
1105         gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h);
1106
1107         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1108                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1109         else
1110                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );      
1111  
1112    PA_DFX (pa_set_frontbuffer_current());
1113         PA_DFX (gr_printf(x,y,score_str));
1114    PA_DFX(pa_set_backbuffer_current()); 
1115         gr_printf(x,y,score_str);
1116
1117         last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1118 WIN(DDGRUNLOCK(dd_grd_curcanv));
1119 }
1120
1121 void sb_show_score_added()
1122 {
1123         int     color;
1124         int w, h, aw;
1125         char    score_str[32];
1126         int x;
1127         static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1128         static  int last_score_display[2] = { -1, -1};
1129    int frc=0;
1130         PA_DFX (frc=0);
1131         
1132         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1133                 return;
1134
1135         if (score_display[VR_current_page] == 0)
1136                 return;
1137
1138 WIN(DDGRLOCK(dd_grd_curcanv));
1139         gr_set_curfont( GAME_FONT );
1140
1141         score_time -= FrameTime;
1142         if (score_time > 0) {
1143                 if (score_display[VR_current_page] != last_score_display[VR_current_page] || frc) {
1144                         gr_setcolor(BM_XRGB(0,0,0));
1145                         PA_DFX (pa_set_frontbuffer_current());
1146                         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));
1147                    PA_DFX(pa_set_backbuffer_current()); 
1148                         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
1150                         last_score_display[VR_current_page] = score_display[VR_current_page];
1151                 }
1152
1153                 color = f2i(score_time * 20) + 10;
1154
1155                 if (color < 10) color = 10;
1156                 if (color > 31) color = 31;
1157
1158                 if (Cheats_enabled)
1159                         sprintf(score_str, "%s", TXT_CHEATER);
1160                 else
1161                         sprintf(score_str, "%5d", score_display[VR_current_page]);
1162
1163                 gr_get_string_size(score_str, &w, &h, &aw );
1164
1165                 x = SB_SCORE_ADDED_RIGHT-w-LHX(2);
1166
1167                 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
1168
1169                 PA_DFX (pa_set_frontbuffer_current());
1170                 PA_DFX (gr_printf(x, SB_SCORE_ADDED_Y, score_str));
1171       PA_DFX(pa_set_backbuffer_current()); 
1172                 gr_printf(x, SB_SCORE_ADDED_Y, score_str);
1173
1174
1175                 last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1176
1177         } else {
1178                 //erase old score
1179                 gr_setcolor(BM_XRGB(0,0,0));
1180                 PA_DFX (pa_set_frontbuffer_current());
1181                 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));
1182            PA_DFX(pa_set_backbuffer_current()); 
1183                 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
1185                 score_time = 0;
1186                 score_display[VR_current_page] = 0;
1187
1188         }
1189 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1190 }
1191
1192 fix     Last_warning_beep_time[2] = {0,0};              //      Time we last played homing missile warning beep.
1193
1194 //      -----------------------------------------------------------------------------
1195 void play_homing_warning(void)
1196 {
1197         fix     beep_delay;
1198
1199         if (Endlevel_sequence || Player_is_dead)
1200                 return;
1201
1202         if (Players[Player_num].homing_object_dist >= 0) {
1203                 beep_delay = Players[Player_num].homing_object_dist/128;
1204                 if (beep_delay > F1_0)
1205                         beep_delay = F1_0;
1206                 else if (beep_delay < F1_0/8)
1207                         beep_delay = F1_0/8;
1208
1209                 if (Last_warning_beep_time[VR_current_page] > GameTime)
1210                         Last_warning_beep_time[VR_current_page] = 0;
1211
1212                 if (GameTime - Last_warning_beep_time[VR_current_page] > beep_delay/2) {
1213                         digi_play_sample( SOUND_HOMING_WARNING, F1_0 );
1214                         Last_warning_beep_time[VR_current_page] = GameTime;
1215                 }
1216         }
1217 }
1218
1219 int     Last_homing_warning_shown[2]={-1,-1};
1220
1221 //      -----------------------------------------------------------------------------
1222 void show_homing_warning(void)
1223 {
1224         if ((Cockpit_mode == CM_STATUS_BAR) || (Endlevel_sequence)) {
1225                 if (Last_homing_warning_shown[VR_current_page] == 1) {
1226                         PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1227
1228                         WIN(DDGRLOCK(dd_grd_curcanv));
1229                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1230                         WIN(DDGRUNLOCK(dd_grd_curcanv));
1231
1232                         Last_homing_warning_shown[VR_current_page] = 0;
1233                 }
1234                 return;
1235         }
1236
1237         WINDOS(
1238                 dd_gr_set_current_canvas( get_current_game_screen() ),
1239                 gr_set_current_canvas( get_current_game_screen() )
1240         );
1241
1242
1243 WIN(DDGRLOCK(dd_grd_curcanv))
1244 {
1245         if (Players[Player_num].homing_object_dist >= 0) {
1246
1247                 if (GameTime & 0x4000) {
1248                         if (Last_homing_warning_shown[VR_current_page] != 1) {
1249                                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_ON );
1250                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_ON) ] );
1251                                 Last_homing_warning_shown[VR_current_page] = 1;
1252                         }
1253                 } else {
1254                         if (Last_homing_warning_shown[VR_current_page] != 0) {
1255                                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1256                                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1257                                 Last_homing_warning_shown[VR_current_page] = 0;
1258                         }
1259                 }
1260         } else if (Last_homing_warning_shown[VR_current_page] != 0) {
1261                 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1262                 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1263                 Last_homing_warning_shown[VR_current_page] = 0;
1264         }
1265 }
1266 WIN(DDGRUNLOCK(dd_grd_curcanv));
1267
1268 }
1269
1270 #define MAX_SHOWN_LIVES 4
1271
1272 extern int Game_window_y;
1273 extern int SW_y[2];
1274
1275 void hud_show_homing_warning(void)
1276 {
1277         if (Players[Player_num].homing_object_dist >= 0) {
1278                 if (GameTime & 0x4000) {
1279                         int x=0x8000, y=grd_curcanv->cv_h-Line_spacing;
1280
1281                         if (weapon_box_user[0] != WBU_WEAPON || weapon_box_user[1] != WBU_WEAPON) {
1282                                 int wy = (weapon_box_user[0] != WBU_WEAPON)?SW_y[0]:SW_y[1];
1283                                 y = min(y,(wy - Line_spacing - Game_window_y));
1284                         }
1285
1286                         gr_set_curfont( GAME_FONT );
1287                         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1288                         gr_printf(x,y,TXT_LOCK);
1289                 }
1290         }
1291 }
1292
1293 void hud_show_keys(void)
1294 {
1295         int y = 3*Line_spacing;
1296         int dx = GAME_FONT->ft_w+GAME_FONT->ft_w/2;
1297
1298         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY) {
1299                 PAGE_IN_GAUGE( KEY_ICON_BLUE );
1300                 gr_ubitmapm(2,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_BLUE) ] );
1301
1302         }
1303
1304         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY) {
1305                 PAGE_IN_GAUGE( KEY_ICON_YELLOW );
1306                 gr_ubitmapm(2+dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_YELLOW) ] );
1307         }
1308
1309         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY) {
1310                 PAGE_IN_GAUGE( KEY_ICON_RED );
1311                 gr_ubitmapm(2+2*dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_RED) ] );
1312         }
1313
1314 }
1315
1316 #ifdef NETWORK
1317 extern grs_bitmap Orb_icons[2];
1318
1319 void hud_show_orbs (void)
1320 {
1321         if (Game_mode & GM_HOARD) {
1322                 int x,y;
1323                 grs_bitmap *bm;
1324
1325                 x=y=0;
1326
1327                 if (Cockpit_mode == CM_FULL_COCKPIT) {
1328                         y = 2*Line_spacing;
1329                         x = 4*GAME_FONT->ft_w;
1330                 }
1331                 else if (Cockpit_mode == CM_STATUS_BAR) {
1332                         y = Line_spacing;
1333                         x = GAME_FONT->ft_w;
1334                 }
1335                 else if (Cockpit_mode == CM_FULL_SCREEN) {
1336                         y = 5*Line_spacing;
1337                         x = GAME_FONT->ft_w;
1338                         if (FontHires)
1339                                 y += Line_spacing;
1340                 }
1341                 else
1342                         Int3();         //what sort of cockpit?
1343
1344                 bm = &Orb_icons[FontHires];
1345                 gr_ubitmapm(x,y,bm);
1346
1347                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1348                 gr_printf(x+bm->bm_w+bm->bm_w/2, y+(FontHires?2:1), "x %d", Players[Player_num].secondary_ammo[PROXIMITY_INDEX]);
1349
1350         }
1351 }
1352
1353 void hud_show_flag(void)
1354 {
1355         if ((Game_mode & GM_CAPTURE) && (Players[Player_num].flags & PLAYER_FLAGS_FLAG)) {
1356                 int x,y,icon;
1357
1358                 x=y=0;
1359
1360                 if (Cockpit_mode == CM_FULL_COCKPIT) {
1361                         y = 2*Line_spacing;
1362                         x = 4*GAME_FONT->ft_w;
1363                 }
1364                 else if (Cockpit_mode == CM_STATUS_BAR) {
1365                         y = Line_spacing;
1366                         x = GAME_FONT->ft_w;
1367                 }
1368                 else if (Cockpit_mode == CM_FULL_SCREEN) {
1369                         y = 5*Line_spacing;
1370                         x = GAME_FONT->ft_w;
1371                         if (FontHires)
1372                                 y += Line_spacing;
1373                 }
1374                 else
1375                         Int3();         //what sort of cockpit?
1376
1377
1378                 icon = (get_team(Player_num) == TEAM_BLUE)?FLAG_ICON_RED:FLAG_ICON_BLUE;
1379
1380                 PAGE_IN_GAUGE( icon );
1381                 gr_ubitmapm(x,y,&GameBitmaps[ GET_GAUGE_INDEX(icon) ] );
1382
1383         }
1384 }
1385 #endif
1386
1387 void hud_show_energy(void)
1388 {
1389         //gr_set_current_canvas(&VR_render_sub_buffer[0]);      //render off-screen
1390         gr_set_curfont( GAME_FONT );
1391         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1392         if (Game_mode & GM_MULTI)
1393                 gr_printf(2, grd_curcanv->cv_h-5*Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1394         else
1395                 gr_printf(2, grd_curcanv->cv_h-Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1396
1397         if (Newdemo_state==ND_STATE_RECORDING ) {
1398                 int energy = f2ir(Players[Player_num].energy);
1399
1400                 if (energy != old_energy[VR_current_page]) {
1401                         newdemo_record_player_energy(old_energy[VR_current_page], energy);
1402                         old_energy[VR_current_page] = energy;
1403                 }
1404         }
1405 }
1406
1407 void hud_show_afterburner(void)
1408 {
1409         int y;
1410
1411         if (! (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER))
1412                 return;         //don't draw if don't have
1413
1414         gr_set_curfont( GAME_FONT );
1415         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1416
1417         y = (Game_mode & GM_MULTI)?(-8*Line_spacing):(-3*Line_spacing);
1418
1419         gr_printf(2, grd_curcanv->cv_h+y, "burn: %d%%" , fixmul(Afterburner_charge,100));
1420
1421         if (Newdemo_state==ND_STATE_RECORDING ) {
1422
1423                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
1424                         newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
1425                         old_afterburner[VR_current_page] = Afterburner_charge;
1426                 }
1427         }
1428 }
1429
1430 char *d2_very_short_secondary_weapon_names[] =
1431                 {"Flash","Guided","SmrtMine","Mercury","Shaker"};
1432
1433 #define SECONDARY_WEAPON_NAMES_VERY_SHORT(weapon_num)                                   \
1434         ((weapon_num <= MEGA_INDEX)?(*(&TXT_CONCUSSION + (weapon_num))):        \
1435         d2_very_short_secondary_weapon_names[weapon_num-SMISSILE1_INDEX])
1436
1437 //return which bomb will be dropped next time the bomb key is pressed
1438 extern int which_bomb();
1439
1440 void show_bomb_count(int x,int y,int bg_color,int always_show)
1441 {
1442         int bomb,count,countx;
1443         char txt[5],*t;
1444
1445         bomb = which_bomb();
1446         count = Players[Player_num].secondary_ammo[bomb];
1447
1448         #ifndef RELEASE
1449         count = min(count,99);  //only have room for 2 digits - cheating give 200
1450         #endif
1451
1452         countx = (bomb==PROXIMITY_INDEX)?count:-count;
1453
1454         if (always_show && count == 0)          //no bombs, draw nothing on HUD
1455                 return;
1456
1457         if (!always_show && countx == old_bombcount[VR_current_page])
1458                 return;
1459
1460 WIN(DDGRLOCK(dd_grd_curcanv));
1461
1462 // I hate doing this off of hard coded coords!!!!
1463
1464         if (Cockpit_mode == CM_STATUS_BAR) {            //draw background
1465                 gr_setcolor(bg_color);
1466                 if (!Current_display_mode) {
1467                         gr_rect(169,189,189,196);
1468                         gr_setcolor(gr_find_closest_color(10,10,10));
1469                         gr_scanline(168,189,189);
1470                 } else {
1471                         PA_DFX (pa_set_frontbuffer_current());
1472                         PA_DFX (gr_rect(338,453,378,470));
1473          PA_DFX(pa_set_backbuffer_current()); 
1474                         gr_rect(338,453,378,470);
1475
1476                         gr_setcolor(gr_find_closest_color(10,10,10));
1477                         PA_DFX (pa_set_frontbuffer_current());
1478                         PA_DFX (gr_scanline(336,378,453));
1479          PA_DFX(pa_set_backbuffer_current()); 
1480                         gr_scanline(336,378,453);
1481                 }
1482         }
1483
1484         if (count)
1485                 gr_set_fontcolor((bomb==PROXIMITY_INDEX)?gr_find_closest_color(55,0,0):gr_getcolor(59,50,21),bg_color);
1486         else
1487                 gr_set_fontcolor(bg_color,bg_color);    //erase by drawing in background color
1488
1489         sprintf(txt,"B:%02d",count);
1490
1491         while ((t=strchr(txt,'1')) != NULL)
1492                 *t = '\x84';    //convert to wide '1'
1493
1494         PA_DFX (pa_set_frontbuffer_current());
1495         PA_DFX (gr_string(x,y,txt));
1496    PA_DFX(pa_set_backbuffer_current()); 
1497         gr_string(x,y,txt);
1498
1499 WIN(DDGRUNLOCK(dd_grd_curcanv));
1500
1501         old_bombcount[VR_current_page] = countx;
1502 }
1503
1504 void draw_primary_ammo_info(int ammo_count)
1505 {
1506         if (Cockpit_mode == CM_STATUS_BAR)
1507                 draw_ammo_info(SB_PRIMARY_AMMO_X,SB_PRIMARY_AMMO_Y,ammo_count,1);
1508         else
1509                 draw_ammo_info(PRIMARY_AMMO_X,PRIMARY_AMMO_Y,ammo_count,1);
1510 }
1511
1512 //convert '1' characters to special wide ones
1513 #define convert_1s(s) do {char *p=s; while ((p=strchr(p,'1')) != NULL) *p=132;} while(0)
1514
1515 void hud_show_weapons(void)
1516 {
1517         int     w, h, aw;
1518         int     y;
1519         char    *weapon_name;
1520         char    weapon_str[32];
1521
1522 //      gr_set_current_canvas(&VR_render_sub_buffer[0]);        //render off-screen
1523         gr_set_curfont( GAME_FONT );
1524         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1525
1526         y = grd_curcanv->cv_h;
1527
1528         if (Game_mode & GM_MULTI)
1529                 y -= 4*Line_spacing;
1530
1531         weapon_name = PRIMARY_WEAPON_NAMES_SHORT(Primary_weapon);
1532
1533         switch (Primary_weapon) {
1534                 case LASER_INDEX:
1535                         if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)
1536                                 sprintf(weapon_str, "%s %s %i", TXT_QUAD, weapon_name, Players[Player_num].laser_level+1);
1537                         else
1538                                 sprintf(weapon_str, "%s %i", weapon_name, Players[Player_num].laser_level+1);
1539                         break;
1540
1541                 case SUPER_LASER_INDEX: Int3(); break;  //no such thing as super laser
1542
1543                 case VULCAN_INDEX:              
1544                 case GAUSS_INDEX:                       
1545                         sprintf(weapon_str, "%s: %i", weapon_name, f2i((unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX] * (unsigned) VULCAN_AMMO_SCALE)); 
1546                         convert_1s(weapon_str);
1547                         break;
1548
1549                 case SPREADFIRE_INDEX:
1550                 case PLASMA_INDEX:
1551                 case FUSION_INDEX:
1552                 case HELIX_INDEX:
1553                 case PHOENIX_INDEX:
1554                         strcpy(weapon_str, weapon_name);
1555                         break;
1556                 case OMEGA_INDEX:
1557                         sprintf(weapon_str, "%s: %03i", weapon_name, Omega_charge * 100/MAX_OMEGA_CHARGE);
1558                         convert_1s(weapon_str);
1559                         break;
1560
1561                 default:                                                Int3(); weapon_str[0] = 0;      break;
1562         }
1563
1564         gr_get_string_size(weapon_str, &w, &h, &aw );
1565         gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-2*Line_spacing, weapon_str);
1566
1567         if (Primary_weapon == VULCAN_INDEX) {
1568                 if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0][VR_current_page]) {
1569                         if (Newdemo_state == ND_STATE_RECORDING)
1570                                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[Primary_weapon]);
1571                         old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[Primary_weapon];
1572                 }
1573         }
1574
1575         if (Primary_weapon == OMEGA_INDEX) {
1576                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
1577                         if (Newdemo_state == ND_STATE_RECORDING)
1578                                 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
1579                         Old_Omega_charge[VR_current_page] = Omega_charge;
1580                 }
1581         }
1582
1583         weapon_name = SECONDARY_WEAPON_NAMES_VERY_SHORT(Secondary_weapon);
1584
1585         sprintf(weapon_str, "%s %d",weapon_name,Players[Player_num].secondary_ammo[Secondary_weapon]);
1586         gr_get_string_size(weapon_str, &w, &h, &aw );
1587         gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-Line_spacing, weapon_str);
1588
1589         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
1590                 if (Newdemo_state == ND_STATE_RECORDING)
1591                         newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
1592                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
1593         }
1594
1595         show_bomb_count(grd_curcanv->cv_bitmap.bm_w-(3*GAME_FONT->ft_w+(FontHires?0:2)), y-3*Line_spacing,-1,1);
1596 }
1597
1598 void hud_show_cloak_invuln(void)
1599 {
1600         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1601
1602         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
1603                 int     y = grd_curcanv->cv_h;
1604
1605                 if (Game_mode & GM_MULTI)
1606                         y -= 7*Line_spacing;
1607                 else
1608                         y -= 4*Line_spacing;
1609
1610                 if ((Players[Player_num].cloak_time+CLOAK_TIME_MAX - GameTime > F1_0*3 ) || (GameTime & 0x8000))
1611                         gr_printf(2, y, "%s", TXT_CLOAKED);
1612         }
1613
1614         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
1615                 int     y = grd_curcanv->cv_h;
1616
1617                 if (Game_mode & GM_MULTI)
1618                         y -= 10*Line_spacing;
1619                 else
1620                         y -= 5*Line_spacing;
1621
1622                 if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000))
1623                         gr_printf(2, y, "%s", TXT_INVULNERABLE);
1624         }
1625
1626 }
1627
1628 void hud_show_shield(void)
1629 {
1630 //      gr_set_current_canvas(&VR_render_sub_buffer[0]);        //render off-screen
1631         gr_set_curfont( GAME_FONT );
1632         gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1633
1634         if ( Players[Player_num].shields >= 0 ) {
1635                 if (Game_mode & GM_MULTI)
1636                         gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1637                 else
1638                         gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1639         } else {
1640                 if (Game_mode & GM_MULTI)
1641                         gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: 0", TXT_SHIELD );
1642                 else
1643                         gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: 0", TXT_SHIELD );
1644         }
1645
1646         if (Newdemo_state==ND_STATE_RECORDING ) {
1647                 int shields = f2ir(Players[Player_num].shields);
1648
1649                 if (shields != old_shields[VR_current_page]) {          // Draw the shield gauge
1650                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
1651                         old_shields[VR_current_page] = shields;
1652                 }
1653         }
1654 }
1655
1656 //draw the icons for number of lives
1657 void hud_show_lives()
1658 {
1659         if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
1660                 return;
1661
1662         if (Game_mode & GM_MULTI) {
1663                 gr_set_curfont( GAME_FONT );
1664                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1665                 gr_printf(10, 3, "%s: %d", TXT_DEATHS, Players[Player_num].net_killed_total);
1666         } 
1667         else if (Players[Player_num].lives > 1)  {
1668                 grs_bitmap *bm;
1669                 gr_set_curfont( GAME_FONT );
1670                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1671                 PAGE_IN_GAUGE( GAUGE_LIVES );
1672                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1673                 gr_ubitmapm(10,3,bm);
1674                 gr_printf(10+bm->bm_w+bm->bm_w/2, 4, "x %d", Players[Player_num].lives-1);
1675         }
1676
1677 }
1678
1679 void sb_show_lives()
1680 {
1681         int x,y;
1682         grs_bitmap * bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1683    int frc=0;
1684         x = SB_LIVES_X;
1685         y = SB_LIVES_Y;
1686   
1687    PA_DFX (frc=0);
1688
1689         WIN(DDGRLOCK(dd_grd_curcanv));
1690         if (old_lives[VR_current_page]==-1 || frc) {
1691                 gr_set_curfont( GAME_FONT );
1692                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1693                 if (Game_mode & GM_MULTI)
1694                  {
1695                    PA_DFX (pa_set_frontbuffer_current());
1696                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS));
1697                    PA_DFX (pa_set_backbuffer_current());
1698                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS);
1699
1700                  }
1701                 else
1702                   {
1703                    PA_DFX (pa_set_frontbuffer_current());
1704                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES));
1705                    PA_DFX (pa_set_backbuffer_current());
1706                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES);
1707                  }
1708
1709         }
1710 WIN(DDGRUNLOCK(dd_grd_curcanv));
1711
1712         if (Game_mode & GM_MULTI)
1713         {
1714                 char killed_str[20];
1715                 int w, h, aw;
1716                 static int last_x[4] = {SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1717                 int x;
1718
1719         WIN(DDGRLOCK(dd_grd_curcanv));
1720                 sprintf(killed_str, "%5d", Players[Player_num].net_killed_total);
1721                 gr_get_string_size(killed_str, &w, &h, &aw);
1722                 gr_setcolor(BM_XRGB(0,0,0));
1723                 gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page], y+1, SB_SCORE_RIGHT, y+GAME_FONT->ft_h);
1724                 gr_set_fontcolor(gr_getcolor(0,20,0),-1);
1725                 x = SB_SCORE_RIGHT-w-2;         
1726                 gr_printf(x, y+1, killed_str);
1727                 last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1728         WIN(DDGRUNLOCK(dd_grd_curcanv));
1729                 return;
1730         }
1731
1732         if (frc || old_lives[VR_current_page]==-1 || Players[Player_num].lives != old_lives[VR_current_page]) {
1733         WIN(DDGRLOCK(dd_grd_curcanv));
1734
1735                 //erase old icons
1736
1737                 gr_setcolor(BM_XRGB(0,0,0));
1738       
1739       PA_DFX (pa_set_frontbuffer_current());
1740            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
1741       PA_DFX (pa_set_backbuffer_current());
1742            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
1743
1744                 if (Players[Player_num].lives-1 > 0) {
1745                         gr_set_curfont( GAME_FONT );
1746                         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1747                         PAGE_IN_GAUGE( GAUGE_LIVES );
1748                         #ifdef PA_3DFX_VOODOO
1749                       PA_DFX (pa_set_frontbuffer_current());
1750                                 gr_ubitmapm(x, y,bm);
1751                                 gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
1752                         #endif
1753
1754               PA_DFX (pa_set_backbuffer_current());
1755                         gr_ubitmapm(x, y,bm);
1756                         gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
1757
1758 //                      gr_printf(x+12, y, "x %d", Players[Player_num].lives-1);
1759                 }
1760         WIN(DDGRUNLOCK(dd_grd_curcanv));
1761         }
1762
1763 //      for (i=0;i<draw_count;i++,x+=bm->bm_w+2)
1764 //              gr_ubitmapm(x,y,bm);
1765
1766 }
1767
1768 #ifndef RELEASE
1769
1770 #ifdef PIGGY_USE_PAGING
1771 extern int Piggy_bitmap_cache_next;
1772 #endif
1773
1774 void show_time()
1775 {
1776         int secs = f2i(Players[Player_num].time_level) % 60;
1777         int mins = f2i(Players[Player_num].time_level) / 60;
1778
1779         gr_set_curfont( GAME_FONT );
1780
1781         if (Color_0_31_0 == -1)
1782                 Color_0_31_0 = gr_getcolor(0,31,0);
1783         gr_set_fontcolor(Color_0_31_0, -1 );
1784
1785         gr_printf(grd_curcanv->cv_w-4*GAME_FONT->ft_w,grd_curcanv->cv_h-4*Line_spacing,"%d:%02d", mins, secs);
1786
1787 //@@#ifdef PIGGY_USE_PAGING
1788 //@@    {
1789 //@@            char text[25];
1790 //@@            int w,h,aw;
1791 //@@            sprintf( text, "%d KB", Piggy_bitmap_cache_next/1024 );
1792 //@@            gr_get_string_size( text, &w, &h, &aw );        
1793 //@@            gr_printf(grd_curcanv->cv_w-10-w,grd_curcanv->cv_h/2, text );
1794 //@@    }
1795 //@@#endif
1796
1797 }
1798 #endif
1799
1800 #define EXTRA_SHIP_SCORE        50000           //get new ship every this many points
1801
1802 void add_points_to_score(int points) 
1803 {
1804         int prev_score;
1805
1806         score_time += f1_0*2;
1807         score_display[0] += points;
1808         score_display[1] += points;
1809         if (score_time > f1_0*4) score_time = f1_0*4;
1810
1811         if (points == 0 || Cheats_enabled)
1812                 return;
1813
1814         if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
1815                 return;
1816
1817         prev_score=Players[Player_num].score;
1818
1819         Players[Player_num].score += points;
1820
1821         if (Newdemo_state == ND_STATE_RECORDING)
1822                 newdemo_record_player_score(points);
1823
1824 #ifdef NETWORK
1825         if (Game_mode & GM_MULTI_COOP)
1826                 multi_send_score();
1827
1828         if (Game_mode & GM_MULTI)
1829                 return;
1830 #endif
1831
1832         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1833                 int snd;
1834                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1835                 powerup_basic(20, 20, 20, 0, TXT_EXTRA_LIFE);
1836                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1837                         digi_play_sample( snd, F1_0 );
1838         }
1839 }
1840
1841 void add_bonus_points_to_score(int points) 
1842 {
1843         int prev_score;
1844
1845         if (points == 0 || Cheats_enabled)
1846                 return;
1847
1848         prev_score=Players[Player_num].score;
1849
1850         Players[Player_num].score += points;
1851
1852
1853         if (Newdemo_state == ND_STATE_RECORDING)
1854                 newdemo_record_player_score(points);
1855
1856         if (Game_mode & GM_MULTI)
1857                 return;
1858
1859         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1860                 int snd;
1861                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1862                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1863                         digi_play_sample( snd, F1_0 );
1864         }
1865 }
1866
1867 #include "key.h"
1868
1869 void init_gauge_canvases()
1870 {
1871         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
1872         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
1873
1874         Canv_LeftEnergyGauge = gr_create_canvas( LEFT_ENERGY_GAUGE_W, LEFT_ENERGY_GAUGE_H );
1875         Canv_SBEnergyGauge = gr_create_canvas( SB_ENERGY_GAUGE_W, SB_ENERGY_GAUGE_H );
1876         Canv_SBAfterburnerGauge = gr_create_canvas( SB_AFTERBURNER_GAUGE_W, SB_AFTERBURNER_GAUGE_H );
1877         Canv_RightEnergyGauge = gr_create_canvas( RIGHT_ENERGY_GAUGE_W, RIGHT_ENERGY_GAUGE_H );
1878         Canv_NumericalGauge = gr_create_canvas( NUMERICAL_GAUGE_W, NUMERICAL_GAUGE_H );
1879         Canv_AfterburnerGauge = gr_create_canvas( AFTERBURNER_GAUGE_W, AFTERBURNER_GAUGE_H );
1880
1881 }
1882
1883 void close_gauge_canvases()
1884 {
1885         gr_free_canvas( Canv_LeftEnergyGauge );
1886         gr_free_canvas( Canv_SBEnergyGauge );
1887         gr_free_canvas( Canv_SBAfterburnerGauge );
1888         gr_free_canvas( Canv_RightEnergyGauge );
1889         gr_free_canvas( Canv_NumericalGauge );
1890         gr_free_canvas( Canv_AfterburnerGauge );
1891 }
1892
1893 void init_gauges()
1894 {
1895         int i;
1896
1897         //draw_gauges_on        = 1;
1898
1899         for (i=0; i<2; i++ )    {
1900                 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)) ) 
1901                         old_score[i] = -99;
1902                 else
1903                         old_score[i]                    = -1;
1904                 old_energy[i]                   = -1;
1905                 old_shields[i]                  = -1;
1906                 old_flags[i]                    = -1;
1907                 old_cloak[i]                    = -1;
1908                 old_lives[i]                    = -1;
1909                 old_afterburner[i]      = -1;
1910                 old_bombcount[i]                = 0;
1911                 old_laser_level[i]      = 0;
1912         
1913                 old_weapon[0][i] = old_weapon[1][i] = -1;
1914                 old_ammo_count[0][i] = old_ammo_count[1][i] = -1;
1915                 Old_Omega_charge[i] = -1;
1916         }
1917
1918         cloak_fade_state = 0;
1919
1920         weapon_box_user[0] = weapon_box_user[1] = WBU_WEAPON;
1921 }
1922
1923 void draw_energy_bar(int energy)
1924 {
1925         int not_energy;
1926         int x1, x2, y;
1927
1928         // Draw left energy bar
1929         gr_set_current_canvas( Canv_LeftEnergyGauge );
1930         PAGE_IN_GAUGE( GAUGE_ENERGY_LEFT );
1931         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_LEFT)] );
1932         gr_setcolor( BM_XRGB(0,0,0) );
1933
1934         if ( !Current_display_mode )
1935                 not_energy = 61 - (energy*61)/100;
1936         else
1937                 not_energy = 125 - (energy*125)/100;
1938
1939         if (energy < 100)
1940                 for (y=0; y < LEFT_ENERGY_GAUGE_H; y++) {
1941                         x1 = LEFT_ENERGY_GAUGE_H - 1 - y;
1942                         x2 = LEFT_ENERGY_GAUGE_H - 1 - y + not_energy;
1943         
1944                         if ( y>=0 && y<(LEFT_ENERGY_GAUGE_H/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 1) x2 = LEFT_ENERGY_GAUGE_W - 1;
1945                         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;
1946                         if ( y>=((LEFT_ENERGY_GAUGE_H*3)/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 3) x2 = LEFT_ENERGY_GAUGE_W - 3;
1947                         
1948                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
1949                 }
1950         
1951         WINDOS(
1952                 dd_gr_set_current_canvas(get_current_game_screen()),
1953                 gr_set_current_canvas( get_current_game_screen() )
1954         );
1955         WIN(DDGRLOCK(dd_grd_curcanv));
1956                 gr_ubitmapm( LEFT_ENERGY_GAUGE_X, LEFT_ENERGY_GAUGE_Y, &Canv_LeftEnergyGauge->cv_bitmap );
1957         WIN(DDGRUNLOCK(dd_grd_curcanv));
1958
1959         // Draw right energy bar
1960         gr_set_current_canvas( Canv_RightEnergyGauge );
1961         PAGE_IN_GAUGE( GAUGE_ENERGY_RIGHT );
1962         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_RIGHT) ] );
1963         gr_setcolor( BM_XRGB(0,0,0) );
1964
1965         if (energy < 100)
1966                 for (y=0; y < RIGHT_ENERGY_GAUGE_H; y++) {
1967                         x1 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y - not_energy;
1968                         x2 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y;
1969         
1970                         if ( y>=0 && y<(RIGHT_ENERGY_GAUGE_H/4) ) if (x1 < 0) x1 = 0;
1971                         if ( y>=(RIGHT_ENERGY_GAUGE_H/4) && y<((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 1) x1 = 1;
1972                         if ( y>=((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 2) x1 = 2;
1973                         
1974                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
1975                 }
1976
1977         WINDOS(
1978                 dd_gr_set_current_canvas(get_current_game_screen()),
1979                 gr_set_current_canvas( get_current_game_screen() )
1980         );
1981         WIN(DDGRLOCK(dd_grd_curcanv));
1982                 gr_ubitmapm( RIGHT_ENERGY_GAUGE_X, RIGHT_ENERGY_GAUGE_Y, &Canv_RightEnergyGauge->cv_bitmap );
1983         WIN(DDGRUNLOCK(dd_grd_curcanv));
1984 }
1985
1986 ubyte afterburner_bar_table[AFTERBURNER_GAUGE_H_L*2] = {
1987                         3,11,
1988                         3,11,
1989                         3,11,
1990                         3,11,
1991                         3,11,
1992                         3,11,
1993                         2,11,
1994                         2,10,
1995                         2,10,
1996                         2,10,
1997                         2,10,
1998                         2,10,
1999                         2,10,
2000                         1,10,
2001                         1,10,
2002                         1,10,
2003                         1,9,
2004                         1,9,
2005                         1,9,
2006                         1,9,
2007                         0,9,
2008                         0,9,
2009                         0,8,
2010                         0,8,
2011                         0,8,
2012                         0,8,
2013                         1,8,
2014                         2,8,
2015                         3,8,
2016                         4,8,
2017                         5,8,
2018                         6,7,
2019 };
2020
2021 ubyte afterburner_bar_table_hires[AFTERBURNER_GAUGE_H_H*2] = {
2022         5,20,
2023         5,20,
2024         5,19,
2025         5,19,
2026         5,19,
2027         5,19,
2028         4,19,
2029         4,19,
2030         4,19,
2031         4,19,
2032
2033         4,19,
2034         4,18,
2035         4,18,
2036         4,18,
2037         4,18,
2038         3,18,
2039         3,18,
2040         3,18,
2041         3,18,
2042         3,18,
2043
2044         3,18,
2045         3,17,
2046         3,17,
2047         2,17,
2048         2,17,
2049         2,17,
2050         2,17,
2051         2,17,
2052         2,17,
2053         2,17,
2054
2055         2,17,
2056         2,16,
2057         2,16,
2058         1,16,
2059         1,16,
2060         1,16,
2061         1,16,
2062         1,16,
2063         1,16,
2064         1,16,
2065
2066         1,16,
2067         1,15,
2068         1,15,
2069         1,15,
2070         0,15,
2071         0,15,
2072         0,15,
2073         0,15,
2074         0,15,
2075         0,15,
2076
2077         0,14,
2078         0,14,
2079         0,14,
2080         1,14,
2081         2,14,
2082         3,14,
2083         4,14,
2084         5,14,
2085         6,13,
2086         7,13,
2087
2088         8,13,
2089         9,13,
2090         10,13,
2091         11,13,
2092         12,13
2093 };
2094
2095
2096 void draw_afterburner_bar(int afterburner)
2097 {
2098         int not_afterburner;
2099         int y;
2100
2101         // Draw afterburner bar
2102         gr_set_current_canvas( Canv_AfterburnerGauge );
2103         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
2104         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_AFTERBURNER) ] );
2105         gr_setcolor( BM_XRGB(0,0,0) );
2106
2107         not_afterburner = fixmul(f1_0 - afterburner,AFTERBURNER_GAUGE_H);
2108
2109         for (y=0;y<not_afterburner;y++) {
2110
2111                 gr_uscanline( (Current_display_mode?afterburner_bar_table_hires[y*2]:afterburner_bar_table[y*2]),
2112                                                 (Current_display_mode?afterburner_bar_table_hires[y*2+1]:afterburner_bar_table[y*2+1]), y ); 
2113         }
2114
2115         WINDOS(
2116                 dd_gr_set_current_canvas(get_current_game_screen()),
2117                 gr_set_current_canvas( get_current_game_screen() )
2118         );
2119         WIN(DDGRLOCK(dd_grd_curcanv));
2120                 gr_ubitmapm( AFTERBURNER_GAUGE_X, AFTERBURNER_GAUGE_Y, &Canv_AfterburnerGauge->cv_bitmap );
2121         WIN(DDGRUNLOCK(dd_grd_curcanv));
2122 }
2123
2124 void draw_shield_bar(int shield)
2125 {
2126         int bm_num = shield>=100?9:(shield / 10);
2127
2128         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num   );
2129         WIN(DDGRLOCK(dd_grd_curcanv));
2130         PA_DFX (pa_set_frontbuffer_current());
2131    PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
2132         PA_DFX (pa_set_backbuffer_current());
2133         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
2134
2135         WIN(DDGRUNLOCK(dd_grd_curcanv));
2136 }
2137
2138 #define CLOAK_FADE_WAIT_TIME  0x400
2139
2140 void draw_player_ship(int cloak_state,int old_cloak_state,int x, int y)
2141 {
2142         static fix cloak_fade_timer=0;
2143         static int cloak_fade_value=GR_FADE_LEVELS-1;
2144         static int refade = 0;
2145         grs_bitmap *bm;
2146
2147         if (Game_mode & GM_TEAM)        {
2148                 #ifdef NETWORK
2149                 PAGE_IN_GAUGE( GAUGE_SHIPS+get_team(Player_num) );
2150                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+get_team(Player_num)) ];
2151                 #endif
2152         } else {
2153                 PAGE_IN_GAUGE( GAUGE_SHIPS+Player_num );
2154                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+Player_num) ];
2155         }
2156         
2157
2158         if (old_cloak_state==-1 && cloak_state)
2159                         cloak_fade_value=0;
2160
2161 //      mprintf((0, "cloak/oldcloak %d/%d", cloak_state, old_cloak_state));
2162
2163         if (!cloak_state) {
2164                 cloak_fade_value=GR_FADE_LEVELS-1;
2165                 cloak_fade_state = 0;
2166         }
2167
2168         if (cloak_state==1 && old_cloak_state==0)
2169                 cloak_fade_state = -1;
2170         //else if (cloak_state==0 && old_cloak_state==1)
2171         //      cloak_fade_state = 1;
2172
2173         if (cloak_state==old_cloak_state)               //doing "about-to-uncloak" effect
2174                 if (cloak_fade_state==0)
2175                         cloak_fade_state = 2;
2176         
2177
2178         if (cloak_fade_state)
2179                 cloak_fade_timer -= FrameTime;
2180
2181         while (cloak_fade_state && cloak_fade_timer < 0) {
2182
2183                 cloak_fade_timer += CLOAK_FADE_WAIT_TIME;
2184
2185                 cloak_fade_value += cloak_fade_state;
2186
2187                 if (cloak_fade_value >= GR_FADE_LEVELS-1) {
2188                         cloak_fade_value = GR_FADE_LEVELS-1;
2189                         if (cloak_fade_state == 2 && cloak_state)
2190                                 cloak_fade_state = -2;
2191                         else
2192                                 cloak_fade_state = 0;
2193                 }
2194                 else if (cloak_fade_value <= 0) {
2195                         cloak_fade_value = 0;
2196                         if (cloak_fade_state == -2)
2197                                 cloak_fade_state = 2;
2198                         else
2199                                 cloak_fade_state = 0;
2200                 }
2201         }
2202
2203 //      To fade out both pages in a paged mode.
2204         if (refade) refade = 0;
2205         else if (cloak_state && old_cloak_state && !cloak_fade_state && !refade) {
2206                 cloak_fade_state = -1;
2207                 refade = 1;
2208         }
2209
2210 #if defined(POLY_ACC)
2211         #ifdef MACINTOSH
2212         if ( PAEnabled ) {
2213         #endif
2214             Gr_scanline_darkening_level = cloak_fade_value;
2215             gr_set_current_canvas( get_current_game_screen() );
2216             PA_DFX (pa_set_frontbuffer_current());      
2217             PA_DFX (pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h));
2218                  PA_DFX (pa_set_backbuffer_current());  
2219             pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h);
2220
2221             Gr_scanline_darkening_level = GR_FADE_LEVELS;
2222             return;
2223 //          }
2224 //          else
2225 //                  Gr_scanline_darkening_level = GR_FADE_LEVELS;
2226 //               mprintf ((1,"HEY! HIT THIS!\n"));      
2227 //               Int3();
2228         #ifdef MACINTOSH
2229         }
2230         #endif
2231 #endif
2232
2233         WINDOS(                 
2234                 dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2235                 gr_set_current_canvas(&VR_render_buffer[0])
2236         );
2237
2238         WIN(DDGRLOCK(dd_grd_curcanv));
2239                 gr_ubitmap( x, y, bm);
2240
2241                 Gr_scanline_darkening_level = cloak_fade_value;
2242                 gr_rect(x, y, x+bm->bm_w-1, y+bm->bm_h-1);
2243                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2244         WIN(DDGRUNLOCK(dd_grd_curcanv));
2245
2246         WINDOS(
2247                 dd_gr_set_current_canvas(get_current_game_screen()),
2248                 gr_set_current_canvas( get_current_game_screen() )
2249         );
2250
2251 #ifdef WINDOWS
2252         DDGRLOCK(dd_grd_curcanv);
2253         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2254                 DDGRLOCK(&dd_VR_render_buffer[0]);
2255         }
2256         else {
2257                 dd_gr_dup_hack(&dd_VR_render_buffer[0], dd_grd_curcanv);
2258         }
2259 #endif
2260         WINDOS(
2261                 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),
2262                 gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &VR_render_buffer[0].cv_bitmap, &grd_curcanv->cv_bitmap)
2263         );
2264 #ifdef WINDOWS
2265         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2266                 DDGRUNLOCK(&dd_VR_render_buffer[0]);
2267         }
2268         else {
2269                 dd_gr_dup_unhack(&dd_VR_render_buffer[0]);
2270         }
2271         DDGRUNLOCK(dd_grd_curcanv);
2272 #endif
2273 }
2274
2275 #define INV_FRAME_TIME  (f1_0/10)               //how long for each frame
2276
2277 void draw_numerical_display(int shield, int energy)
2278 {
2279         gr_set_current_canvas( Canv_NumericalGauge );
2280         gr_set_curfont( GAME_FONT );
2281         PAGE_IN_GAUGE( GAUGE_NUMERICAL );
2282         gr_ubitmap( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_NUMERICAL) ] );
2283
2284         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2285
2286         if (!Current_display_mode) {
2287                 gr_printf((shield>99)?3:((shield>9)?5:7),15,"%d",shield);
2288                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2289                 gr_printf((energy>99)?3:((energy>9)?5:7),2,"%d",energy);
2290         } else {
2291                 gr_printf((shield>99)?7:((shield>9)?11:15),33,"%d",shield);
2292                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2293                 gr_printf((energy>99)?7:((energy>9)?11:15),4,"%d",energy);
2294         }
2295         
2296         WINDOS(
2297                 dd_gr_set_current_canvas(get_current_game_screen()),
2298                 gr_set_current_canvas( get_current_game_screen() )
2299         );
2300         WIN(DDGRLOCK(dd_grd_curcanv));
2301                 gr_ubitmapm( NUMERICAL_GAUGE_X, NUMERICAL_GAUGE_Y, &Canv_NumericalGauge->cv_bitmap );
2302         WIN(DDGRUNLOCK(dd_grd_curcanv));
2303 }
2304
2305
2306 void draw_keys()
2307 {
2308 WINDOS(
2309         dd_gr_set_current_canvas( get_current_game_screen() ),
2310         gr_set_current_canvas( get_current_game_screen() )
2311 );
2312
2313 WIN(DDGRLOCK(dd_grd_curcanv));
2314         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY ) {
2315                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY );
2316                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY) ] );
2317         } else {
2318                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY_OFF );
2319                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY_OFF) ] );
2320         }
2321
2322         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)  {
2323                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY );
2324                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY) ] );
2325         } else {
2326                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY_OFF );
2327                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY_OFF) ] );
2328         }
2329
2330         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)   {
2331                 PAGE_IN_GAUGE( GAUGE_RED_KEY );
2332                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY) ] );
2333         } else {
2334                 PAGE_IN_GAUGE( GAUGE_RED_KEY_OFF );
2335                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY_OFF) ] );
2336         }
2337 WIN(DDGRUNLOCK(dd_grd_curcanv));
2338 }
2339
2340
2341 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)
2342 {
2343         grs_bitmap *bm;
2344         char *p;
2345
2346         //clear the window
2347         gr_setcolor(BM_XRGB(0,0,0));
2348         
2349   // PA_DFX (pa_set_frontbuffer_current());
2350 //      PA_DFX (gr_rect(box->left,box->top,box->right,box->bot));
2351    PA_DFX (pa_set_backbuffer_current());
2352         gr_rect(box->left,box->top,box->right,box->bot);
2353
2354         if (Current_display_mode) {
2355                 bm=&GameBitmaps[Weapon_info[info_index].hires_picture.index];
2356                 PIGGY_PAGE_IN( Weapon_info[info_index].hires_picture );
2357         } else {
2358                 bm=&GameBitmaps[Weapon_info[info_index].picture.index];
2359                 PIGGY_PAGE_IN( Weapon_info[info_index].picture );
2360         }
2361         
2362         Assert(bm != NULL);
2363
2364 //   PA_DFX (pa_set_frontbuffer_current());
2365 //      PA_DFX (gr_ubitmapm(pic_x,pic_y,bm));
2366    PA_DFX (pa_set_backbuffer_current());
2367         gr_ubitmapm(pic_x,pic_y,bm);
2368         
2369         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2370
2371         if ((p=strchr(name,'\n'))!=NULL) {
2372                 *p=0;
2373            #ifdef PA_3DFX_VOODOO
2374   //                    pa_set_frontbuffer_current();
2375 //                      gr_printf(text_x,text_y,name);
2376 //                      gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2377                 #endif
2378                 PA_DFX (pa_set_backbuffer_current());
2379                 gr_printf(text_x,text_y,name);
2380                 gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2381                 *p='\n';
2382         } else
2383          {
2384   //            PA_DFX(pa_set_frontbuffer_current());
2385 //              PA_DFX (gr_printf(text_x,text_y,name));
2386                 PA_DFX(pa_set_backbuffer_current());
2387                 gr_printf(text_x,text_y,name);
2388          }      
2389
2390         //      For laser, show level and quadness
2391         if (info_index == LASER_ID || info_index == SUPER_LASER_ID) {
2392                 char    temp_str[7];
2393
2394                 sprintf(temp_str, "%s: 0", TXT_LVL);
2395
2396                 temp_str[5] = Players[Player_num].laser_level+1 + '0';
2397
2398 //              PA_DFX(pa_set_frontbuffer_current());
2399 //              PA_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2400                 PA_DFX(pa_set_backbuffer_current());
2401                 NO_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2402                 PA_DFX (gr_printf(text_x,text_y+12, temp_str));
2403
2404                 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
2405                         strcpy(temp_str, TXT_QUAD);
2406 //                      PA_DFX(pa_set_frontbuffer_current());
2407 //                      PA_DFX (gr_printf(text_x,text_y+2*Line_spacing, temp_str));
2408                         PA_DFX(pa_set_backbuffer_current());
2409                         gr_printf(text_x,text_y+2*Line_spacing, temp_str);
2410
2411                 }
2412
2413         }
2414 }
2415
2416
2417 void draw_weapon_info(int weapon_type,int weapon_num,int laser_level)
2418 {
2419         int info_index;
2420
2421         if (weapon_type == 0) {
2422                 info_index = Primary_weapon_to_weapon_info[weapon_num];
2423
2424                 if (info_index == LASER_ID && laser_level > MAX_LASER_LEVEL)
2425                         info_index = SUPER_LASER_ID;
2426
2427                 if (Cockpit_mode == CM_STATUS_BAR)
2428                         draw_weapon_info_sub(info_index,
2429                                 &gauge_boxes[SB_PRIMARY_BOX],
2430                                 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
2431                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2432                                 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
2433                 else
2434                         draw_weapon_info_sub(info_index,
2435                                 &gauge_boxes[COCKPIT_PRIMARY_BOX],
2436                                 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
2437                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2438                                 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
2439
2440         }
2441         else {
2442                 info_index = Secondary_weapon_to_weapon_info[weapon_num];
2443
2444                 if (Cockpit_mode == CM_STATUS_BAR)
2445                         draw_weapon_info_sub(info_index,
2446                                 &gauge_boxes[SB_SECONDARY_BOX],
2447                                 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
2448                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2449                                 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
2450                 else
2451                         draw_weapon_info_sub(info_index,
2452                                 &gauge_boxes[COCKPIT_SECONDARY_BOX],
2453                                 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
2454                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2455                                 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
2456         }
2457 }
2458
2459 void draw_ammo_info(int x,int y,int ammo_count,int primary)
2460 {
2461         int w;
2462         char str[16];
2463
2464         if (primary)
2465                 w = (grd_curcanv->cv_font->ft_w*7)/2;
2466         else
2467                 w = (grd_curcanv->cv_font->ft_w*5)/2;
2468
2469 WIN(DDGRLOCK(dd_grd_curcanv));
2470 {
2471
2472         PA_DFX (pa_set_frontbuffer_current());
2473
2474         gr_setcolor(BM_XRGB(0,0,0));
2475         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2476         gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
2477         sprintf(str,"%03d",ammo_count);
2478         convert_1s(str);
2479         gr_printf(x,y,str);
2480
2481         PA_DFX (pa_set_backbuffer_current());
2482         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2483         gr_printf(x,y,str);
2484 }
2485
2486 WIN(DDGRUNLOCK(dd_grd_curcanv));
2487 }
2488
2489 void draw_secondary_ammo_info(int ammo_count)
2490 {
2491         if (Cockpit_mode == CM_STATUS_BAR)
2492                 draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
2493         else
2494                 draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
2495 }
2496
2497 //returns true if drew picture
2498 int draw_weapon_box(int weapon_type,int weapon_num)
2499 {
2500         int drew_flag=0;
2501         int laser_level_changed;
2502
2503 WINDOS(
2504         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2505         gr_set_current_canvas(&VR_render_buffer[0])
2506 );
2507
2508    PA_DFX (pa_set_backbuffer_current());
2509  
2510 WIN(DDGRLOCK(dd_grd_curcanv));
2511         gr_set_curfont( GAME_FONT );
2512
2513         laser_level_changed = (weapon_type==0 && weapon_num==LASER_INDEX && (Players[Player_num].laser_level != old_laser_level[VR_current_page]));
2514
2515         if ((weapon_num != old_weapon[weapon_type][VR_current_page] || laser_level_changed) && weapon_box_states[weapon_type] == WS_SET) {
2516                 weapon_box_states[weapon_type] = WS_FADING_OUT;
2517                 weapon_box_fade_values[weapon_type]=i2f(GR_FADE_LEVELS-1);
2518         }
2519                 
2520         if (old_weapon[weapon_type][VR_current_page] == -1) {
2521                 //@@if (laser_level_changed)
2522                 //@@    old_weapon[weapon_type][VR_current_page] = LASER_INDEX;
2523                 //@@else 
2524                 {
2525                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2526                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2527                         old_ammo_count[weapon_type][VR_current_page]=-1;
2528                         Old_Omega_charge[VR_current_page]=-1;
2529                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2530                         drew_flag=1;
2531                         weapon_box_states[weapon_type] = WS_SET;
2532                 }
2533         }
2534
2535         if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
2536                 draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page],old_laser_level[VR_current_page]);
2537                 old_ammo_count[weapon_type][VR_current_page]=-1;
2538                 Old_Omega_charge[VR_current_page]=-1;
2539                 drew_flag=1;
2540                 weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
2541                 if (weapon_box_fade_values[weapon_type] <= 0) {
2542                         weapon_box_states[weapon_type] = WS_FADING_IN;
2543                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2544                         old_weapon[weapon_type][!VR_current_page] = weapon_num;
2545                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2546                         old_laser_level[!VR_current_page] = Players[Player_num].laser_level;
2547                         weapon_box_fade_values[weapon_type] = 0;
2548                 }
2549         }
2550         else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
2551                 if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
2552                         weapon_box_states[weapon_type] = WS_FADING_OUT;
2553                 }
2554                 else {
2555                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2556                         old_ammo_count[weapon_type][VR_current_page]=-1;
2557                         Old_Omega_charge[VR_current_page]=-1;
2558                         drew_flag=1;
2559                         weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
2560                         if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
2561                                 weapon_box_states[weapon_type] = WS_SET;
2562                                 old_weapon[weapon_type][!VR_current_page] = -1;         //force redraw (at full fade-in) of other page
2563                         }
2564                 }
2565         }
2566
2567         if (weapon_box_states[weapon_type] != WS_SET) {         //fade gauge
2568                 int fade_value = f2i(weapon_box_fade_values[weapon_type]);
2569                 int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2570                 
2571                 Gr_scanline_darkening_level = fade_value;
2572 //         PA_DFX (pa_set_frontbuffer_current());
2573 //              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));
2574            PA_DFX (pa_set_backbuffer_current());
2575                 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
2577                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2578         }
2579 WIN(DDGRUNLOCK(dd_grd_curcanv));
2580
2581 WINDOS(
2582         dd_gr_set_current_canvas(get_current_game_screen()),
2583         gr_set_current_canvas(get_current_game_screen())
2584 );
2585         return drew_flag;
2586 }
2587
2588 fix static_time[2];
2589
2590 void draw_static(int win)
2591 {
2592         vclip *vc = &Vclip[VCLIP_MONITOR_STATIC];
2593         grs_bitmap *bmp;
2594         int framenum;
2595         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2596         int x,y;
2597
2598         static_time[win] += FrameTime;
2599         if (static_time[win] >= vc->play_time) {
2600                 weapon_box_user[win] = WBU_WEAPON;
2601                 return;
2602         }
2603
2604         framenum = static_time[win] * vc->num_frames / vc->play_time;
2605
2606         PIGGY_PAGE_IN(vc->frames[framenum]);
2607
2608         bmp = &GameBitmaps[vc->frames[framenum].index];
2609
2610         WINDOS(
2611         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2612         gr_set_current_canvas(&VR_render_buffer[0])
2613         );
2614         WIN(DDGRLOCK(dd_grd_curcanv));
2615    PA_DFX (pa_set_backbuffer_current());
2616         PA_DFX (pa_bypass_mode (0));
2617         PA_DFX (pa_clip_window (gauge_boxes[boxofs+win].left,gauge_boxes[boxofs+win].top,
2618                                                                         gauge_boxes[boxofs+win].right,gauge_boxes[boxofs+win].bot));
2619    
2620         for (x=gauge_boxes[boxofs+win].left;x<gauge_boxes[boxofs+win].right;x+=bmp->bm_w)
2621                 for (y=gauge_boxes[boxofs+win].top;y<gauge_boxes[boxofs+win].bot;y+=bmp->bm_h)
2622                         gr_bitmap(x,y,bmp);
2623
2624         PA_DFX (pa_bypass_mode(1));
2625         PA_DFX (pa_clip_window (0,0,640,480));
2626
2627         WIN(DDGRUNLOCK(dd_grd_curcanv));
2628
2629         WINDOS(
2630         dd_gr_set_current_canvas(get_current_game_screen()),
2631         gr_set_current_canvas(get_current_game_screen())
2632         );
2633
2634 //   PA_DFX (return);
2635   
2636         WINDOS(
2637         copy_gauge_box(&gauge_boxes[boxofs+win],&dd_VR_render_buffer[0]),
2638         copy_gauge_box(&gauge_boxes[boxofs+win],&VR_render_buffer[0].cv_bitmap)
2639         );
2640 }
2641
2642 void draw_weapon_boxes()
2643 {
2644         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2645         int drew;
2646
2647         if (weapon_box_user[0] == WBU_WEAPON) {
2648                 drew = draw_weapon_box(0,Primary_weapon);
2649                 if (drew) 
2650                         WINDOS(
2651                                 copy_gauge_box(&gauge_boxes[boxofs+0],&dd_VR_render_buffer[0]),
2652                                 copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap)
2653                         );
2654
2655                 if (weapon_box_states[0] == WS_SET) {
2656                         if ((Primary_weapon == VULCAN_INDEX) || (Primary_weapon == GAUSS_INDEX)) {
2657                                 if (Players[Player_num].primary_ammo[VULCAN_INDEX] != old_ammo_count[0][VR_current_page]) {
2658                                         if (Newdemo_state == ND_STATE_RECORDING)
2659                                                 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[VULCAN_INDEX]);
2660                                         draw_primary_ammo_info(f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX]));
2661                                         old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[VULCAN_INDEX];
2662                                 }
2663                         }
2664
2665                         if (Primary_weapon == OMEGA_INDEX) {
2666                                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
2667                                         if (Newdemo_state == ND_STATE_RECORDING)
2668                                                 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
2669                                         draw_primary_ammo_info(Omega_charge * 100/MAX_OMEGA_CHARGE);
2670                                         Old_Omega_charge[VR_current_page] = Omega_charge;
2671                                 }
2672                         }
2673                 }
2674         }
2675         else if (weapon_box_user[0] == WBU_STATIC)
2676                 draw_static(0);
2677
2678         if (weapon_box_user[1] == WBU_WEAPON) {
2679                 drew = draw_weapon_box(1,Secondary_weapon);
2680                 if (drew)
2681                         WINDOS(
2682                                 copy_gauge_box(&gauge_boxes[boxofs+1],&dd_VR_render_buffer[0]),
2683                                 copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap)
2684                         );
2685
2686                 if (weapon_box_states[1] == WS_SET)
2687                         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
2688                                 old_bombcount[VR_current_page] = 0x7fff;        //force redraw
2689                                 if (Newdemo_state == ND_STATE_RECORDING)
2690                                         newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
2691                                 draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
2692                                 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
2693                         }
2694         }
2695         else if (weapon_box_user[1] == WBU_STATIC)
2696                 draw_static(1);
2697 }
2698
2699
2700 void sb_draw_energy_bar(energy)
2701 {
2702         int erase_height, w, h, aw;
2703         char energy_str[20];
2704
2705         gr_set_current_canvas( Canv_SBEnergyGauge );
2706
2707         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2708         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_ENERGY) ] );
2709
2710         erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
2711
2712         if (erase_height > 0) {
2713                 gr_setcolor( BM_XRGB(0,0,0) );
2714                 gr_rect(0,0,SB_ENERGY_GAUGE_W-1,erase_height-1);
2715         }
2716
2717         WINDOS(
2718         dd_gr_set_current_canvas(get_current_game_screen()),
2719         gr_set_current_canvas(get_current_game_screen())
2720         );
2721
2722         WIN(DDGRLOCK(dd_grd_curcanv));
2723    PA_DFX (pa_set_frontbuffer_current());
2724    PA_DFX (gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap));
2725    PA_DFX (pa_set_backbuffer_current());
2726         gr_ubitmapm( SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, &Canv_SBEnergyGauge->cv_bitmap );
2727
2728         //draw numbers
2729         sprintf(energy_str, "%d", energy);
2730         gr_get_string_size(energy_str, &w, &h, &aw );
2731         gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2732    PA_DFX (pa_set_frontbuffer_current());
2733         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));
2734    PA_DFX (pa_set_backbuffer_current());
2735         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         WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
2737 }
2738
2739 void sb_draw_afterburner()
2740 {
2741         int erase_height, w, h, aw;
2742         char ab_str[3] = "AB";
2743
2744         gr_set_current_canvas( Canv_SBAfterburnerGauge );
2745         PAGE_IN_GAUGE( SB_GAUGE_AFTERBURNER );
2746         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_AFTERBURNER) ] );
2747
2748         erase_height = fixmul((f1_0 - Afterburner_charge),SB_AFTERBURNER_GAUGE_H);
2749
2750         if (erase_height > 0) {
2751                 gr_setcolor( BM_XRGB(0,0,0) );
2752                 gr_rect(0,0,SB_AFTERBURNER_GAUGE_W-1,erase_height-1);
2753         }
2754
2755 WINDOS(
2756         dd_gr_set_current_canvas(get_current_game_screen()),
2757         gr_set_current_canvas(get_current_game_screen())
2758 );
2759 WIN(DDGRLOCK(dd_grd_curcanv));
2760    PA_DFX (pa_set_frontbuffer_current());
2761         gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap );
2762    PA_DFX (pa_set_backbuffer_current());
2763         PA_DFX (gr_ubitmapm( SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, &Canv_SBAfterburnerGauge->cv_bitmap ));
2764
2765         //draw legend
2766         if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
2767                 gr_set_fontcolor(gr_getcolor(45,0,0),-1 );
2768         else 
2769                 gr_set_fontcolor(gr_getcolor(12,12,12),-1 );
2770
2771         gr_get_string_size(ab_str, &w, &h, &aw );
2772    PA_DFX (pa_set_frontbuffer_current());
2773         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"));
2774    PA_DFX (pa_set_backbuffer_current());
2775         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
2777 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
2778 }
2779
2780 void sb_draw_shield_num(int shield)
2781 {
2782         //draw numbers
2783
2784         gr_set_curfont( GAME_FONT );
2785         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2786
2787         //erase old one
2788         PIGGY_PAGE_IN( cockpit_bitmap[Cockpit_mode+(Current_display_mode?(Num_cockpits/2):0)] );
2789
2790 WIN(DDGRLOCK(dd_grd_curcanv));
2791    PA_DFX (pa_set_back_to_read());
2792         gr_setcolor(gr_gpixel(&grd_curcanv->cv_bitmap,SB_SHIELD_NUM_X-1,SB_SHIELD_NUM_Y-1));
2793    PA_DFX (pa_set_front_to_read());
2794
2795         PA_DFX (pa_set_frontbuffer_current());
2796
2797         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);
2798         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);
2799
2800         PA_DFX (pa_set_backbuffer_current());
2801         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));
2802         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));
2803
2804 WIN(DDGRUNLOCK(dd_grd_curcanv));
2805 }
2806
2807 void sb_draw_shield_bar(int shield)
2808 {
2809         int bm_num = shield>=100?9:(shield / 10);
2810
2811 WINDOS(
2812         dd_gr_set_current_canvas(get_current_game_screen()),
2813         gr_set_current_canvas(get_current_game_screen())
2814 );
2815 WIN(DDGRLOCK(dd_grd_curcanv));
2816         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num );
2817    PA_DFX (pa_set_frontbuffer_current());               
2818         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
2819    PA_DFX (pa_set_backbuffer_current());                
2820         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
2821         
2822 WIN(DDGRUNLOCK(dd_grd_curcanv));                                          
2823 }
2824
2825 void sb_draw_keys()
2826 {
2827         grs_bitmap * bm;
2828         int flags = Players[Player_num].flags;
2829
2830 WINDOS(
2831         dd_gr_set_current_canvas(get_current_game_screen()),
2832         gr_set_current_canvas(get_current_game_screen())
2833 );
2834 WIN(DDGRLOCK(dd_grd_curcanv));
2835    PA_DFX (pa_set_frontbuffer_current());
2836         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
2837         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
2838         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
2839         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
2840         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
2841         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
2842         bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
2843         PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
2844         gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
2845         #ifdef PA_3DFX_VOODOO
2846            PA_DFX (pa_set_backbuffer_current());
2847                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
2848                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
2849                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
2850                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
2851                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
2852                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
2853                 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
2854                 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
2855                 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm  );
2856         #endif
2857
2858 WIN(DDGRUNLOCK(dd_grd_curcanv));
2859 }
2860
2861 //      Draws invulnerable ship, or maybe the flashing ship, depending on invulnerability time left.
2862 void draw_invulnerable_ship()
2863 {
2864         static fix time=0;
2865
2866 WINDOS(
2867         dd_gr_set_current_canvas(get_current_game_screen()),
2868         gr_set_current_canvas(get_current_game_screen())
2869 );
2870 WIN(DDGRLOCK(dd_grd_curcanv));
2871
2872         if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000)) {
2873
2874                 if (Cockpit_mode == CM_STATUS_BAR)      {
2875                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
2876                         PA_DFX (pa_set_frontbuffer_current());
2877                         gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] );
2878                         PA_DFX (pa_set_backbuffer_current());
2879                         PA_DFX (gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] ));
2880                 } else {
2881                         PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
2882                         PA_DFX (pa_set_frontbuffer_current());
2883                         PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] ));
2884                         PA_DFX (pa_set_backbuffer_current());
2885                         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] );
2886                 }
2887
2888                 time += FrameTime;
2889
2890                 while (time > INV_FRAME_TIME) {
2891                         time -= INV_FRAME_TIME;
2892                         if (++invulnerable_frame == N_INVULNERABLE_FRAMES)
2893                                 invulnerable_frame=0;
2894                 }
2895         } else if (Cockpit_mode == CM_STATUS_BAR)
2896                 sb_draw_shield_bar(f2ir(Players[Player_num].shields));
2897         else
2898                 draw_shield_bar(f2ir(Players[Player_num].shields));
2899 WIN(DDGRUNLOCK(dd_grd_curcanv));
2900 }
2901
2902 extern int Missile_gun;
2903 extern int allowed_to_fire_laser(void);
2904 extern int allowed_to_fire_missile(void);
2905
2906 rgb player_rgb[] = {
2907                                                         {15,15,23},
2908                                                         {27,0,0},
2909                                                         {0,23,0},
2910                                                         {30,11,31},
2911                                                         {31,16,0},
2912                                                         {24,17,6},
2913                                                         {14,21,12},
2914                                                         {29,29,0},
2915                                                 };
2916
2917 extern ubyte Newdemo_flying_guided;
2918 extern int max_window_w;
2919
2920 typedef struct {byte x,y;} xy;
2921
2922 //offsets for reticle parts: high-big  high-sml  low-big  low-sml
2923 xy cross_offsets[4] =           { {-8,-5},      {-4,-2},        {-4,-2}, {-2,-1} };
2924 xy primary_offsets[4] =         { {-30,14}, {-16,6},    {-15,6}, {-8, 2} };
2925 xy secondary_offsets[4] =       { {-24,2},      {-12,0}, {-12,1}, {-6,-2} };
2926
2927 //draw the reticle
2928 void show_reticle(int force_big_one)
2929 {
2930         int x,y;
2931         int laser_ready,missile_ready,laser_ammo,missile_ammo;
2932         int cross_bm_num,primary_bm_num,secondary_bm_num;
2933         int use_hires_reticle,small_reticle,ofs,gauge_index;
2934
2935    if (Newdemo_state==ND_STATE_PLAYBACK && Newdemo_flying_guided)
2936                 {
2937                 WIN(DDGRLOCK(dd_grd_curcanv));
2938                  draw_guided_crosshair();
2939                 WIN(DDGRUNLOCK(dd_grd_curcanv));
2940                  return;
2941            }
2942
2943         x = grd_curcanv->cv_w/2;
2944         y = grd_curcanv->cv_h/2;
2945
2946         laser_ready = allowed_to_fire_laser();
2947         missile_ready = allowed_to_fire_missile();
2948
2949         laser_ammo = player_has_weapon(Primary_weapon,0);
2950         missile_ammo = player_has_weapon(Secondary_weapon,1);
2951
2952         primary_bm_num = (laser_ready && laser_ammo==HAS_ALL);
2953         secondary_bm_num = (missile_ready && missile_ammo==HAS_ALL);
2954
2955         if (primary_bm_num && Primary_weapon==LASER_INDEX && (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS))
2956                 primary_bm_num++;
2957
2958         if (Secondary_weapon_to_gun_num[Secondary_weapon]==7)
2959                 secondary_bm_num += 3;          //now value is 0,1 or 3,4
2960         else if (secondary_bm_num && !(Missile_gun&1))
2961                         secondary_bm_num++;
2962
2963         cross_bm_num = ((primary_bm_num > 0) || (secondary_bm_num > 0));
2964
2965         Assert(primary_bm_num <= 2);
2966         Assert(secondary_bm_num <= 4);
2967         Assert(cross_bm_num <= 1);
2968 #ifdef OGL
2969       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);
2970        } else {
2971 #endif
2972
2973
2974         #ifndef MACINTOSH
2975                 use_hires_reticle = (FontHires != 0);
2976         #else
2977                 use_hires_reticle = !Scanline_double;
2978         #endif
2979
2980         WIN(DDGRLOCK(dd_grd_curcanv));
2981
2982 #ifndef MACINTOSH
2983         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*2 || force_big_one);
2984 #else
2985         small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*(Scanline_double?1:2) || force_big_one);
2986 #endif
2987         ofs = (use_hires_reticle?0:2) + small_reticle;
2988
2989         gauge_index = (small_reticle?SML_RETICLE_CROSS:RETICLE_CROSS) + cross_bm_num;
2990         PAGE_IN_GAUGE( gauge_index );
2991         gr_ubitmapm(x+cross_offsets[ofs].x,y+cross_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
2992
2993         gauge_index = (small_reticle?SML_RETICLE_PRIMARY:RETICLE_PRIMARY) + primary_bm_num;
2994         PAGE_IN_GAUGE( gauge_index );
2995         gr_ubitmapm(x+primary_offsets[ofs].x,y+primary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
2996
2997         gauge_index = (small_reticle?SML_RETICLE_SECONDARY:RETICLE_SECONDARY) + secondary_bm_num;
2998         PAGE_IN_GAUGE( gauge_index );
2999         gr_ubitmapm(x+secondary_offsets[ofs].x,y+secondary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
3000
3001         WIN(DDGRUNLOCK(dd_grd_curcanv));
3002 #ifdef OGL
3003        }
3004 #endif
3005 }
3006
3007 #ifdef NETWORK
3008 void hud_show_kill_list()
3009 {
3010         int n_players,player_list[MAX_NUM_NET_PLAYERS];
3011         int n_left,i,x0,x1,y,save_y,fth;
3012
3013 // ugly hack since placement of netgame players and kills is based off of
3014 // menuhires (which is always 1 for mac).  This throws off placement of
3015 // players in pixel double mode.
3016
3017 #ifdef MACINTOSH
3018         MenuHires = !(Scanline_double);
3019 #endif
3020
3021         if (Show_kill_list_timer > 0)
3022         {
3023                 Show_kill_list_timer -= FrameTime;
3024                 if (Show_kill_list_timer < 0)
3025                         Show_kill_list = 0;
3026         }
3027         
3028         gr_set_curfont( GAME_FONT );
3029
3030         n_players = multi_get_kill_list(player_list);
3031
3032         if (Show_kill_list == 3)
3033                 n_players = 2;
3034
3035         if (n_players <= 4)
3036                 n_left = n_players;
3037         else
3038                 n_left = (n_players+1)/2;
3039
3040         //If font size changes, this code might not work right anymore 
3041         //Assert(GAME_FONT->ft_h==5 && GAME_FONT->ft_w==7);
3042
3043         fth = GAME_FONT->ft_h;
3044
3045         x0 = LHX(1); x1 = LHX(43);
3046
3047         if (Game_mode & GM_MULTI_COOP)
3048                 x1 = LHX(31);
3049
3050         save_y = y = grd_curcanv->cv_h - n_left*(fth+1);
3051
3052         if (Cockpit_mode == CM_FULL_COCKPIT) {
3053                 save_y = y -= LHX(6);
3054                 if (Game_mode & GM_MULTI_COOP)
3055                         x1 = LHX(33);
3056                 else
3057                         x1 = LHX(43);
3058         }
3059
3060         for (i=0;i<n_players;i++) {
3061                 int player_num;
3062                 char name[9];
3063                 int sw,sh,aw;
3064
3065                 if (i>=n_left) {
3066                         if (Cockpit_mode == CM_FULL_COCKPIT)
3067                                 x0 = grd_curcanv->cv_w - LHX(53);
3068                         else
3069                                 x0 = grd_curcanv->cv_w - LHX(60);
3070                         if (Game_mode & GM_MULTI_COOP)
3071                                 x1 = grd_curcanv->cv_w - LHX(27);
3072                         else
3073                                 x1 = grd_curcanv->cv_w - LHX(15);  // Right edge of name, change this for width problems
3074                         if (i==n_left)
3075                                 y = save_y;
3076
3077         if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3078            {
3079              x1-=LHX(18);
3080             // x0-=LHX(18);
3081            }
3082                 }
3083      else  if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
3084            {
3085                                  x1 = LHX(43);
3086              x1-=LHX(18);
3087             // x0-=LHX(18);
3088            }
3089
3090         
3091                 if (Show_kill_list == 3)
3092                         player_num = i;
3093                 else
3094                         player_num = player_list[i];
3095
3096                 if (Show_kill_list == 1 || Show_kill_list==2)
3097                 {
3098                         int color;
3099
3100                         if (Players[player_num].connected != 1)
3101                                 gr_set_fontcolor(gr_getcolor(12, 12, 12), -1);
3102                         else if (Game_mode & GM_TEAM) {
3103                                 color = get_team(player_num);
3104                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3105                         }
3106                         else {
3107                                 color = player_num;
3108                                 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
3109                         }
3110                 }       
3111
3112                 else 
3113                 {
3114                         gr_set_fontcolor(gr_getcolor(player_rgb[player_num].r,player_rgb[player_num].g,player_rgb[player_num].b),-1 );
3115                 }
3116
3117                 if (Show_kill_list == 3)
3118                         strcpy(name, Netgame.team_name[i]);
3119                 else
3120                         strcpy(name,Players[player_num].callsign);      // Note link to above if!!
3121                 gr_get_string_size(name,&sw,&sh,&aw);
3122                 while (sw > (x1-x0-LHX(2))) {
3123                         name[strlen(name)-1]=0;
3124                         gr_get_string_size(name,&sw,&sh,&aw);
3125                 }
3126                 gr_printf(x0,y,"%s",name);
3127
3128                 if (Show_kill_list==2)
3129                  {
3130                   if (Players[player_num].net_killed_total+Players[player_num].net_kills_total==0)
3131                         gr_printf (x1,y,"NA");
3132                   else
3133                    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));           
3134                  }
3135                 else if (Show_kill_list == 3)   
3136                         gr_printf(x1,y,"%3d",team_kills[i]);
3137                 else if (Game_mode & GM_MULTI_COOP)
3138                         gr_printf(x1,y,"%-6d",Players[player_num].score);
3139       else if (Netgame.PlayTimeAllowed || Netgame.KillGoal)
3140          gr_printf(x1,y,"%3d(%d)",Players[player_num].net_kills_total,Players[player_num].KillGoalCount);
3141       else
3142                         gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
3143                         
3144                 y += fth+1;
3145
3146         }
3147
3148 #ifdef MACINTOSH
3149         MenuHires = 1;
3150 #endif
3151 }
3152 #endif
3153
3154 #ifndef RELEASE
3155 extern int Saving_movie_frames;
3156 #else
3157 #define Saving_movie_frames 0
3158 #endif
3159
3160 //returns true if viewer can see object
3161 int see_object(int objnum)
3162 {
3163         fvi_query fq;
3164         int hit_type;
3165         fvi_info hit_data;
3166
3167         //see if we can see this player
3168
3169         fq.p0                                   = &Viewer->pos;
3170         fq.p1                                   = &Objects[objnum].pos;
3171         fq.rad                                  = 0;
3172         fq.thisobjnum                   = Viewer - Objects;
3173         fq.flags                                = FQ_TRANSWALL | FQ_CHECK_OBJS;
3174         fq.startseg                             = Viewer->segnum;
3175         fq.ignore_obj_list      = NULL;
3176
3177         hit_type = find_vector_intersection(&fq, &hit_data);
3178
3179         return (hit_type == HIT_OBJECT && hit_data.hit_object == objnum);
3180 }
3181
3182 #ifdef NETWORK
3183 //show names of teammates & players carrying flags
3184 void show_HUD_names()
3185 {
3186         int show_team_names,show_all_names,show_flags,player_team;
3187         int p;
3188
3189         show_all_names = ((Newdemo_state == ND_STATE_PLAYBACK) || (Netgame.ShowAllNames && Show_reticle_name));
3190         show_team_names = (((Game_mode & GM_MULTI_COOP) || (Game_mode & GM_TEAM)) && Show_reticle_name);
3191         show_flags = (Game_mode & GM_CAPTURE) | (Game_mode & GM_HOARD);
3192
3193         if (! (show_all_names || show_team_names || show_flags))
3194                 return;
3195
3196         player_team = get_team(Player_num);
3197
3198         for (p=0;p<N_players;p++) {     //check all players
3199                 int objnum;
3200                 int show_name,has_flag;
3201
3202                 show_name = ((show_all_names && !(Players[p].flags & PLAYER_FLAGS_CLOAKED)) || (show_team_names && get_team(p)==player_team));
3203                 has_flag = (Players[p].connected && Players[p].flags & PLAYER_FLAGS_FLAG);
3204
3205                 if (Newdemo_state == ND_STATE_PLAYBACK) {
3206                         //if this is a demo, the objnum in the player struct is wrong,
3207                         //so we search the object list for the objnum
3208
3209                         for (objnum=0;objnum<=Highest_object_index;objnum++)
3210                                 if (Objects[objnum].type==OBJ_PLAYER && Objects[objnum].id == p)
3211                                         break;
3212                         if (objnum > Highest_object_index)              //not in list, thus not visible
3213                                 show_name = has_flag = 0;                               //..so don't show name
3214                 }
3215                 else
3216                         objnum = Players[p].objnum;
3217
3218                 if ((show_name || has_flag) && see_object(objnum)) {
3219                         g3s_point player_point;
3220
3221                         g3_rotate_point(&player_point,&Objects[objnum].pos);
3222
3223                         if (player_point.p3_codes == 0) {       //on screen
3224
3225                                 g3_project_point(&player_point);
3226
3227                                 if (! (player_point.p3_flags & PF_OVERFLOW)) {
3228                                         fix x,y;
3229                         
3230                                         x = player_point.p3_sx;
3231                                         y = player_point.p3_sy;
3232                         
3233                                         if (show_name) {                                // Draw callsign on HUD
3234                                                 char s[CALLSIGN_LEN+1];
3235                                                 int w, h, aw;
3236                                                 int x1, y1;
3237                                                 int color_num;
3238                         
3239                                                 color_num = (Game_mode & GM_TEAM)?get_team(p):p;
3240
3241                                                 sprintf(s, "%s", Players[p].callsign);
3242                                                 gr_get_string_size(s, &w, &h, &aw);
3243                                                 gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
3244                                                 x1 = f2i(x)-w/2;
3245                                                 y1 = f2i(y)-h/2;
3246                                                 gr_string (x1, y1, s);
3247                                         }
3248                 
3249                                         if (has_flag) {                         // Draw box on HUD
3250                                                 fix dx,dy,w,h;
3251                         
3252                                                 dy = -fixmuldiv(fixmul(Objects[objnum].size,Matrix_scale.y),i2f(grd_curcanv->cv_h)/2,player_point.p3_z);
3253                                                 dx = fixmul(dy,grd_curscreen->sc_aspect);
3254         
3255                                                 w = dx/4;
3256                                                 h = dy/4;
3257         
3258                                                 if (Game_mode & GM_CAPTURE)
3259                                                         gr_setcolor((get_team(p) == TEAM_BLUE)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3260                                                 else if (Game_mode & GM_HOARD)
3261                                                 {
3262                                                         if (Game_mode & GM_TEAM)
3263                                                                 gr_setcolor((get_team(p) == TEAM_RED)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
3264                                                         else
3265                                                                 gr_setcolor(BM_XRGB(0,31,0));
3266                                                 }
3267
3268                                                 gr_line(x+dx-w,y-dy,x+dx,y-dy);
3269                                                 gr_line(x+dx,y-dy,x+dx,y-dy+h);
3270         
3271                                                 gr_line(x-dx,y-dy,x-dx+w,y-dy);
3272                                                 gr_line(x-dx,y-dy,x-dx,y-dy+h);
3273         
3274                                                 gr_line(x+dx-w,y+dy,x+dx,y+dy);
3275                                                 gr_line(x+dx,y+dy,x+dx,y+dy-h);
3276         
3277                                                 gr_line(x-dx,y+dy,x-dx+w,y+dy);
3278                                                 gr_line(x-dx,y+dy,x-dx,y+dy-h);
3279                                         }
3280                                 }
3281                         }
3282                 }
3283         }
3284 }
3285 #endif
3286
3287
3288 //draw all the things on the HUD
3289 void draw_hud()
3290 {
3291
3292 #ifdef OGL
3293         if (Cockpit_mode==CM_STATUS_BAR){
3294                 //ogl needs to redraw every frame, at least currently.
3295                 //              init_cockpit();
3296                 //              last_drawn_cockpit[0]=-1;
3297                 //              last_drawn_cockpit[1]=-1;
3298                                   init_gauges();
3299                 
3300                                //              vr_reset_display();
3301         }
3302 #endif
3303                                           
3304
3305 #ifdef MACINTOSH
3306         if (Scanline_double)            // I should be shot for this ugly hack....
3307                 FontHires = 1;
3308 #endif
3309         Line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
3310 #ifdef MACINTOSH
3311         if (Scanline_double)
3312                 FontHires = 0;
3313 #endif
3314
3315 WIN(DDGRLOCK(dd_grd_curcanv));
3316         //      Show score so long as not in rearview
3317         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames) {
3318                 hud_show_score();
3319                 if (score_time)
3320                         hud_show_score_added();
3321         }
3322
3323         if ( !Rear_view && Cockpit_mode!=CM_REAR_VIEW && !Saving_movie_frames) 
3324          hud_show_timer_count();
3325
3326         //      Show other stuff if not in rearview or letterbox.
3327         if (!Rear_view && Cockpit_mode!=CM_REAR_VIEW) { // && Cockpit_mode!=CM_LETTERBOX) {
3328                 if (Cockpit_mode==CM_STATUS_BAR || Cockpit_mode==CM_FULL_SCREEN)
3329                         hud_show_homing_warning();
3330
3331                 if (Cockpit_mode==CM_FULL_SCREEN) {
3332                         hud_show_energy();
3333                         hud_show_shield();
3334                         hud_show_afterburner();
3335                         hud_show_weapons();
3336                         if (!Saving_movie_frames)
3337                                 hud_show_keys();
3338                         hud_show_cloak_invuln();
3339
3340                         if ( ( Newdemo_state==ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags[VR_current_page] )) {
3341                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3342                                 old_flags[VR_current_page] = Players[Player_num].flags;
3343                         }
3344                 }
3345
3346                 #ifdef NETWORK
3347                 #ifndef RELEASE
3348                 if (!(Game_mode&GM_MULTI && Show_kill_list) && !Saving_movie_frames)
3349                         show_time();
3350                 #endif
3351                 #endif
3352                 if (Reticle_on && Cockpit_mode != CM_LETTERBOX && (!Use_player_head_angles))
3353                         show_reticle(0);
3354
3355 #ifdef NETWORK
3356                 show_HUD_names();
3357
3358                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3359                         hud_show_flag();
3360
3361                 if (Cockpit_mode != CM_LETTERBOX && Cockpit_mode != CM_REAR_VIEW)
3362                         hud_show_orbs();
3363
3364 #endif
3365                 if (!Saving_movie_frames)
3366                         HUD_render_message_frame();
3367
3368                 if (Cockpit_mode!=CM_STATUS_BAR && !Saving_movie_frames)
3369                         hud_show_lives();
3370
3371                 #ifdef NETWORK
3372                 if (Game_mode&GM_MULTI && Show_kill_list)
3373                         hud_show_kill_list();
3374                 #endif
3375         }
3376
3377         if (Rear_view && Cockpit_mode!=CM_REAR_VIEW) {
3378                 HUD_render_message_frame();
3379                 gr_set_curfont( GAME_FONT );
3380                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
3381                 if (Newdemo_state == ND_STATE_PLAYBACK)
3382                         gr_printf(0x8000,grd_curcanv->cv_h-14,TXT_REAR_VIEW);
3383                 else
3384                         gr_printf(0x8000,grd_curcanv->cv_h-10,TXT_REAR_VIEW);
3385         }
3386 WIN(DDGRUNLOCK(dd_grd_curcanv));
3387 }
3388
3389 extern short *BackBuffer;
3390
3391 //print out some player statistics
3392 void render_gauges()
3393 {
3394 #ifndef MACINTOSH
3395         static int old_display_mode = 0;
3396 #else
3397         static int old_display_mode = 1;
3398 #endif
3399         int energy = f2ir(Players[Player_num].energy);
3400         int shields = f2ir(Players[Player_num].shields);
3401         int cloak = ((Players[Player_num].flags&PLAYER_FLAGS_CLOAKED) != 0);
3402         int frc=0;
3403  
3404    PA_DFX (frc=0);
3405    PA_DFX (pa_set_backbuffer_current());
3406
3407         Assert(Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR);
3408
3409 // check to see if our display mode has changed since last render time --
3410 // if so, then we need to make new gauge canvases.
3411
3412   
3413         if (old_display_mode != Current_display_mode) {
3414                 close_gauge_canvases();
3415                 init_gauge_canvases();
3416                 old_display_mode = Current_display_mode;
3417         }
3418
3419         if (shields < 0 ) shields = 0;
3420
3421         WINDOS(
3422                 dd_gr_set_current_canvas(get_current_game_screen()),
3423                 gr_set_current_canvas(get_current_game_screen())
3424         );
3425         gr_set_curfont( GAME_FONT );
3426
3427         if (Newdemo_state == ND_STATE_RECORDING)
3428                 if (Players[Player_num].homing_object_dist >= 0)
3429                         newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
3430
3431         if (Cockpit_mode == CM_FULL_COCKPIT) {
3432                 if (energy != old_energy[VR_current_page]) {
3433                         if (Newdemo_state==ND_STATE_RECORDING ) {
3434                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3435                         }
3436                         draw_energy_bar(energy);
3437                         draw_numerical_display(shields, energy);
3438                         old_energy[VR_current_page] = energy;
3439                 }
3440
3441                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
3442                         if (Newdemo_state==ND_STATE_RECORDING ) {
3443                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3444                         }
3445                         draw_afterburner_bar(Afterburner_charge);
3446                         old_afterburner[VR_current_page] = Afterburner_charge;
3447                 }
3448
3449                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3450                         draw_numerical_display(shields, energy);
3451                         draw_invulnerable_ship();
3452                         old_shields[VR_current_page] = shields ^ 1;
3453                 } else if (shields != old_shields[VR_current_page]) {           // Draw the shield gauge
3454                         if (Newdemo_state==ND_STATE_RECORDING ) {
3455                                 newdemo_record_player_shields(old_shields[VR_current_page], shields);
3456                         }
3457                         draw_shield_bar(shields);
3458                         draw_numerical_display(shields, energy);
3459                         old_shields[VR_current_page] = shields;
3460                 }
3461         
3462                 if (Players[Player_num].flags != old_flags[VR_current_page]) {
3463                         if (Newdemo_state==ND_STATE_RECORDING )
3464                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3465                         draw_keys();
3466                         old_flags[VR_current_page] = Players[Player_num].flags;
3467                 }
3468
3469                 show_homing_warning();
3470
3471                 show_bomb_count(BOMB_COUNT_X,BOMB_COUNT_Y,gr_find_closest_color(0,0,0),0);
3472         
3473         } else if (Cockpit_mode == CM_STATUS_BAR) {
3474
3475                 if (energy != old_energy[VR_current_page] || frc)  {
3476                         if (Newdemo_state==ND_STATE_RECORDING ) {
3477                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3478                         }
3479                         sb_draw_energy_bar(energy);
3480                         old_energy[VR_current_page] = energy;
3481                 }
3482
3483                 if (Afterburner_charge != old_afterburner[VR_current_page] || frc) {
3484                         if (Newdemo_state==ND_STATE_RECORDING ) {
3485                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3486                         }
3487                         sb_draw_afterburner();
3488                         old_afterburner[VR_current_page] = Afterburner_charge;
3489                 }
3490         
3491                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3492                         draw_invulnerable_ship();
3493                         old_shields[VR_current_page] = shields ^ 1;
3494                         sb_draw_shield_num(shields);
3495                 } 
3496                 else 
3497                         if (shields != old_shields[VR_current_page] || frc) {           // Draw the shield gauge
3498                                 if (Newdemo_state==ND_STATE_RECORDING ) {
3499                                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
3500                                 }
3501                                 sb_draw_shield_bar(shields);
3502                                 old_shields[VR_current_page] = shields;
3503                                 sb_draw_shield_num(shields);
3504                         }
3505
3506                 if (Players[Player_num].flags != old_flags[VR_current_page] || frc) {
3507                         if (Newdemo_state==ND_STATE_RECORDING )
3508                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3509                         sb_draw_keys();
3510                         old_flags[VR_current_page] = Players[Player_num].flags;
3511                 }
3512         
3513
3514                 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3515                 {
3516                         if (Players[Player_num].net_killed_total != old_lives[VR_current_page] || frc) {
3517                                 sb_show_lives();
3518                                 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
3519                         }
3520                 }
3521                 else
3522                 {
3523                         if (Players[Player_num].lives != old_lives[VR_current_page] || frc) {
3524                                 sb_show_lives();
3525                                 old_lives[VR_current_page] = Players[Player_num].lives;
3526                         }
3527                 }
3528
3529                 if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) {
3530                         if (Players[Player_num].net_kills_total != old_score[VR_current_page] || frc) {
3531                                 sb_show_score();
3532                                 old_score[VR_current_page] = Players[Player_num].net_kills_total;
3533                         }
3534                 }
3535                 else {
3536                         if (Players[Player_num].score != old_score[VR_current_page] || frc) {
3537                                 sb_show_score();
3538                                 old_score[VR_current_page] = Players[Player_num].score;
3539                         }
3540
3541                         //if (score_time)
3542                                 sb_show_score_added();
3543                 }
3544
3545                 show_bomb_count(SB_BOMB_COUNT_X,SB_BOMB_COUNT_Y,gr_find_closest_color(5,5,5),0);
3546         }
3547
3548         if (frc || cloak != old_cloak[VR_current_page] || cloak_fade_state || (cloak && GameTime>Players[Player_num].cloak_time+CLOAK_TIME_MAX-i2f(3))) {
3549                 if (Cockpit_mode == CM_FULL_COCKPIT)
3550                         draw_player_ship(cloak,old_cloak[VR_current_page],SHIP_GAUGE_X,SHIP_GAUGE_Y);
3551                 else
3552                         draw_player_ship(cloak,old_cloak[VR_current_page],SB_SHIP_GAUGE_X,SB_SHIP_GAUGE_Y);
3553
3554                 old_cloak[VR_current_page]=cloak;
3555         }
3556
3557
3558         draw_weapon_boxes();
3559
3560 }
3561
3562 //      ---------------------------------------------------------------------------------------------------------
3563 //      Call when picked up a laser powerup.
3564 //      If laser is active, set old_weapon[0] to -1 to force redraw.
3565 void update_laser_weapon_info(void)
3566 {
3567         if (old_weapon[0][VR_current_page] == 0)
3568                 if (! (Players[Player_num].laser_level > MAX_LASER_LEVEL && old_laser_level[VR_current_page] <= MAX_LASER_LEVEL))
3569                         old_weapon[0][VR_current_page] = -1;
3570 }
3571
3572 extern int Game_window_y;
3573 void fill_background(void);
3574
3575 int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
3576
3577 //draws a 3d view into one of the cockpit windows.  win is 0 for left,
3578 //1 for right.  viewer is object.  NULL object means give up window
3579 //user is one of the WBU_ constants.  If rear_view_flag is set, show a
3580 //rear view.  If label is non-NULL, print the label at the top of the
3581 //window.
3582 void do_cockpit_window_view(int win,object *viewer,int rear_view_flag,int user,char *label)
3583 {
3584         WINDOS(
3585                 dd_grs_canvas window_canv,
3586                 grs_canvas window_canv
3587         );
3588         WINDOS(
3589                 static dd_grs_canvas overlap_canv,
3590                 static grs_canvas overlap_canv
3591         );
3592
3593 #ifdef WINDOWS
3594         int saved_window_x, saved_window_y;
3595 #endif
3596
3597         object *viewer_save = Viewer;
3598         static int overlap_dirty[2]={0,0};
3599         int boxnum;
3600         static int window_x,window_y;
3601         gauge_box *box;
3602         int rear_view_save = Rear_view;
3603         int w,h,dx;
3604
3605         box = NULL;
3606
3607         if (viewer == NULL) {                                                           //this user is done
3608
3609                 Assert(user == WBU_WEAPON || user == WBU_STATIC);
3610
3611                 if (user == WBU_STATIC && weapon_box_user[win] != WBU_STATIC)
3612                         static_time[win] = 0;
3613
3614                 if (weapon_box_user[win] == WBU_WEAPON || weapon_box_user[win] == WBU_STATIC)
3615                         return;         //already set
3616
3617                 weapon_box_user[win] = user;
3618
3619                 if (overlap_dirty[win]) {
3620                 WINDOS(
3621                         dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
3622                         gr_set_current_canvas(&VR_screen_pages[VR_current_page])
3623                 );
3624                         fill_background();
3625                         overlap_dirty[win] = 0;
3626                 }
3627
3628                 return;
3629         }
3630
3631         update_rendered_data(win+1, viewer, rear_view_flag, user);
3632
3633         weapon_box_user[win] = user;                                            //say who's using window
3634                 
3635         Viewer = viewer;
3636         Rear_view = rear_view_flag;
3637
3638         if (Cockpit_mode == CM_FULL_SCREEN)
3639         {
3640
3641                 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
3642                 #ifdef MACINTOSH
3643                 if (Scanline_double)
3644                         w /= 2;
3645                 #endif
3646
3647                 h = i2f(w) / grd_curscreen->sc_aspect;
3648
3649                 dx = (win==0)?-(w+(w/10)):(w/10);
3650
3651                 window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3652                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3653
3654         #ifdef WINDOWS
3655                 saved_window_x = window_x;
3656                 saved_window_y = window_y;
3657                 window_x = dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w/2+dx;
3658                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10)-dd_VR_render_sub_buffer[0].yoff;
3659         #endif
3660
3661                 #ifdef MACINTOSH
3662                 if (Scanline_double) {
3663                         window_x = (VR_render_buffer[0].cv_bitmap.bm_w/2+VR_render_sub_buffer[0].cv_bitmap.bm_x)/2+dx;
3664                         window_y = ((VR_render_buffer[0].cv_bitmap.bm_h+VR_render_sub_buffer[0].cv_bitmap.bm_y)/2)-h-(h/10);
3665                 }
3666                 #endif
3667
3668                 //copy these vars so stereo code can get at them
3669                 SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3670
3671         WINDOS(
3672                 dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,w,h),
3673                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],window_x,window_y,w,h)
3674         );
3675         }
3676         else {
3677                 if (Cockpit_mode == CM_FULL_COCKPIT)
3678                         boxnum = (COCKPIT_PRIMARY_BOX)+win;
3679                 else if (Cockpit_mode == CM_STATUS_BAR)
3680                         boxnum = (SB_PRIMARY_BOX)+win;
3681                 else
3682                         goto abort;
3683
3684                 box = &gauge_boxes[boxnum];
3685
3686                 #ifndef MACINTOSH
3687         WINDOS(                                                           
3688                 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),
3689                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1)
3690         );
3691                 #else
3692                 if (Scanline_double)
3693                         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);
3694                 else
3695                         gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1);
3696                 #endif
3697         }
3698
3699 WINDOS(
3700         dd_gr_set_current_canvas(&window_canv),
3701         gr_set_current_canvas(&window_canv)
3702 );
3703         
3704         #if defined(MACINTOSH) && defined(POLY_ACC)
3705         if ( PAEnabled )
3706         {
3707                 switch (Cockpit_mode)
3708                 {
3709                 // copy these vars so stereo code can get at them
3710                 // SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3711                         case CM_FULL_SCREEN:
3712                                 ;       // do not switch contexts
3713                                 pa_set_3d_window_offsets(window_x, window_y);
3714                                 break;
3715                         case CM_FULL_COCKPIT:
3716                         case CM_STATUS_BAR:
3717                                 if (win == 0)
3718                                 {
3719                                         pa_set_context(kSubViewZeroDrawContextID, NULL);
3720                                 }
3721                                 else
3722                                 {
3723                                         pa_set_context(kSubViewOneDrawContextID, NULL);
3724                                 }
3725                                 break;
3726                         default:
3727                                 Int3(); // invalid cockpit mode
3728                 };
3729         }
3730         #endif
3731
3732         WIN(DDGRLOCK(dd_grd_curcanv));
3733         
3734                 #ifdef MACINTOSH
3735                         #ifdef POLY_ACC
3736                                 if (PAEnabled)
3737                                 {
3738                                         if (Cockpit_mode != CM_FULL_SCREEN)
3739                                         {
3740                                                 pa_render_start();
3741                                         }
3742                                 }
3743                         #endif
3744                 #endif 
3745                 
3746                 render_frame(0, win+1);
3747                 
3748                 #ifdef MACINTOSH
3749                         #ifdef POLY_ACC
3750                                 if (PAEnabled)
3751                                 {
3752                                         if (Cockpit_mode != CM_FULL_SCREEN)
3753                                         {
3754                                                 pa_render_end();
3755                                         }
3756                                 }
3757                         #endif
3758                 #endif 
3759
3760         WIN(DDGRUNLOCK(dd_grd_curcanv));
3761
3762         //      HACK! If guided missile, wake up robots as necessary.
3763         if (viewer->type == OBJ_WEAPON) {
3764                 // -- Used to require to be GUIDED -- if (viewer->id == GUIDEDMISS_ID)
3765                 wake_up_rendered_objects(viewer, win+1);
3766         }
3767
3768         if (label) {
3769         WIN(DDGRLOCK(dd_grd_curcanv));
3770         MAC(if (Scanline_double) FontHires = 0;)                // get the right font size
3771                 gr_set_curfont( GAME_FONT );
3772                 if (Color_0_31_0 == -1)
3773                         Color_0_31_0 = gr_getcolor(0,31,0);
3774                 gr_set_fontcolor(Color_0_31_0, -1);
3775                 gr_printf(0x8000,2,label);
3776         MAC(if (Scanline_double) FontHires = 1;)                // get the right font size back to normal
3777         WIN(DDGRUNLOCK(dd_grd_curcanv));
3778         }
3779
3780         if (user == WBU_GUIDED) {
3781         WIN(DDGRLOCK(dd_grd_curcanv));
3782                 draw_guided_crosshair();
3783         WIN(DDGRUNLOCK(dd_grd_curcanv));
3784         }
3785
3786         if (Cockpit_mode == CM_FULL_SCREEN) {
3787                 int small_window_bottom,big_window_bottom,extra_part_h;
3788                 
3789                 WIN(DDGRLOCK(dd_grd_curcanv));
3790                 {
3791                         gr_setcolor(BM_XRGB(0,0,32));
3792                         gr_ubox(0,0,grd_curcanv->cv_bitmap.bm_w-1,grd_curcanv->cv_bitmap.bm_h-1);
3793                 }
3794                 WIN(DDGRUNLOCK(dd_grd_curcanv));
3795
3796                 //if the window only partially overlaps the big 3d window, copy
3797                 //the extra part to the visible screen
3798
3799                 #ifdef MACINTOSH                // recalc window_x and window_y because of scanline doubling problems
3800                 {
3801                         int w, h, dx;
3802                         
3803                         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
3804                         h = i2f(w) / grd_curscreen->sc_aspect;
3805                         dx = (win==0)?-(w+(w/10)):(w/10);
3806                         window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3807                         window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3808                         if (Scanline_double)
3809                                 window_x += ((win==0)?2:-1);            // a real hack here....
3810                 }
3811                 #endif
3812                 big_window_bottom = Game_window_y + Game_window_h - 1;
3813
3814         #ifdef WINDOWS
3815                 window_x = saved_window_x;
3816                 window_y = saved_window_y;
3817 //              dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,
3818 //                                              VR_render_buffer[0].cv_bitmap.bm_w/6,
3819 //                                              i2f(VR_render_buffer[0].cv_bitmap.bm_w/6) / grd_curscreen->sc_aspect);
3820
3821         #endif
3822
3823                 if (window_y > big_window_bottom) {
3824
3825                         //the small window is completely outside the big 3d window, so
3826                         //copy it to the visible screen
3827
3828                         if (VR_screen_flags & VRF_USE_PAGING)
3829                                 WINDOS(
3830                                         dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
3831                                         gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
3832                                 );
3833                         else
3834                                 WINDOS(
3835                                         dd_gr_set_current_canvas(get_current_game_screen()),
3836                                         gr_set_current_canvas(get_current_game_screen())
3837                                 );
3838
3839                         #ifdef MACINTOSH
3840                         if (Scanline_double)
3841                                 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);
3842                         else
3843                         #endif          // note link to above if
3844                         WINDOS(
3845                                 dd_gr_blt_notrans(&window_canv, 0,0,0,0,
3846                                                                                 dd_grd_curcanv, window_x, window_y, 0,0),
3847                                 gr_bitmap(window_x,window_y,&window_canv.cv_bitmap)
3848                         );
3849
3850                         overlap_dirty[win] = 1;
3851                 }
3852                 else {
3853
3854                 WINDOS(
3855                         small_window_bottom = window_y + window_canv.canvas.cv_bitmap.bm_h - 1,
3856                         small_window_bottom = window_y + window_canv.cv_bitmap.bm_h - 1
3857                 );
3858                         #ifdef MACINTOSH
3859                         if (Scanline_double)
3860                                 small_window_bottom = window_y + (window_canv.cv_bitmap.bm_h*2) - 1;
3861                         #endif
3862                         
3863                         extra_part_h = small_window_bottom - big_window_bottom;
3864
3865                         if (extra_part_h > 0) {
3866                         
3867                                 #ifdef MACINTOSH
3868                                 if (Scanline_double)
3869                                         extra_part_h /= 2;
3870                                 #endif
3871         
3872                                 WINDOS(
3873                                         dd_gr_init_sub_canvas(&overlap_canv,&window_canv,0,
3874                                                 window_canv.canvas.cv_bitmap.bm_h-extra_part_h,
3875                                                 window_canv.canvas.cv_bitmap.bm_w,extra_part_h),
3876                                         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)
3877                                 );
3878
3879                                 if (VR_screen_flags & VRF_USE_PAGING)
3880                                         WINDOS(
3881                                                 dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
3882                                                 gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
3883                                         );
3884                                 else
3885                                         WINDOS(
3886                                                 dd_gr_set_current_canvas(get_current_game_screen()),
3887                                                 gr_set_current_canvas(get_current_game_screen())
3888                                         );
3889
3890                                 #ifdef MACINTOSH
3891                                 if (Scanline_double)
3892                                         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);
3893                                 else
3894                                 #endif          // note link to above if
3895                                 WINDOS(
3896                                         dd_gr_blt_notrans(&overlap_canv, 0,0,0,0,
3897                                                                                         dd_grd_curcanv, window_x, big_window_bottom+1, 0,0),
3898                                         gr_bitmap(window_x,big_window_bottom+1,&overlap_canv.cv_bitmap)
3899                                 );
3900                                 
3901                                 overlap_dirty[win] = 1;
3902                         }
3903                 }
3904         }
3905         else {
3906         PA_DFX (goto skip_this_junk);
3907         
3908         WINDOS(
3909                 dd_gr_set_current_canvas(get_current_game_screen()),
3910                 gr_set_current_canvas(get_current_game_screen())
3911         );
3912         #ifndef MACINTOSH
3913         WINDOS(
3914                 copy_gauge_box(box,&dd_VR_render_buffer[0]),
3915                 copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap)
3916         );
3917         #else
3918         if (Scanline_double)
3919                 copy_gauge_box_double(box,&VR_render_buffer[0].cv_bitmap);              // pixel double the external view
3920         else
3921                 // Only do this if we are not running under RAVE, otherwise we erase all of the rendering RAVE has done.
3922                 if (!PAEnabled)
3923                 {
3924                         copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap);
3925                 }
3926         #endif
3927         }
3928
3929   PA_DFX(skip_this_junk:)
3930   
3931         #if defined(MACINTOSH) && defined(POLY_ACC)
3932         if ( PAEnabled )
3933         {
3934                 pa_set_context(kGamePlayDrawContextID, NULL);
3935         }
3936         #endif
3937
3938         //force redraw when done
3939         old_weapon[win][VR_current_page] = old_ammo_count[win][VR_current_page] = -1;
3940
3941 abort:;
3942
3943         Viewer = viewer_save;
3944
3945         Rear_view = rear_view_save;
3946 }
3947
3948 #ifdef MACINTOSH
3949         void calculate_sub_view_window_bounds(int inSubWindowNum, TQARect* outBoundsRect)
3950         {
3951                 int             boxNumber               = 0;
3952                 gauge_box*      currentGaugeBox = NULL;
3953                 int w   = 0;
3954                 int h   = 0;
3955                 int dx  = 0;
3956                 int window_x = 0;
3957                 int window_y = 0;
3958
3959                 Assert(outBoundsRect);
3960                 Assert((inSubWindowNum == 0) || (inSubWindowNum == 1));
3961                 Assert(!Scanline_double);
3962                 
3963                 switch (Cockpit_mode)
3964                 {
3965                         case CM_FULL_SCREEN:
3966                                 // note: this calculation is taken from do_cockpit_window_view for the full
3967                                 // screen mode case
3968