]> icculus.org git repositories - btb/d2x.git/blob - main/gauges.c
set builtin_hogsize for non-built-in missions
[btb/d2x.git] / main / gauges.c
1 /* $Id: gauges.c,v 1.11 2004-08-28 23:17:45 schaffner 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];
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                 gr_set_curfont( GAME_FONT );
1085                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1086
1087                 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1088                         {
1089                          PA_DFX(pa_set_frontbuffer_current()); 
1090           PA_DFX(gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS)); 
1091           PA_DFX(pa_set_backbuffer_current()); 
1092                          gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS);
1093                         }
1094                 else
1095                   {
1096                    PA_DFX (pa_set_frontbuffer_current() );
1097                         PA_DFX (gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE) );
1098          PA_DFX(pa_set_backbuffer_current()); 
1099                         gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE);
1100                   }
1101         }
1102
1103         gr_set_curfont( GAME_FONT );
1104         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1105                 sprintf(score_str, "%5d", Players[Player_num].net_kills_total);
1106         else
1107                 sprintf(score_str, "%5d", Players[Player_num].score);
1108         gr_get_string_size(score_str, &w, &h, &aw );
1109
1110         x = SB_SCORE_RIGHT-w-LHX(2);
1111         y = SB_SCORE_Y;
1112         
1113         //erase old score
1114         gr_setcolor(BM_XRGB(0,0,0));
1115    PA_DFX (pa_set_frontbuffer_current());
1116         PA_DFX (gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h));
1117    PA_DFX(pa_set_backbuffer_current()); 
1118         gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page],y,SB_SCORE_RIGHT,y+GAME_FONT->ft_h);
1119
1120         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1121                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1122         else
1123                 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );      
1124  
1125    PA_DFX (pa_set_frontbuffer_current());
1126         PA_DFX (gr_printf(x,y,score_str));
1127    PA_DFX(pa_set_backbuffer_current()); 
1128         gr_printf(x,y,score_str);
1129
1130         last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1131 WIN(DDGRUNLOCK(dd_grd_curcanv));
1132 }
1133
1134 void sb_show_score_added()
1135 {
1136         int     color;
1137         int w, h, aw;
1138         char    score_str[32];
1139         int x;
1140         static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1141         static  int last_score_display[2] = { -1, -1};
1142    int frc=0;
1143         PA_DFX (frc=0);
1144         
1145         if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) ) 
1146                 return;
1147
1148         if (score_display[VR_current_page] == 0)
1149                 return;
1150
1151 WIN(DDGRLOCK(dd_grd_curcanv));
1152         gr_set_curfont( GAME_FONT );
1153
1154         score_time -= FrameTime;
1155         if (score_time > 0) {
1156                 if (score_display[VR_current_page] != last_score_display[VR_current_page] || frc) {
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    int frc=0;
1697         x = SB_LIVES_X;
1698         y = SB_LIVES_Y;
1699   
1700    PA_DFX (frc=0);
1701
1702         WIN(DDGRLOCK(dd_grd_curcanv));
1703         if (old_lives[VR_current_page]==-1 || frc) {
1704                 gr_set_curfont( GAME_FONT );
1705                 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1706                 if (Game_mode & GM_MULTI)
1707                  {
1708                    PA_DFX (pa_set_frontbuffer_current());
1709                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS));
1710                    PA_DFX (pa_set_backbuffer_current());
1711                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS);
1712
1713                  }
1714                 else
1715                   {
1716                    PA_DFX (pa_set_frontbuffer_current());
1717                         PA_DFX (gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES));
1718                    PA_DFX (pa_set_backbuffer_current());
1719                         gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES);
1720                  }
1721
1722         }
1723 WIN(DDGRUNLOCK(dd_grd_curcanv));
1724
1725         if (Game_mode & GM_MULTI)
1726         {
1727                 char killed_str[20];
1728                 int w, h, aw;
1729                 static int last_x[4] = {SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1730                 int x;
1731
1732         WIN(DDGRLOCK(dd_grd_curcanv));
1733                 sprintf(killed_str, "%5d", Players[Player_num].net_killed_total);
1734                 gr_get_string_size(killed_str, &w, &h, &aw);
1735                 gr_setcolor(BM_XRGB(0,0,0));
1736                 gr_rect(last_x[(Current_display_mode?2:0)+VR_current_page], y+1, SB_SCORE_RIGHT, y+GAME_FONT->ft_h);
1737                 gr_set_fontcolor(gr_getcolor(0,20,0),-1);
1738                 x = SB_SCORE_RIGHT-w-2;         
1739                 gr_printf(x, y+1, killed_str);
1740                 last_x[(Current_display_mode?2:0)+VR_current_page] = x;
1741         WIN(DDGRUNLOCK(dd_grd_curcanv));
1742                 return;
1743         }
1744
1745         if (frc || old_lives[VR_current_page]==-1 || Players[Player_num].lives != old_lives[VR_current_page]) {
1746         WIN(DDGRLOCK(dd_grd_curcanv));
1747
1748                 //erase old icons
1749
1750                 gr_setcolor(BM_XRGB(0,0,0));
1751       
1752       PA_DFX (pa_set_frontbuffer_current());
1753            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
1754       PA_DFX (pa_set_backbuffer_current());
1755            gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
1756
1757                 if (Players[Player_num].lives-1 > 0) {
1758                         gr_set_curfont( GAME_FONT );
1759                         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1760                         PAGE_IN_GAUGE( GAUGE_LIVES );
1761                         #ifdef PA_3DFX_VOODOO
1762                       PA_DFX (pa_set_frontbuffer_current());
1763                                 gr_ubitmapm(x, y,bm);
1764                                 gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
1765                         #endif
1766
1767               PA_DFX (pa_set_backbuffer_current());
1768                         gr_ubitmapm(x, y,bm);
1769                         gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
1770
1771 //                      gr_printf(x+12, y, "x %d", Players[Player_num].lives-1);
1772                 }
1773         WIN(DDGRUNLOCK(dd_grd_curcanv));
1774         }
1775
1776 //      for (i=0;i<draw_count;i++,x+=bm->bm_w+2)
1777 //              gr_ubitmapm(x,y,bm);
1778
1779 }
1780
1781 #ifndef RELEASE
1782
1783 #ifdef PIGGY_USE_PAGING
1784 extern int Piggy_bitmap_cache_next;
1785 #endif
1786
1787 void show_time()
1788 {
1789         int secs = f2i(Players[Player_num].time_level) % 60;
1790         int mins = f2i(Players[Player_num].time_level) / 60;
1791
1792         gr_set_curfont( GAME_FONT );
1793
1794         if (Color_0_31_0 == -1)
1795                 Color_0_31_0 = gr_getcolor(0,31,0);
1796         gr_set_fontcolor(Color_0_31_0, -1 );
1797
1798         gr_printf(grd_curcanv->cv_w-4*GAME_FONT->ft_w,grd_curcanv->cv_h-4*Line_spacing,"%d:%02d", mins, secs);
1799
1800 //@@#ifdef PIGGY_USE_PAGING
1801 //@@    {
1802 //@@            char text[25];
1803 //@@            int w,h,aw;
1804 //@@            sprintf( text, "%d KB", Piggy_bitmap_cache_next/1024 );
1805 //@@            gr_get_string_size( text, &w, &h, &aw );        
1806 //@@            gr_printf(grd_curcanv->cv_w-10-w,grd_curcanv->cv_h/2, text );
1807 //@@    }
1808 //@@#endif
1809
1810 }
1811 #endif
1812
1813 #define EXTRA_SHIP_SCORE        50000           //get new ship every this many points
1814
1815 void add_points_to_score(int points) 
1816 {
1817         int prev_score;
1818
1819         score_time += f1_0*2;
1820         score_display[0] += points;
1821         score_display[1] += points;
1822         if (score_time > f1_0*4) score_time = f1_0*4;
1823
1824         if (points == 0 || Cheats_enabled)
1825                 return;
1826
1827         if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
1828                 return;
1829
1830         prev_score=Players[Player_num].score;
1831
1832         Players[Player_num].score += points;
1833
1834         if (Newdemo_state == ND_STATE_RECORDING)
1835                 newdemo_record_player_score(points);
1836
1837 #ifdef NETWORK
1838         if (Game_mode & GM_MULTI_COOP)
1839                 multi_send_score();
1840
1841         if (Game_mode & GM_MULTI)
1842                 return;
1843 #endif
1844
1845         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1846                 int snd;
1847                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1848                 powerup_basic(20, 20, 20, 0, TXT_EXTRA_LIFE);
1849                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1850                         digi_play_sample( snd, F1_0 );
1851         }
1852 }
1853
1854 void add_bonus_points_to_score(int points) 
1855 {
1856         int prev_score;
1857
1858         if (points == 0 || Cheats_enabled)
1859                 return;
1860
1861         prev_score=Players[Player_num].score;
1862
1863         Players[Player_num].score += points;
1864
1865
1866         if (Newdemo_state == ND_STATE_RECORDING)
1867                 newdemo_record_player_score(points);
1868
1869         if (Game_mode & GM_MULTI)
1870                 return;
1871
1872         if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1873                 int snd;
1874                 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1875                 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1876                         digi_play_sample( snd, F1_0 );
1877         }
1878 }
1879
1880 #include "key.h"
1881
1882 void init_gauge_canvases()
1883 {
1884         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
1885         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
1886
1887         Canv_LeftEnergyGauge = gr_create_canvas( LEFT_ENERGY_GAUGE_W, LEFT_ENERGY_GAUGE_H );
1888         Canv_SBEnergyGauge = gr_create_canvas( SB_ENERGY_GAUGE_W, SB_ENERGY_GAUGE_H );
1889         Canv_SBAfterburnerGauge = gr_create_canvas( SB_AFTERBURNER_GAUGE_W, SB_AFTERBURNER_GAUGE_H );
1890         Canv_RightEnergyGauge = gr_create_canvas( RIGHT_ENERGY_GAUGE_W, RIGHT_ENERGY_GAUGE_H );
1891         Canv_NumericalGauge = gr_create_canvas( NUMERICAL_GAUGE_W, NUMERICAL_GAUGE_H );
1892         Canv_AfterburnerGauge = gr_create_canvas( AFTERBURNER_GAUGE_W, AFTERBURNER_GAUGE_H );
1893
1894 }
1895
1896 void close_gauge_canvases()
1897 {
1898         gr_free_canvas( Canv_LeftEnergyGauge );
1899         gr_free_canvas( Canv_SBEnergyGauge );
1900         gr_free_canvas( Canv_SBAfterburnerGauge );
1901         gr_free_canvas( Canv_RightEnergyGauge );
1902         gr_free_canvas( Canv_NumericalGauge );
1903         gr_free_canvas( Canv_AfterburnerGauge );
1904 }
1905
1906 void init_gauges()
1907 {
1908         int i;
1909
1910         //draw_gauges_on        = 1;
1911
1912         for (i=0; i<2; i++ )    {
1913                 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)) ) 
1914                         old_score[i] = -99;
1915                 else
1916                         old_score[i]                    = -1;
1917                 old_energy[i]                   = -1;
1918                 old_shields[i]                  = -1;
1919                 old_flags[i]                    = -1;
1920                 old_cloak[i]                    = -1;
1921                 old_lives[i]                    = -1;
1922                 old_afterburner[i]      = -1;
1923                 old_bombcount[i]                = 0;
1924                 old_laser_level[i]      = 0;
1925         
1926                 old_weapon[0][i] = old_weapon[1][i] = -1;
1927                 old_ammo_count[0][i] = old_ammo_count[1][i] = -1;
1928                 Old_Omega_charge[i] = -1;
1929         }
1930
1931         cloak_fade_state = 0;
1932
1933         weapon_box_user[0] = weapon_box_user[1] = WBU_WEAPON;
1934 }
1935
1936 void draw_energy_bar(int energy)
1937 {
1938         int not_energy;
1939         int x1, x2, y;
1940
1941         // Draw left energy bar
1942         gr_set_current_canvas( Canv_LeftEnergyGauge );
1943         PAGE_IN_GAUGE( GAUGE_ENERGY_LEFT );
1944         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_LEFT)] );
1945         gr_setcolor( BM_XRGB(0,0,0) );
1946
1947         if ( !Current_display_mode )
1948                 not_energy = 61 - (energy*61)/100;
1949         else
1950                 not_energy = 125 - (energy*125)/100;
1951
1952         if (energy < 100)
1953                 for (y=0; y < LEFT_ENERGY_GAUGE_H; y++) {
1954                         x1 = LEFT_ENERGY_GAUGE_H - 1 - y;
1955                         x2 = LEFT_ENERGY_GAUGE_H - 1 - y + not_energy;
1956         
1957                         if ( y>=0 && y<(LEFT_ENERGY_GAUGE_H/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 1) x2 = LEFT_ENERGY_GAUGE_W - 1;
1958                         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;
1959                         if ( y>=((LEFT_ENERGY_GAUGE_H*3)/4) ) if (x2 > LEFT_ENERGY_GAUGE_W - 3) x2 = LEFT_ENERGY_GAUGE_W - 3;
1960                         
1961                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
1962                 }
1963         
1964         WINDOS(
1965                 dd_gr_set_current_canvas(get_current_game_screen()),
1966                 gr_set_current_canvas( get_current_game_screen() )
1967         );
1968         WIN(DDGRLOCK(dd_grd_curcanv));
1969                 gr_ubitmapm( LEFT_ENERGY_GAUGE_X, LEFT_ENERGY_GAUGE_Y, &Canv_LeftEnergyGauge->cv_bitmap );
1970         WIN(DDGRUNLOCK(dd_grd_curcanv));
1971
1972         // Draw right energy bar
1973         gr_set_current_canvas( Canv_RightEnergyGauge );
1974         PAGE_IN_GAUGE( GAUGE_ENERGY_RIGHT );
1975         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_RIGHT) ] );
1976         gr_setcolor( BM_XRGB(0,0,0) );
1977
1978         if (energy < 100)
1979                 for (y=0; y < RIGHT_ENERGY_GAUGE_H; y++) {
1980                         x1 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y - not_energy;
1981                         x2 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + y;
1982         
1983                         if ( y>=0 && y<(RIGHT_ENERGY_GAUGE_H/4) ) if (x1 < 0) x1 = 0;
1984                         if ( y>=(RIGHT_ENERGY_GAUGE_H/4) && y<((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 1) x1 = 1;
1985                         if ( y>=((RIGHT_ENERGY_GAUGE_H*3)/4) ) if (x1 < 2) x1 = 2;
1986                         
1987                         if (x2 > x1) gr_uscanline( x1, x2, y ); 
1988                 }
1989
1990         WINDOS(
1991                 dd_gr_set_current_canvas(get_current_game_screen()),
1992                 gr_set_current_canvas( get_current_game_screen() )
1993         );
1994         WIN(DDGRLOCK(dd_grd_curcanv));
1995                 gr_ubitmapm( RIGHT_ENERGY_GAUGE_X, RIGHT_ENERGY_GAUGE_Y, &Canv_RightEnergyGauge->cv_bitmap );
1996         WIN(DDGRUNLOCK(dd_grd_curcanv));
1997 }
1998
1999 ubyte afterburner_bar_table[AFTERBURNER_GAUGE_H_L*2] = {
2000                         3,11,
2001                         3,11,
2002                         3,11,
2003                         3,11,
2004                         3,11,
2005                         3,11,
2006                         2,11,
2007                         2,10,
2008                         2,10,
2009                         2,10,
2010                         2,10,
2011                         2,10,
2012                         2,10,
2013                         1,10,
2014                         1,10,
2015                         1,10,
2016                         1,9,
2017                         1,9,
2018                         1,9,
2019                         1,9,
2020                         0,9,
2021                         0,9,
2022                         0,8,
2023                         0,8,
2024                         0,8,
2025                         0,8,
2026                         1,8,
2027                         2,8,
2028                         3,8,
2029                         4,8,
2030                         5,8,
2031                         6,7,
2032 };
2033
2034 ubyte afterburner_bar_table_hires[AFTERBURNER_GAUGE_H_H*2] = {
2035         5,20,
2036         5,20,
2037         5,19,
2038         5,19,
2039         5,19,
2040         5,19,
2041         4,19,
2042         4,19,
2043         4,19,
2044         4,19,
2045
2046         4,19,
2047         4,18,
2048         4,18,
2049         4,18,
2050         4,18,
2051         3,18,
2052         3,18,
2053         3,18,
2054         3,18,
2055         3,18,
2056
2057         3,18,
2058         3,17,
2059         3,17,
2060         2,17,
2061         2,17,
2062         2,17,
2063         2,17,
2064         2,17,
2065         2,17,
2066         2,17,
2067
2068         2,17,
2069         2,16,
2070         2,16,
2071         1,16,
2072         1,16,
2073         1,16,
2074         1,16,
2075         1,16,
2076         1,16,
2077         1,16,
2078
2079         1,16,
2080         1,15,
2081         1,15,
2082         1,15,
2083         0,15,
2084         0,15,
2085         0,15,
2086         0,15,
2087         0,15,
2088         0,15,
2089
2090         0,14,
2091         0,14,
2092         0,14,
2093         1,14,
2094         2,14,
2095         3,14,
2096         4,14,
2097         5,14,
2098         6,13,
2099         7,13,
2100
2101         8,13,
2102         9,13,
2103         10,13,
2104         11,13,
2105         12,13
2106 };
2107
2108
2109 void draw_afterburner_bar(int afterburner)
2110 {
2111         int not_afterburner;
2112         int y;
2113
2114         // Draw afterburner bar
2115         gr_set_current_canvas( Canv_AfterburnerGauge );
2116         PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
2117         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_AFTERBURNER) ] );
2118         gr_setcolor( BM_XRGB(0,0,0) );
2119
2120         not_afterburner = fixmul(f1_0 - afterburner,AFTERBURNER_GAUGE_H);
2121
2122         for (y=0;y<not_afterburner;y++) {
2123
2124                 gr_uscanline( (Current_display_mode?afterburner_bar_table_hires[y*2]:afterburner_bar_table[y*2]),
2125                                                 (Current_display_mode?afterburner_bar_table_hires[y*2+1]:afterburner_bar_table[y*2+1]), y ); 
2126         }
2127
2128         WINDOS(
2129                 dd_gr_set_current_canvas(get_current_game_screen()),
2130                 gr_set_current_canvas( get_current_game_screen() )
2131         );
2132         WIN(DDGRLOCK(dd_grd_curcanv));
2133                 gr_ubitmapm( AFTERBURNER_GAUGE_X, AFTERBURNER_GAUGE_Y, &Canv_AfterburnerGauge->cv_bitmap );
2134         WIN(DDGRUNLOCK(dd_grd_curcanv));
2135 }
2136
2137 void draw_shield_bar(int shield)
2138 {
2139         int bm_num = shield>=100?9:(shield / 10);
2140
2141         PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num   );
2142         WIN(DDGRLOCK(dd_grd_curcanv));
2143         PA_DFX (pa_set_frontbuffer_current());
2144    PA_DFX (gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] ));
2145         PA_DFX (pa_set_backbuffer_current());
2146         gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
2147
2148         WIN(DDGRUNLOCK(dd_grd_curcanv));
2149 }
2150
2151 #define CLOAK_FADE_WAIT_TIME  0x400
2152
2153 void draw_player_ship(int cloak_state,int old_cloak_state,int x, int y)
2154 {
2155         static fix cloak_fade_timer=0;
2156         static int cloak_fade_value=GR_FADE_LEVELS-1;
2157         static int refade = 0;
2158         grs_bitmap *bm = NULL;
2159
2160         if (Game_mode & GM_TEAM)        {
2161                 #ifdef NETWORK
2162                 PAGE_IN_GAUGE( GAUGE_SHIPS+get_team(Player_num) );
2163                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+get_team(Player_num)) ];
2164                 #endif
2165         } else {
2166                 PAGE_IN_GAUGE( GAUGE_SHIPS+Player_num );
2167                 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+Player_num) ];
2168         }
2169         
2170
2171         if (old_cloak_state==-1 && cloak_state)
2172                         cloak_fade_value=0;
2173
2174 //      mprintf((0, "cloak/oldcloak %d/%d", cloak_state, old_cloak_state));
2175
2176         if (!cloak_state) {
2177                 cloak_fade_value=GR_FADE_LEVELS-1;
2178                 cloak_fade_state = 0;
2179         }
2180
2181         if (cloak_state==1 && old_cloak_state==0)
2182                 cloak_fade_state = -1;
2183         //else if (cloak_state==0 && old_cloak_state==1)
2184         //      cloak_fade_state = 1;
2185
2186         if (cloak_state==old_cloak_state)               //doing "about-to-uncloak" effect
2187                 if (cloak_fade_state==0)
2188                         cloak_fade_state = 2;
2189         
2190
2191         if (cloak_fade_state)
2192                 cloak_fade_timer -= FrameTime;
2193
2194         while (cloak_fade_state && cloak_fade_timer < 0) {
2195
2196                 cloak_fade_timer += CLOAK_FADE_WAIT_TIME;
2197
2198                 cloak_fade_value += cloak_fade_state;
2199
2200                 if (cloak_fade_value >= GR_FADE_LEVELS-1) {
2201                         cloak_fade_value = GR_FADE_LEVELS-1;
2202                         if (cloak_fade_state == 2 && cloak_state)
2203                                 cloak_fade_state = -2;
2204                         else
2205                                 cloak_fade_state = 0;
2206                 }
2207                 else if (cloak_fade_value <= 0) {
2208                         cloak_fade_value = 0;
2209                         if (cloak_fade_state == -2)
2210                                 cloak_fade_state = 2;
2211                         else
2212                                 cloak_fade_state = 0;
2213                 }
2214         }
2215
2216 //      To fade out both pages in a paged mode.
2217         if (refade) refade = 0;
2218         else if (cloak_state && old_cloak_state && !cloak_fade_state && !refade) {
2219                 cloak_fade_state = -1;
2220                 refade = 1;
2221         }
2222
2223 #if defined(POLY_ACC)
2224         #ifdef MACINTOSH
2225         if ( PAEnabled ) {
2226         #endif
2227             Gr_scanline_darkening_level = cloak_fade_value;
2228             gr_set_current_canvas( get_current_game_screen() );
2229             PA_DFX (pa_set_frontbuffer_current());      
2230             PA_DFX (pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h));
2231                  PA_DFX (pa_set_backbuffer_current());  
2232             pa_blit_lit(&grd_curcanv->cv_bitmap, x, y, bm, 0, 0, bm->bm_w, bm->bm_h);
2233
2234             Gr_scanline_darkening_level = GR_FADE_LEVELS;
2235             return;
2236 //          }
2237 //          else
2238 //                  Gr_scanline_darkening_level = GR_FADE_LEVELS;
2239 //               mprintf ((1,"HEY! HIT THIS!\n"));      
2240 //               Int3();
2241         #ifdef MACINTOSH
2242         }
2243         #endif
2244 #endif
2245
2246         WINDOS(                 
2247                 dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2248                 gr_set_current_canvas(&VR_render_buffer[0])
2249         );
2250
2251         WIN(DDGRLOCK(dd_grd_curcanv));
2252                 gr_ubitmap( x, y, bm);
2253
2254                 Gr_scanline_darkening_level = cloak_fade_value;
2255                 gr_rect(x, y, x+bm->bm_w-1, y+bm->bm_h-1);
2256                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2257         WIN(DDGRUNLOCK(dd_grd_curcanv));
2258
2259         WINDOS(
2260                 dd_gr_set_current_canvas(get_current_game_screen()),
2261                 gr_set_current_canvas( get_current_game_screen() )
2262         );
2263
2264 #ifdef WINDOWS
2265         DDGRLOCK(dd_grd_curcanv);
2266         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2267                 DDGRLOCK(&dd_VR_render_buffer[0]);
2268         }
2269         else {
2270                 dd_gr_dup_hack(&dd_VR_render_buffer[0], dd_grd_curcanv);
2271         }
2272 #endif
2273         WINDOS(
2274                 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),
2275                 gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &VR_render_buffer[0].cv_bitmap, &grd_curcanv->cv_bitmap)
2276         );
2277 #ifdef WINDOWS
2278         if (dd_grd_curcanv->lpdds != dd_VR_render_buffer[0].lpdds) {
2279                 DDGRUNLOCK(&dd_VR_render_buffer[0]);
2280         }
2281         else {
2282                 dd_gr_dup_unhack(&dd_VR_render_buffer[0]);
2283         }
2284         DDGRUNLOCK(dd_grd_curcanv);
2285 #endif
2286 }
2287
2288 #define INV_FRAME_TIME  (f1_0/10)               //how long for each frame
2289
2290 void draw_numerical_display(int shield, int energy)
2291 {
2292         gr_set_current_canvas( Canv_NumericalGauge );
2293         gr_set_curfont( GAME_FONT );
2294         PAGE_IN_GAUGE( GAUGE_NUMERICAL );
2295         gr_ubitmap( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_NUMERICAL) ] );
2296
2297         gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2298
2299         if (!Current_display_mode) {
2300                 gr_printf((shield>99)?3:((shield>9)?5:7),15,"%d",shield);
2301                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2302                 gr_printf((energy>99)?3:((energy>9)?5:7),2,"%d",energy);
2303         } else {
2304                 gr_printf((shield>99)?7:((shield>9)?11:15),33,"%d",shield);
2305                 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2306                 gr_printf((energy>99)?7:((energy>9)?11:15),4,"%d",energy);
2307         }
2308         
2309         WINDOS(
2310                 dd_gr_set_current_canvas(get_current_game_screen()),
2311                 gr_set_current_canvas( get_current_game_screen() )
2312         );
2313         WIN(DDGRLOCK(dd_grd_curcanv));
2314                 gr_ubitmapm( NUMERICAL_GAUGE_X, NUMERICAL_GAUGE_Y, &Canv_NumericalGauge->cv_bitmap );
2315         WIN(DDGRUNLOCK(dd_grd_curcanv));
2316 }
2317
2318
2319 void draw_keys()
2320 {
2321 WINDOS(
2322         dd_gr_set_current_canvas( get_current_game_screen() ),
2323         gr_set_current_canvas( get_current_game_screen() )
2324 );
2325
2326 WIN(DDGRLOCK(dd_grd_curcanv));
2327         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY ) {
2328                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY );
2329                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY) ] );
2330         } else {
2331                 PAGE_IN_GAUGE( GAUGE_BLUE_KEY_OFF );
2332                 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY_OFF) ] );
2333         }
2334
2335         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)  {
2336                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY );
2337                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY) ] );
2338         } else {
2339                 PAGE_IN_GAUGE( GAUGE_GOLD_KEY_OFF );
2340                 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY_OFF) ] );
2341         }
2342
2343         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)   {
2344                 PAGE_IN_GAUGE( GAUGE_RED_KEY );
2345                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY) ] );
2346         } else {
2347                 PAGE_IN_GAUGE( GAUGE_RED_KEY_OFF );
2348                 gr_ubitmapm( GAUGE_RED_KEY_X,  GAUGE_RED_KEY_Y,  &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY_OFF) ] );
2349         }
2350 WIN(DDGRUNLOCK(dd_grd_curcanv));
2351 }
2352
2353
2354 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)
2355 {
2356         grs_bitmap *bm;
2357         char *p;
2358
2359         //clear the window
2360         gr_setcolor(BM_XRGB(0,0,0));
2361         
2362   // PA_DFX (pa_set_frontbuffer_current());
2363 //      PA_DFX (gr_rect(box->left,box->top,box->right,box->bot));
2364    PA_DFX (pa_set_backbuffer_current());
2365         gr_rect(box->left,box->top,box->right,box->bot);
2366
2367         if (Piggy_hamfile_version >= 3 // !SHAREWARE
2368                 && Current_display_mode)
2369         {
2370                 bm=&GameBitmaps[Weapon_info[info_index].hires_picture.index];
2371                 PIGGY_PAGE_IN( Weapon_info[info_index].hires_picture );
2372         } else {
2373                 bm=&GameBitmaps[Weapon_info[info_index].picture.index];
2374                 PIGGY_PAGE_IN( Weapon_info[info_index].picture );
2375         }
2376
2377         Assert(bm != NULL);
2378
2379 //   PA_DFX (pa_set_frontbuffer_current());
2380 //      PA_DFX (gr_ubitmapm(pic_x,pic_y,bm));
2381    PA_DFX (pa_set_backbuffer_current());
2382         gr_ubitmapm(pic_x,pic_y,bm);
2383         
2384         gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2385
2386         if ((p=strchr(name,'\n'))!=NULL) {
2387                 *p=0;
2388            #ifdef PA_3DFX_VOODOO
2389   //                    pa_set_frontbuffer_current();
2390 //                      gr_printf(text_x,text_y,name);
2391 //                      gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2392                 #endif
2393                 PA_DFX (pa_set_backbuffer_current());
2394                 gr_printf(text_x,text_y,name);
2395                 gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2396                 *p='\n';
2397         } else
2398          {
2399   //            PA_DFX(pa_set_frontbuffer_current());
2400 //              PA_DFX (gr_printf(text_x,text_y,name));
2401                 PA_DFX(pa_set_backbuffer_current());
2402                 gr_printf(text_x,text_y,name);
2403          }      
2404
2405         //      For laser, show level and quadness
2406         if (info_index == LASER_ID || info_index == SUPER_LASER_ID) {
2407                 char    temp_str[7];
2408
2409                 sprintf(temp_str, "%s: 0", TXT_LVL);
2410
2411                 temp_str[5] = Players[Player_num].laser_level+1 + '0';
2412
2413 //              PA_DFX(pa_set_frontbuffer_current());
2414 //              PA_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2415                 PA_DFX(pa_set_backbuffer_current());
2416                 NO_DFX (gr_printf(text_x,text_y+Line_spacing, temp_str));
2417                 PA_DFX (gr_printf(text_x,text_y+12, temp_str));
2418
2419                 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
2420                         strcpy(temp_str, TXT_QUAD);
2421 //                      PA_DFX(pa_set_frontbuffer_current());
2422 //                      PA_DFX (gr_printf(text_x,text_y+2*Line_spacing, temp_str));
2423                         PA_DFX(pa_set_backbuffer_current());
2424                         gr_printf(text_x,text_y+2*Line_spacing, temp_str);
2425
2426                 }
2427
2428         }
2429 }
2430
2431
2432 void draw_weapon_info(int weapon_type,int weapon_num,int laser_level)
2433 {
2434         int info_index;
2435
2436         if (weapon_type == 0) {
2437                 info_index = Primary_weapon_to_weapon_info[weapon_num];
2438
2439                 if (info_index == LASER_ID && laser_level > MAX_LASER_LEVEL)
2440                         info_index = SUPER_LASER_ID;
2441
2442                 if (Cockpit_mode == CM_STATUS_BAR)
2443                         draw_weapon_info_sub(info_index,
2444                                 &gauge_boxes[SB_PRIMARY_BOX],
2445                                 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
2446                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2447                                 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
2448                 else
2449                         draw_weapon_info_sub(info_index,
2450                                 &gauge_boxes[COCKPIT_PRIMARY_BOX],
2451                                 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
2452                                 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2453                                 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
2454
2455         }
2456         else {
2457                 info_index = Secondary_weapon_to_weapon_info[weapon_num];
2458
2459                 if (Cockpit_mode == CM_STATUS_BAR)
2460                         draw_weapon_info_sub(info_index,
2461                                 &gauge_boxes[SB_SECONDARY_BOX],
2462                                 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
2463                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2464                                 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
2465                 else
2466                         draw_weapon_info_sub(info_index,
2467                                 &gauge_boxes[COCKPIT_SECONDARY_BOX],
2468                                 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
2469                                 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2470                                 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
2471         }
2472 }
2473
2474 void draw_ammo_info(int x,int y,int ammo_count,int primary)
2475 {
2476         int w;
2477         char str[16];
2478
2479         if (primary)
2480                 w = (grd_curcanv->cv_font->ft_w*7)/2;
2481         else
2482                 w = (grd_curcanv->cv_font->ft_w*5)/2;
2483
2484 WIN(DDGRLOCK(dd_grd_curcanv));
2485 {
2486
2487         PA_DFX (pa_set_frontbuffer_current());
2488
2489         gr_setcolor(BM_XRGB(0,0,0));
2490         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2491         gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
2492         sprintf(str,"%03d",ammo_count);
2493         convert_1s(str);
2494         gr_printf(x,y,str);
2495
2496         PA_DFX (pa_set_backbuffer_current());
2497         gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2498         gr_printf(x,y,str);
2499 }
2500
2501 WIN(DDGRUNLOCK(dd_grd_curcanv));
2502 }
2503
2504 void draw_secondary_ammo_info(int ammo_count)
2505 {
2506         if (Cockpit_mode == CM_STATUS_BAR)
2507                 draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
2508         else
2509                 draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
2510 }
2511
2512 //returns true if drew picture
2513 int draw_weapon_box(int weapon_type,int weapon_num)
2514 {
2515         int drew_flag=0;
2516         int laser_level_changed;
2517
2518 WINDOS(
2519         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2520         gr_set_current_canvas(&VR_render_buffer[0])
2521 );
2522
2523    PA_DFX (pa_set_backbuffer_current());
2524  
2525 WIN(DDGRLOCK(dd_grd_curcanv));
2526         gr_set_curfont( GAME_FONT );
2527
2528         laser_level_changed = (weapon_type==0 && weapon_num==LASER_INDEX && (Players[Player_num].laser_level != old_laser_level[VR_current_page]));
2529
2530         if ((weapon_num != old_weapon[weapon_type][VR_current_page] || laser_level_changed) && weapon_box_states[weapon_type] == WS_SET) {
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 (old_weapon[weapon_type][VR_current_page] == -1) {
2536                 //@@if (laser_level_changed)
2537                 //@@    old_weapon[weapon_type][VR_current_page] = LASER_INDEX;
2538                 //@@else 
2539                 {
2540                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2541                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2542                         old_ammo_count[weapon_type][VR_current_page]=-1;
2543                         Old_Omega_charge[VR_current_page]=-1;
2544                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2545                         drew_flag=1;
2546                         weapon_box_states[weapon_type] = WS_SET;
2547                 }
2548         }
2549
2550         if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
2551                 draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page],old_laser_level[VR_current_page]);
2552                 old_ammo_count[weapon_type][VR_current_page]=-1;
2553                 Old_Omega_charge[VR_current_page]=-1;
2554                 drew_flag=1;
2555                 weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
2556                 if (weapon_box_fade_values[weapon_type] <= 0) {
2557                         weapon_box_states[weapon_type] = WS_FADING_IN;
2558                         old_weapon[weapon_type][VR_current_page] = weapon_num;
2559                         old_weapon[weapon_type][!VR_current_page] = weapon_num;
2560                         old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2561                         old_laser_level[!VR_current_page] = Players[Player_num].laser_level;
2562                         weapon_box_fade_values[weapon_type] = 0;
2563                 }
2564         }
2565         else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
2566                 if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
2567                         weapon_box_states[weapon_type] = WS_FADING_OUT;
2568                 }
2569                 else {
2570                         draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2571                         old_ammo_count[weapon_type][VR_current_page]=-1;
2572                         Old_Omega_charge[VR_current_page]=-1;
2573                         drew_flag=1;
2574                         weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
2575                         if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
2576                                 weapon_box_states[weapon_type] = WS_SET;
2577                                 old_weapon[weapon_type][!VR_current_page] = -1;         //force redraw (at full fade-in) of other page
2578                         }
2579                 }
2580         }
2581
2582         if (weapon_box_states[weapon_type] != WS_SET) {         //fade gauge
2583                 int fade_value = f2i(weapon_box_fade_values[weapon_type]);
2584                 int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2585                 
2586                 Gr_scanline_darkening_level = fade_value;
2587 //         PA_DFX (pa_set_frontbuffer_current());
2588 //              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));
2589            PA_DFX (pa_set_backbuffer_current());
2590                 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);
2591
2592                 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2593         }
2594 WIN(DDGRUNLOCK(dd_grd_curcanv));
2595
2596 WINDOS(
2597         dd_gr_set_current_canvas(get_current_game_screen()),
2598         gr_set_current_canvas(get_current_game_screen())
2599 );
2600         return drew_flag;
2601 }
2602
2603 fix static_time[2];
2604
2605 void draw_static(int win)
2606 {
2607         vclip *vc = &Vclip[VCLIP_MONITOR_STATIC];
2608         grs_bitmap *bmp;
2609         int framenum;
2610         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2611         int x,y;
2612
2613         static_time[win] += FrameTime;
2614         if (static_time[win] >= vc->play_time) {
2615                 weapon_box_user[win] = WBU_WEAPON;
2616                 return;
2617         }
2618
2619         framenum = static_time[win] * vc->num_frames / vc->play_time;
2620
2621         PIGGY_PAGE_IN(vc->frames[framenum]);
2622
2623         bmp = &GameBitmaps[vc->frames[framenum].index];
2624
2625         WINDOS(
2626         dd_gr_set_current_canvas(&dd_VR_render_buffer[0]),
2627         gr_set_current_canvas(&VR_render_buffer[0])
2628         );
2629         WIN(DDGRLOCK(dd_grd_curcanv));
2630    PA_DFX (pa_set_backbuffer_current());
2631         PA_DFX (pa_bypass_mode (0));
2632         PA_DFX (pa_clip_window (gauge_boxes[boxofs+win].left,gauge_boxes[boxofs+win].top,
2633                                                                         gauge_boxes[boxofs+win].right,gauge_boxes[boxofs+win].bot));
2634    
2635         for (x=gauge_boxes[boxofs+win].left;x<gauge_boxes[boxofs+win].right;x+=bmp->bm_w)
2636                 for (y=gauge_boxes[boxofs+win].top;y<gauge_boxes[boxofs+win].bot;y+=bmp->bm_h)
2637                         gr_bitmap(x,y,bmp);
2638
2639         PA_DFX (pa_bypass_mode(1));
2640         PA_DFX (pa_clip_window (0,0,640,480));
2641
2642         WIN(DDGRUNLOCK(dd_grd_curcanv));
2643
2644         WINDOS(
2645         dd_gr_set_current_canvas(get_current_game_screen()),
2646         gr_set_current_canvas(get_current_game_screen())
2647         );
2648
2649 //   PA_DFX (return);
2650   
2651         WINDOS(
2652         copy_gauge_box(&gauge_boxes[boxofs+win],&dd_VR_render_buffer[0]),
2653         copy_gauge_box(&gauge_boxes[boxofs+win],&VR_render_buffer[0].cv_bitmap)
2654         );
2655 }
2656
2657 void draw_weapon_boxes()
2658 {
2659         int boxofs = (Cockpit_mode==CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2660         int drew;
2661
2662         if (weapon_box_user[0] == WBU_WEAPON) {
2663                 drew = draw_weapon_box(0,Primary_weapon);
2664                 if (drew) 
2665                         WINDOS(
2666                                 copy_gauge_box(&gauge_boxes[boxofs+0],&dd_VR_render_buffer[0]),
2667                                 copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap)
2668                         );
2669
2670                 if (weapon_box_states[0] == WS_SET) {
2671                         if ((Primary_weapon == VULCAN_INDEX) || (Primary_weapon == GAUSS_INDEX)) {
2672                                 if (Players[Player_num].primary_ammo[VULCAN_INDEX] != old_ammo_count[0][VR_current_page]) {
2673                                         if (Newdemo_state == ND_STATE_RECORDING)
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
2680                         if (Primary_weapon == OMEGA_INDEX) {
2681                                 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
2682                                         if (Newdemo_state == ND_STATE_RECORDING)
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         }
2690         else if (weapon_box_user[0] == WBU_STATIC)
2691                 draw_static(0);
2692
2693         if (weapon_box_user[1] == WBU_WEAPON) {
2694                 drew = draw_weapon_box(1,Secondary_weapon);
2695                 if (drew)
2696                         WINDOS(
2697                                 copy_gauge_box(&gauge_boxes[boxofs+1],&dd_VR_render_buffer[0]),
2698                                 copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap)
2699                         );
2700
2701                 if (weapon_box_states[1] == WS_SET)
2702                         if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
2703                                 old_bombcount[VR_current_page] = 0x7fff;        //force redraw
2704                                 if (Newdemo_state == ND_STATE_RECORDING)
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         PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2723         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_ENERGY) ] );
2724
2725         erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
2726
2727         if (erase_height > 0) {
2728                 gr_setcolor( BM_XRGB(0,0,0) );
2729                 gr_rect(0,0,SB_ENERGY_GAUGE_W-1,erase_height-1);
2730         }
2731
2732         WINDOS(
2733         dd_gr_set_current_canvas(get_current_game_screen()),
2734         gr_set_current_canvas(get_current_game_screen())
2735         );
2736
2737         WIN(DDGRLOCK(dd_grd_curcanv));
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         PAGE_IN_GAUGE( SB_GAUGE_AFTERBURNER );
2761         gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(SB_GAUGE_AFTERBURNER) ] );
2762
2763         erase_height = fixmul((f1_0 - Afterburner_charge),SB_AFTERBURNER_GAUGE_H);
2764
2765         if (erase_height > 0) {
2766                 gr_setcolor( BM_XRGB(0,0,0) );
2767                 gr_rect(0,0,SB_AFTERBURNER_GAUGE_W-1,erase_height-1);
2768         }
2769
2770 WINDOS(
2771         dd_gr_set_current_canvas(get_current_game_screen()),
2772         gr_set_current_canvas(get_current_game_screen())
2773 );
2774 WIN(DDGRLOCK(dd_grd_curcanv));
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 #ifdef 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         int frc=0;
3422  
3423    PA_DFX (frc=0);
3424    PA_DFX (pa_set_backbuffer_current());
3425
3426         Assert(Cockpit_mode==CM_FULL_COCKPIT || Cockpit_mode==CM_STATUS_BAR);
3427
3428 // check to see if our display mode has changed since last render time --
3429 // if so, then we need to make new gauge canvases.
3430
3431   
3432         if (old_display_mode != Current_display_mode) {
3433                 close_gauge_canvases();
3434                 init_gauge_canvases();
3435                 old_display_mode = Current_display_mode;
3436         }
3437
3438         if (shields < 0 ) shields = 0;
3439
3440         WINDOS(
3441                 dd_gr_set_current_canvas(get_current_game_screen()),
3442                 gr_set_current_canvas(get_current_game_screen())
3443         );
3444         gr_set_curfont( GAME_FONT );
3445
3446         if (Newdemo_state == ND_STATE_RECORDING)
3447                 if (Players[Player_num].homing_object_dist >= 0)
3448                         newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
3449
3450         if (Cockpit_mode == CM_FULL_COCKPIT) {
3451                 if (energy != old_energy[VR_current_page]) {
3452                         if (Newdemo_state==ND_STATE_RECORDING ) {
3453                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3454                         }
3455                         draw_energy_bar(energy);
3456                         draw_numerical_display(shields, energy);
3457                         old_energy[VR_current_page] = energy;
3458                 }
3459
3460                 if (Afterburner_charge != old_afterburner[VR_current_page]) {
3461                         if (Newdemo_state==ND_STATE_RECORDING ) {
3462                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3463                         }
3464                         draw_afterburner_bar(Afterburner_charge);
3465                         old_afterburner[VR_current_page] = Afterburner_charge;
3466                 }
3467
3468                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3469                         draw_numerical_display(shields, energy);
3470                         draw_invulnerable_ship();
3471                         old_shields[VR_current_page] = shields ^ 1;
3472                 } else if (shields != old_shields[VR_current_page]) {           // Draw the shield gauge
3473                         if (Newdemo_state==ND_STATE_RECORDING ) {
3474                                 newdemo_record_player_shields(old_shields[VR_current_page], shields);
3475                         }
3476                         draw_shield_bar(shields);
3477                         draw_numerical_display(shields, energy);
3478                         old_shields[VR_current_page] = shields;
3479                 }
3480         
3481                 if (Players[Player_num].flags != old_flags[VR_current_page]) {
3482                         if (Newdemo_state==ND_STATE_RECORDING )
3483                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3484                         draw_keys();
3485                         old_flags[VR_current_page] = Players[Player_num].flags;
3486                 }
3487
3488                 show_homing_warning();
3489
3490                 show_bomb_count(BOMB_COUNT_X,BOMB_COUNT_Y,gr_find_closest_color(0,0,0),0);
3491         
3492         } else if (Cockpit_mode == CM_STATUS_BAR) {
3493
3494                 if (energy != old_energy[VR_current_page] || frc)  {
3495                         if (Newdemo_state==ND_STATE_RECORDING ) {
3496                                 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3497                         }
3498                         sb_draw_energy_bar(energy);
3499                         old_energy[VR_current_page] = energy;
3500                 }
3501
3502                 if (Afterburner_charge != old_afterburner[VR_current_page] || frc) {
3503                         if (Newdemo_state==ND_STATE_RECORDING ) {
3504                                 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3505                         }
3506                         sb_draw_afterburner();
3507                         old_afterburner[VR_current_page] = Afterburner_charge;
3508                 }
3509         
3510                 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
3511                         draw_invulnerable_ship();
3512                         old_shields[VR_current_page] = shields ^ 1;
3513                         sb_draw_shield_num(shields);
3514                 } 
3515                 else 
3516                         if (shields != old_shields[VR_current_page] || frc) {           // Draw the shield gauge
3517                                 if (Newdemo_state==ND_STATE_RECORDING ) {
3518                                         newdemo_record_player_shields(old_shields[VR_current_page], shields);
3519                                 }
3520                                 sb_draw_shield_bar(shields);
3521                                 old_shields[VR_current_page] = shields;
3522                                 sb_draw_shield_num(shields);
3523                         }
3524
3525                 if (Players[Player_num].flags != old_flags[VR_current_page] || frc) {
3526                         if (Newdemo_state==ND_STATE_RECORDING )
3527                                 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3528                         sb_draw_keys();
3529                         old_flags[VR_current_page] = Players[Player_num].flags;
3530                 }
3531         
3532
3533                 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3534                 {
3535                         if (Players[Player_num].net_killed_total != old_lives[VR_current_page] || frc) {
3536                                 sb_show_lives();
3537                                 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
3538                         }
3539                 }
3540                 else
3541                 {
3542                         if (Players[Player_num].lives != old_lives[VR_current_page] || frc) {
3543                                 sb_show_lives();
3544                                 old_lives[VR_current_page] = Players[Player_num].lives;
3545                         }
3546                 }
3547
3548                 if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) {
3549                         if (Players[Player_num].net_kills_total != old_score[VR_current_page] || frc) {
3550                                 sb_show_score();
3551                                 old_score[VR_current_page] = Players[Player_num].net_kills_total;
3552                         }
3553                 }
3554                 else {
3555                         if (Players[Player_num].score != old_score[VR_current_page] || frc) {
3556                                 sb_show_score();
3557                                 old_score[VR_current_page] = Players[Player_num].score;
3558                         }
3559
3560                         //if (score_time)
3561                                 sb_show_score_added();
3562                 }
3563
3564                 show_bomb_count(SB_BOMB_COUNT_X,SB_BOMB_COUNT_Y,gr_find_closest_color(5,5,5),0);
3565         }
3566
3567         if (frc || cloak != old_cloak[VR_current_page] || cloak_fade_state || (cloak && GameTime>Players[Player_num].cloak_time+CLOAK_TIME_MAX-i2f(3))) {
3568                 if (Cockpit_mode == CM_FULL_COCKPIT)
3569                         draw_player_ship(cloak,old_cloak[VR_current_page],SHIP_GAUGE_X,SHIP_GAUGE_Y);
3570                 else
3571                         draw_player_ship(cloak,old_cloak[VR_current_page],SB_SHIP_GAUGE_X,SB_SHIP_GAUGE_Y);
3572
3573                 old_cloak[VR_current_page]=cloak;
3574         }
3575
3576
3577         draw_weapon_boxes();
3578
3579 }
3580
3581 //      ---------------------------------------------------------------------------------------------------------
3582 //      Call when picked up a laser powerup.
3583 //      If laser is active, set old_weapon[0] to -1 to force redraw.
3584 void update_laser_weapon_info(void)
3585 {
3586         if (old_weapon[0][VR_current_page] == 0)
3587                 if (! (Players[Player_num].laser_level > MAX_LASER_LEVEL && old_laser_level[VR_current_page] <= MAX_LASER_LEVEL))
3588                         old_weapon[0][VR_current_page] = -1;
3589 }
3590
3591 extern int Game_window_y;
3592 void fill_background(void);
3593
3594 int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
3595
3596 //draws a 3d view into one of the cockpit windows.  win is 0 for left,
3597 //1 for right.  viewer is object.  NULL object means give up window
3598 //user is one of the WBU_ constants.  If rear_view_flag is set, show a
3599 //rear view.  If label is non-NULL, print the label at the top of the
3600 //window.
3601 void do_cockpit_window_view(int win,object *viewer,int rear_view_flag,int user,char *label)
3602 {
3603         WINDOS(
3604                 dd_grs_canvas window_canv,
3605                 grs_canvas window_canv
3606         );
3607         WINDOS(
3608                 static dd_grs_canvas overlap_canv,
3609                 static grs_canvas overlap_canv
3610         );
3611
3612 #ifdef WINDOWS
3613         int saved_window_x, saved_window_y;
3614 #endif
3615
3616         object *viewer_save = Viewer;
3617         static int overlap_dirty[2]={0,0};
3618         int boxnum;
3619         static int window_x,window_y;
3620         gauge_box *box;
3621         int rear_view_save = Rear_view;
3622         int w,h,dx;
3623
3624         box = NULL;
3625
3626         if (viewer == NULL) {                                                           //this user is done
3627
3628                 Assert(user == WBU_WEAPON || user == WBU_STATIC);
3629
3630                 if (user == WBU_STATIC && weapon_box_user[win] != WBU_STATIC)
3631                         static_time[win] = 0;
3632
3633                 if (weapon_box_user[win] == WBU_WEAPON || weapon_box_user[win] == WBU_STATIC)
3634                         return;         //already set
3635
3636                 weapon_box_user[win] = user;
3637
3638                 if (overlap_dirty[win]) {
3639                 WINDOS(
3640                         dd_gr_set_current_canvas(&dd_VR_screen_pages[VR_current_page]),
3641                         gr_set_current_canvas(&VR_screen_pages[VR_current_page])
3642                 );
3643                         fill_background();
3644                         overlap_dirty[win] = 0;
3645                 }
3646
3647                 return;
3648         }
3649
3650         update_rendered_data(win+1, viewer, rear_view_flag, user);
3651
3652         weapon_box_user[win] = user;                                            //say who's using window
3653                 
3654         Viewer = viewer;
3655         Rear_view = rear_view_flag;
3656
3657         if (Cockpit_mode == CM_FULL_SCREEN)
3658         {
3659
3660                 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
3661                 #ifdef MACINTOSH
3662                 if (Scanline_double)
3663                         w /= 2;
3664                 #endif
3665
3666                 h = i2f(w) / grd_curscreen->sc_aspect;
3667
3668                 dx = (win==0)?-(w+(w/10)):(w/10);
3669
3670                 window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3671                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3672
3673         #ifdef WINDOWS
3674                 saved_window_x = window_x;
3675                 saved_window_y = window_y;
3676                 window_x = dd_VR_render_sub_buffer[0].canvas.cv_bitmap.bm_w/2+dx;
3677                 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10)-dd_VR_render_sub_buffer[0].yoff;
3678         #endif
3679
3680                 #ifdef MACINTOSH
3681                 if (Scanline_double) {
3682                         window_x = (VR_render_buffer[0].cv_bitmap.bm_w/2+VR_render_sub_buffer[0].cv_bitmap.bm_x)/2+dx;
3683                         window_y = ((VR_render_buffer[0].cv_bitmap.bm_h+VR_render_sub_buffer[0].cv_bitmap.bm_y)/2)-h-(h/10);
3684                 }
3685                 #endif
3686
3687                 //copy these vars so stereo code can get at them
3688                 SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3689
3690         WINDOS(
3691                 dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,w,h),
3692                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],window_x,window_y,w,h)
3693         );
3694         }
3695         else {
3696                 if (Cockpit_mode == CM_FULL_COCKPIT)
3697                         boxnum = (COCKPIT_PRIMARY_BOX)+win;
3698                 else if (Cockpit_mode == CM_STATUS_BAR)
3699                         boxnum = (SB_PRIMARY_BOX)+win;
3700                 else
3701                         goto abort;
3702
3703                 box = &gauge_boxes[boxnum];
3704
3705                 #ifndef MACINTOSH
3706         WINDOS(                                                           
3707                 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),
3708                 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1)
3709         );
3710                 #else
3711                 if (Scanline_double)
3712                         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);
3713                 else
3714                         gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1);
3715                 #endif
3716         }
3717
3718 WINDOS(
3719         dd_gr_set_current_canvas(&window_canv),
3720         gr_set_current_canvas(&window_canv)
3721 );
3722         
3723         #if defined(MACINTOSH) && defined(POLY_ACC)
3724         if ( PAEnabled )
3725         {
3726                 switch (Cockpit_mode)
3727                 {
3728                 // copy these vars so stereo code can get at them
3729                 // SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h; 
3730                         case CM_FULL_SCREEN:
3731                                 ;       // do not switch contexts
3732                                 pa_set_3d_window_offsets(window_x, window_y);
3733                                 break;
3734                         case CM_FULL_COCKPIT:
3735                         case CM_STATUS_BAR:
3736                                 if (win == 0)
3737                                 {
3738                                         pa_set_context(kSubViewZeroDrawContextID, NULL);
3739                                 }
3740                                 else
3741                                 {
3742                                         pa_set_context(kSubViewOneDrawContextID, NULL);
3743                                 }
3744                                 break;
3745                         default:
3746                                 Int3(); // invalid cockpit mode
3747                 };
3748         }
3749         #endif
3750
3751         WIN(DDGRLOCK(dd_grd_curcanv));
3752         
3753                 #ifdef MACINTOSH
3754                         #ifdef POLY_ACC
3755                                 if (PAEnabled)
3756                                 {
3757                                         if (Cockpit_mode != CM_FULL_SCREEN)
3758                                         {
3759                                                 pa_render_start();
3760                                         }
3761                                 }
3762                         #endif
3763                 #endif 
3764                 
3765                 render_frame(0, win+1);
3766                 
3767                 #ifdef MACINTOSH
3768                         #ifdef POLY_ACC
3769                                 if (PAEnabled)
3770                                 {
3771                                         if (Cockpit_mode != CM_FULL_SCREEN)
3772                                         {
3773                                                 pa_render_end();
3774                                         }
3775                                 }
3776                         #endif
3777                 #endif 
3778
3779         WIN(DDGRUNLOCK(dd_grd_curcanv));
3780
3781         //      HACK! If guided missile, wake up robots as necessary.
3782         if (viewer->type == OBJ_WEAPON) {
3783                 // -- Used to require to be GUIDED -- if (viewer->id == GUIDEDMISS_ID)
3784                 wake_up_rendered_objects(viewer, win+1);
3785         }
3786
3787         if (label) {
3788         WIN(DDGRLOCK(dd_grd_curcanv));
3789         MAC(if (Scanline_double) FontHires = 0;)                // get the right font size
3790                 gr_set_curfont( GAME_FONT );
3791                 if (Color_0_31_0 == -1)
3792                         Color_0_31_0 = gr_getcolor(0,31,0);
3793                 gr_set_fontcolor(Color_0_31_0, -1);
3794                 gr_printf(0x8000,2,label);
3795         MAC(if (Scanline_double) FontHires = 1;)                // get the right font size back to normal
3796         WIN(DDGRUNLOCK(dd_grd_curcanv));
3797         }
3798
3799         if (user == WBU_GUIDED) {
3800         WIN(DDGRLOCK(dd_grd_curcanv));
3801                 draw_guided_crosshair();
3802         WIN(DDGRUNLOCK(dd_grd_curcanv));
3803         }
3804
3805         if (Cockpit_mode == CM_FULL_SCREEN) {
3806                 int small_window_bottom,big_window_bottom,extra_part_h;
3807                 
3808                 WIN(DDGRLOCK(dd_grd_curcanv));
3809                 {
3810                         gr_setcolor(BM_XRGB(0,0,32));
3811                         gr_ubox(0,0,grd_curcanv->cv_bitmap.bm_w-1,grd_curcanv->cv_bitmap.bm_h-1);
3812                 }
3813                 WIN(DDGRUNLOCK(dd_grd_curcanv));
3814
3815                 //if the window only partially overlaps the big 3d window, copy
3816                 //the extra part to the visible screen
3817
3818                 #ifdef MACINTOSH                // recalc window_x and window_y because of scanline doubling problems
3819                 {
3820                         int w, h, dx;
3821                         
3822                         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
3823                         h = i2f(w) / grd_curscreen->sc_aspect;
3824                         dx = (win==0)?-(w+(w/10)):(w/10);
3825                         window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3826                         window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3827                         if (Scanline_double)
3828                                 window_x += ((win==0)?2:-1);            // a real hack here....
3829                 }
3830                 #endif
3831                 big_window_bottom = Game_window_y + Game_window_h - 1;
3832
3833         #ifdef WINDOWS
3834                 window_x = saved_window_x;
3835                 window_y = saved_window_y;
3836 //              dd_gr_init_sub_canvas(&window_canv, &dd_VR_render_buffer[0],window_x,window_y,
3837 //                                              VR_render_buffer[0].cv_bitmap.bm_w/6,
3838 //                                              i2f(VR_render_buffer[0].cv_bitmap.bm_w/6) / grd_curscreen->sc_aspect);
3839
3840         #endif
3841
3842                 if (window_y > big_window_bottom) {
3843
3844                         //the small window is completely outside the big 3d window, so
3845                         //copy it to the visible screen
3846
3847                         if (VR_screen_flags & VRF_USE_PAGING)
3848                                 WINDOS(
3849                                         dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
3850                                         gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
3851                                 );
3852                         else
3853                                 WINDOS(
3854                                         dd_gr_set_current_canvas(get_current_game_screen()),
3855                                         gr_set_current_canvas(get_current_game_screen())
3856                                 );
3857
3858                         #ifdef MACINTOSH
3859                         if (Scanline_double)
3860                                 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);
3861                         else
3862                         #endif          // note link to above if
3863                         WINDOS(
3864                                 dd_gr_blt_notrans(&window_canv, 0,0,0,0,
3865                                                                                 dd_grd_curcanv, window_x, window_y, 0,0),
3866                                 gr_bitmap(window_x,window_y,&window_canv.cv_bitmap)
3867                         );
3868
3869                         overlap_dirty[win] = 1;
3870                 }
3871                 else {
3872
3873                 WINDOS(
3874                         small_window_bottom = window_y + window_canv.canvas.cv_bitmap.bm_h - 1,
3875                         small_window_bottom = window_y + window_canv.cv_bitmap.bm_h - 1
3876                 );
3877                         #ifdef MACINTOSH
3878                         if (Scanline_double)
3879                                 small_window_bottom = window_y + (window_canv.cv_bitmap.bm_h*2) - 1;
3880                         #endif
3881                         
3882                         extra_part_h = small_window_bottom - big_window_bottom;
3883
3884                         if (extra_part_h > 0) {
3885                         
3886                                 #ifdef MACINTOSH
3887                                 if (Scanline_double)
3888                                         extra_part_h /= 2;
3889                                 #endif
3890         
3891                                 WINDOS(
3892                                         dd_gr_init_sub_canvas(&overlap_canv,&window_canv,0,
3893                                                 window_canv.canvas.cv_bitmap.bm_h-extra_part_h,
3894                                                 window_canv.canvas.cv_bitmap.bm_w,extra_part_h),
3895                                         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)
3896                                 );
3897
3898                                 if (VR_screen_flags & VRF_USE_PAGING)
3899                                         WINDOS(
3900                                                 dd_gr_set_current_canvas(&dd_VR_screen_pages[!VR_current_page]),
3901                                                 gr_set_current_canvas(&VR_screen_pages[!VR_current_page])
3902                                         );
3903                                 else
3904                                         WINDOS(
3905                                                 dd_gr_set_current_canvas(get_current_game_screen()),
3906                                                 gr_set_current_canvas(get_current_game_screen())
3907                                         );
3908
3909                                 #ifdef MACINTOSH
3910                                 if (Scanline_double)
3911                                         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);
3912                                 else
3913                                 #endif          // note link to above if
3914                                 WINDOS(
3915                                         dd_gr_blt_notrans(&overlap_canv, 0,0,0,0,
3916                                                                                         dd_grd_curcanv, window_x, big_window_bottom+1, 0,0),
3917                                         gr_bitmap(window_x,big_window_bottom+1,&overlap_canv.cv_bitmap)
3918                                 );
3919                                 
3920                                 overlap_dirty[win] = 1;
3921                         }
3922                 }
3923         }
3924         else {
3925         PA_DFX (goto skip_this_junk);
3926         
3927         WINDOS(
3928                 dd_gr_set_current_canvas(get_current_game_screen()),
3929                 gr_set_current_canvas(get_current_game_screen())
3930         );
3931         #ifndef MACINTOSH
3932         WINDOS(
3933                 copy_gauge_box(box,&dd_VR_render_buffer[0]),
3934                 copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap)
3935         );
3936         #else
3937         if (Scanline_double)
3938                 copy_gauge_box_double(box,&VR_render_buffer[0].cv_bitmap);              // pixel double the external view
3939         else
3940                 // Only do this if we are not running under RAVE, otherwise we erase all of the rendering RAVE has done.
3941                 if (!PAEnabled)
3942                 {
3943                         copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap);
3944                 }
3945         #endif
3946         }
3947
3948   PA_DFX(skip_this_junk:)
3949   
3950         #if defined(MACINTOSH) && defined(POLY_ACC)
3951         if ( PAEnabled )
3952         {
3953                 pa_set_context(kGamePlayDrawContextID, NULL);
3954         }
3955         #endif
3956
3957         //force redraw when done
3958         old_weapon[win][VR_current_page] = old_ammo_count[win][VR_current_page] = -1;
3959
3960 abort:;
3961
3962         Viewer = viewer_save;
3963
3964         Rear_view = rear_view_save;
3965 }
3966
3967 #ifdef MACINTOSH
3968         void calculate_sub_view_window_bounds(int inSubWindowNum, TQARect* outBoundsRect)
3969         {
3970                 int             boxNumber               = 0;
3971                 gauge_box*      currentGaugeBox = NULL;
3972                 int w   = 0;
3973                 int h   = 0;
3974                 int dx  = 0;
3975                 int window_x = 0;
3976                 int window_y = 0;
3977
3978                 Assert(outBoundsRect);
3979                 Assert((inSubWindowNum == 0) || (inSubWindowNum == 1));
3980                 Assert(!Scanline_double);
3981                 
3982                 switch (Cockpit_mode)
3983                 {
3984                         case CM_FULL_SCREEN:
3985                                 // note: this calculation is taken from do_cockpit_window_view for the full
3986                                 // screen mode case
3987                 
3988                                 w = (VR_render_buffer[0].cv_bitmap.bm_w) / 6;
3989                                 h = (i2f(w)) / (grd_curscreen->sc_aspect);
3990                 
3991                                 dx = (inSubWindowNum==0)?-(w+(w/10)):(w/10);
3992                 
3993                                 window_x = ((VR_render_buffer[0].cv_bitmap.bm_w) / 2) + dx;
3994                                 window_y = (VR_render_buffer[0].cv_bitmap.bm_h) - h - (h/10);
3995                                 
3996                                 outBoundsRect->top              = window_x;
3997                                 outBoundsRect->left             = window_y;
3998                                 outBoundsRect->bottom   = window_x + w;
3999                                 outBoundsRect->right    = window_y + h;
4000                                 break;
4001         
4002                         case CM_FULL_COCKPIT:
4003                         case CM_STATUS_BAR:
4004                                 if (inSubWindowNum == 0)
4005                                 {
4006                                         boxNumber = SB_PRIMARY_BOX;
4007                                 }
4008                                 else
4009                                 {
4010                                         boxNumber = SB_SECONDARY_BOX;
4011                                 }
4012                                 
4013                                 //boxNumber = (Current_display_mode * 4) + (Cockpit_mode * 2) + inSubWindowNum;
4014                                 currentGaugeBox = &gauge_boxes[boxNumber];
4015                                 Assert(currentGaugeBox);
4016                                 
4017                                 outBoundsRect->top              = currentGaugeBox->top;
4018                                 outBoundsRect->left             = currentGaugeBox->left;
4019                                 outBoundsRect->bottom   = currentGaugeBox->bot + 1;
4020                                 outBoundsRect->right    = currentGaugeBox->right + 1;
4021                                 
4022                                 break;
4023         
4024                         default:
4025                                 Int3();
4026                                 return;
4027                 }
4028         }
4029
4030 #endif
4031
4032