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