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