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