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