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