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