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