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