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