2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Inferno gauge drivers
37 void draw_ammo_info(int x,int y,int ammo_count,int primary);
38 extern void draw_guided_crosshair(void);
40 bitmap_index Gauges[MAX_GAUGE_BMS]; // Array of all gauge bitmaps.
41 bitmap_index Gauges_hires[MAX_GAUGE_BMS]; // hires gauges
43 grs_canvas *Canv_LeftEnergyGauge = NULL;
44 grs_canvas *Canv_AfterburnerGauge = NULL;
45 grs_canvas *Canv_SBEnergyGauge = NULL;
46 grs_canvas *Canv_SBAfterburnerGauge = NULL;
47 grs_canvas *Canv_RightEnergyGauge = NULL;
48 grs_canvas *Canv_NumericalGauge = NULL;
50 //Flags for gauges/hud stuff
51 cvar_t Reticle_on = { "crosshair", "1", CVAR_ARCHIVE };
53 //bitmap numbers for gauges
55 #define GAUGE_SHIELDS 0 //0..9, in decreasing order (100%,90%...0%)
57 #define GAUGE_INVULNERABLE 10 //10..19
58 #define N_INVULNERABLE_FRAMES 10
60 #define GAUGE_AFTERBURNER 20
61 #define GAUGE_ENERGY_LEFT 21
62 #define GAUGE_ENERGY_RIGHT 22
63 #define GAUGE_NUMERICAL 23
65 #define GAUGE_BLUE_KEY 24
66 #define GAUGE_GOLD_KEY 25
67 #define GAUGE_RED_KEY 26
68 #define GAUGE_BLUE_KEY_OFF 27
69 #define GAUGE_GOLD_KEY_OFF 28
70 #define GAUGE_RED_KEY_OFF 29
72 #define SB_GAUGE_BLUE_KEY 30
73 #define SB_GAUGE_GOLD_KEY 31
74 #define SB_GAUGE_RED_KEY 32
75 #define SB_GAUGE_BLUE_KEY_OFF 33
76 #define SB_GAUGE_GOLD_KEY_OFF 34
77 #define SB_GAUGE_RED_KEY_OFF 35
79 #define SB_GAUGE_ENERGY 36
81 #define GAUGE_LIVES 37
83 #define GAUGE_SHIPS 38
84 #define GAUGE_SHIPS_LAST 45
86 #define RETICLE_CROSS 46
87 #define RETICLE_PRIMARY 48
88 #define RETICLE_SECONDARY 51
89 #define RETICLE_LAST 55
91 #define GAUGE_HOMING_WARNING_ON 56
92 #define GAUGE_HOMING_WARNING_OFF 57
94 #define SML_RETICLE_CROSS 58
95 #define SML_RETICLE_PRIMARY 60
96 #define SML_RETICLE_SECONDARY 63
97 #define SML_RETICLE_LAST 67
99 #define KEY_ICON_BLUE 68
100 #define KEY_ICON_YELLOW 69
101 #define KEY_ICON_RED 70
103 #define SB_GAUGE_AFTERBURNER 71
105 #define FLAG_ICON_RED 72
106 #define FLAG_ICON_BLUE 73
109 /* Use static inline function under GCC to avoid CR/LF issues */
111 #define PAGE_IN_GAUGE(x) _page_in_gauge(x)
112 static inline void _page_in_gauge(int x)
115 PIGGY_PAGE_IN(Gauges_hires[x]);
117 PIGGY_PAGE_IN(Gauges[x]);
122 #define PAGE_IN_GAUGE(x) \
125 PIGGY_PAGE_IN(Gauges_hires[x]); \
127 PIGGY_PAGE_IN(Gauges[x]); \
133 #define GET_GAUGE_INDEX(x) (FontHires?Gauges_hires[x].index:Gauges[x].index)
135 //change MAX_GAUGE_BMS when adding gauges
137 //Coordinats for gauges
141 #define GAUGE_BLUE_KEY_X_L 272
142 #define GAUGE_BLUE_KEY_Y_L 152
143 #define GAUGE_BLUE_KEY_X_H 535
144 #define GAUGE_BLUE_KEY_Y_H 374
145 #define GAUGE_BLUE_KEY_X (SM_HIRES?GAUGE_BLUE_KEY_X_H:GAUGE_BLUE_KEY_X_L)
146 #define GAUGE_BLUE_KEY_Y (SM_HIRES?GAUGE_BLUE_KEY_Y_H:GAUGE_BLUE_KEY_Y_L)
148 #define GAUGE_GOLD_KEY_X_L 273
149 #define GAUGE_GOLD_KEY_Y_L 162
150 #define GAUGE_GOLD_KEY_X_H 537
151 #define GAUGE_GOLD_KEY_Y_H 395
152 #define GAUGE_GOLD_KEY_X (SM_HIRES?GAUGE_GOLD_KEY_X_H:GAUGE_GOLD_KEY_X_L)
153 #define GAUGE_GOLD_KEY_Y (SM_HIRES?GAUGE_GOLD_KEY_Y_H:GAUGE_GOLD_KEY_Y_L)
155 #define GAUGE_RED_KEY_X_L 274
156 #define GAUGE_RED_KEY_Y_L 172
157 #define GAUGE_RED_KEY_X_H 539
158 #define GAUGE_RED_KEY_Y_H 416
159 #define GAUGE_RED_KEY_X (SM_HIRES?GAUGE_RED_KEY_X_H:GAUGE_RED_KEY_X_L)
160 #define GAUGE_RED_KEY_Y (SM_HIRES?GAUGE_RED_KEY_Y_H:GAUGE_RED_KEY_Y_L)
164 #define SB_GAUGE_KEYS_X_L 11
165 #define SB_GAUGE_KEYS_X_H 26
166 #define SB_GAUGE_KEYS_X (SM_HIRES?SB_GAUGE_KEYS_X_H:SB_GAUGE_KEYS_X_L)
168 #define SB_GAUGE_BLUE_KEY_Y_L 153
169 #define SB_GAUGE_GOLD_KEY_Y_L 169
170 #define SB_GAUGE_RED_KEY_Y_L 185
172 #define SB_GAUGE_BLUE_KEY_Y_H 390
173 #define SB_GAUGE_GOLD_KEY_Y_H 422
174 #define SB_GAUGE_RED_KEY_Y_H 454
176 #define SB_GAUGE_BLUE_KEY_Y (SM_HIRES?SB_GAUGE_BLUE_KEY_Y_H:SB_GAUGE_BLUE_KEY_Y_L)
177 #define SB_GAUGE_GOLD_KEY_Y (SM_HIRES?SB_GAUGE_GOLD_KEY_Y_H:SB_GAUGE_GOLD_KEY_Y_L)
178 #define SB_GAUGE_RED_KEY_Y (SM_HIRES?SB_GAUGE_RED_KEY_Y_H:SB_GAUGE_RED_KEY_Y_L)
180 // cockpit enery gauges
182 #define LEFT_ENERGY_GAUGE_X_L 70
183 #define LEFT_ENERGY_GAUGE_Y_L 131
184 #define LEFT_ENERGY_GAUGE_W_L 64
185 #define LEFT_ENERGY_GAUGE_H_L 8
187 #define LEFT_ENERGY_GAUGE_X_H 137
188 #define LEFT_ENERGY_GAUGE_Y_H 314
189 #define LEFT_ENERGY_GAUGE_W_H 133
190 #define LEFT_ENERGY_GAUGE_H_H 21
192 #define LEFT_ENERGY_GAUGE_X (SM_HIRES?LEFT_ENERGY_GAUGE_X_H:LEFT_ENERGY_GAUGE_X_L)
193 #define LEFT_ENERGY_GAUGE_Y (SM_HIRES?LEFT_ENERGY_GAUGE_Y_H:LEFT_ENERGY_GAUGE_Y_L)
194 #define LEFT_ENERGY_GAUGE_W (SM_HIRES?LEFT_ENERGY_GAUGE_W_H:LEFT_ENERGY_GAUGE_W_L)
195 #define LEFT_ENERGY_GAUGE_H (SM_HIRES?LEFT_ENERGY_GAUGE_H_H:LEFT_ENERGY_GAUGE_H_L)
197 #define RIGHT_ENERGY_GAUGE_X (SM_HIRES?380:190)
198 #define RIGHT_ENERGY_GAUGE_Y (SM_HIRES?314:131)
199 #define RIGHT_ENERGY_GAUGE_W (SM_HIRES?133:64)
200 #define RIGHT_ENERGY_GAUGE_H (SM_HIRES?21:8)
202 // cockpit afterburner gauge
204 #define AFTERBURNER_GAUGE_X_L 45-1
205 #define AFTERBURNER_GAUGE_Y_L 158
206 #define AFTERBURNER_GAUGE_W_L 12
207 #define AFTERBURNER_GAUGE_H_L 32
209 #define AFTERBURNER_GAUGE_X_H 88
210 #define AFTERBURNER_GAUGE_Y_H 377
211 #define AFTERBURNER_GAUGE_W_H 21
212 #define AFTERBURNER_GAUGE_H_H 65
214 #define AFTERBURNER_GAUGE_X (SM_HIRES?AFTERBURNER_GAUGE_X_H:AFTERBURNER_GAUGE_X_L)
215 #define AFTERBURNER_GAUGE_Y (SM_HIRES?AFTERBURNER_GAUGE_Y_H:AFTERBURNER_GAUGE_Y_L)
216 #define AFTERBURNER_GAUGE_W (SM_HIRES?AFTERBURNER_GAUGE_W_H:AFTERBURNER_GAUGE_W_L)
217 #define AFTERBURNER_GAUGE_H (SM_HIRES?AFTERBURNER_GAUGE_H_H:AFTERBURNER_GAUGE_H_L)
221 #define SB_ENERGY_GAUGE_X (SM_HIRES?196:98)
222 #define SB_ENERGY_GAUGE_Y (SM_HIRES?382:(155-2))
223 #define SB_ENERGY_GAUGE_W (SM_HIRES?32:16)
224 #define SB_ENERGY_GAUGE_H (SM_HIRES?60:29)
226 // sb afterburner gauge
228 #define SB_AFTERBURNER_GAUGE_X (SM_HIRES?196:98)
229 #define SB_AFTERBURNER_GAUGE_Y (SM_HIRES?446:184)
230 #define SB_AFTERBURNER_GAUGE_W (SM_HIRES?33:16)
231 #define SB_AFTERBURNER_GAUGE_H (SM_HIRES?29:13)
233 #define SB_ENERGY_NUM_X (SB_ENERGY_GAUGE_X+(SM_HIRES?4:2))
234 #define SB_ENERGY_NUM_Y (SM_HIRES?457:175)
236 #define SHIELD_GAUGE_X (SM_HIRES?292:146)
237 #define SHIELD_GAUGE_Y (SM_HIRES?374:155)
238 #define SHIELD_GAUGE_W (SM_HIRES?70:35)
239 #define SHIELD_GAUGE_H (SM_HIRES?77:32)
241 #define SHIP_GAUGE_X (SHIELD_GAUGE_X+(SM_HIRES?11:5))
242 #define SHIP_GAUGE_Y (SHIELD_GAUGE_Y+(SM_HIRES?10:5))
244 #define SB_SHIELD_GAUGE_X (SM_HIRES?247:123) //139
245 #define SB_SHIELD_GAUGE_Y (SM_HIRES?395:163)
247 #define SB_SHIP_GAUGE_X (SB_SHIELD_GAUGE_X+(SM_HIRES?11:5))
248 #define SB_SHIP_GAUGE_Y (SB_SHIELD_GAUGE_Y+(SM_HIRES?10:5))
250 #define SB_SHIELD_NUM_X (SB_SHIELD_GAUGE_X+(SM_HIRES?21:12)) //151
251 #define SB_SHIELD_NUM_Y (SB_SHIELD_GAUGE_Y-(SM_HIRES?16:8)) //156 -- MWA used to be hard coded to 156
253 #define NUMERICAL_GAUGE_X (SM_HIRES?308:154)
254 #define NUMERICAL_GAUGE_Y (SM_HIRES?316:130)
255 #define NUMERICAL_GAUGE_W (SM_HIRES?38:19)
256 #define NUMERICAL_GAUGE_H (SM_HIRES?55:22)
258 #define PRIMARY_W_PIC_X (SM_HIRES?(135-10):64)
259 #define PRIMARY_W_PIC_Y (SM_HIRES?370:154)
260 #define PRIMARY_W_TEXT_X (SM_HIRES?182:87)
261 #define PRIMARY_W_TEXT_Y (SM_HIRES?400:157)
262 #define PRIMARY_AMMO_X (SM_HIRES?186:(96-3))
263 #define PRIMARY_AMMO_Y (SM_HIRES?420:171)
265 #define SECONDARY_W_PIC_X (SM_HIRES?466:234)
266 #define SECONDARY_W_PIC_Y (SM_HIRES?374:154)
267 #define SECONDARY_W_TEXT_X (SM_HIRES?413:207)
268 #define SECONDARY_W_TEXT_Y (SM_HIRES?378:157)
269 #define SECONDARY_AMMO_X (SM_HIRES?428:213)
270 #define SECONDARY_AMMO_Y (SM_HIRES?407:171)
272 #define SB_LIVES_X (SM_HIRES?(550-10-3):266)
273 #define SB_LIVES_Y (SM_HIRES?450-3:185)
274 #define SB_LIVES_LABEL_X (SM_HIRES?475:237)
275 #define SB_LIVES_LABEL_Y (SB_LIVES_Y+1)
277 #define SB_SCORE_RIGHT_L 301
278 #define SB_SCORE_RIGHT_H (605+8)
279 #define SB_SCORE_RIGHT (SM_HIRES?SB_SCORE_RIGHT_H:SB_SCORE_RIGHT_L)
281 #define SB_SCORE_Y (SM_HIRES?398:158)
282 #define SB_SCORE_LABEL_X (SM_HIRES?475:237)
284 #define SB_SCORE_ADDED_RIGHT (SM_HIRES?SB_SCORE_RIGHT_H:SB_SCORE_RIGHT_L)
285 #define SB_SCORE_ADDED_Y (SM_HIRES?413:165)
287 #define HOMING_WARNING_X (SM_HIRES?14:7)
288 #define HOMING_WARNING_Y (SM_HIRES?415:171)
290 #define BOMB_COUNT_X (SM_HIRES?546:275)
291 #define BOMB_COUNT_Y (SM_HIRES?445:186)
293 #define SB_BOMB_COUNT_X (SM_HIRES?342:171)
294 #define SB_BOMB_COUNT_Y (SM_HIRES?458:191)
296 #define LHX(x) ((x)*(MenuHires?2:1))
297 #define LHY(y) ((y)*(MenuHires?2.4:1))
299 static int score_display[2];
300 static fix score_time;
302 static int old_score[2] = { -1, -1 };
303 static int old_energy[2] = { -1, -1 };
304 static int old_shields[2] = { -1, -1 };
305 static int old_flags[2] = { -1, -1 };
306 static int old_weapon[2][2] = {{ -1, -1 },{-1,-1}};
307 static int old_ammo_count[2][2] = {{ -1, -1 },{-1,-1}};
308 static int Old_Omega_charge[2] = { -1, -1 };
309 static int old_laser_level[2] = { -1, -1 };
310 static int old_cloak[2] = { 0, 0 };
311 static int old_lives[2] = { -1, -1 };
312 static fix old_afterburner[2] = { -1, -1 };
313 static int old_bombcount[2] = { 0, 0 };
315 static int invulnerable_frame = 0;
317 static int cloak_fade_state; //0=steady, -1 fading out, 1 fading in
319 #define WS_SET 0 //in correct state
320 #define WS_FADING_OUT 1
321 #define WS_FADING_IN 2
323 int weapon_box_user[2]={WBU_WEAPON,WBU_WEAPON}; //see WBU_ constants in gauges.h
324 int weapon_box_states[2] = {WS_SET, WS_SET};
325 fix weapon_box_fade_values[2];
327 #define FADE_SCALE (2*i2f(GR_FADE_LEVELS)/REARM_TIME) // fade out and back in REARM_TIME, in fade levels per seconds (int)
329 typedef struct span {
333 //store delta x values from left of box
334 span weapon_window_left[] = { //first span 67,151
381 //store delta x values from left of box
382 span weapon_window_right[] = { //first span 207,154
428 //store delta x values from left of box
429 span weapon_window_left_hires[] = { //first span 67,154
540 //store delta x values from left of box
541 span weapon_window_right_hires[] = { //first span 207,154
652 #define N_LEFT_WINDOW_SPANS (sizeof(weapon_window_left)/sizeof(*weapon_window_left))
653 #define N_RIGHT_WINDOW_SPANS (sizeof(weapon_window_right)/sizeof(*weapon_window_right))
655 #define N_LEFT_WINDOW_SPANS_H (sizeof(weapon_window_left_hires)/sizeof(*weapon_window_left_hires))
656 #define N_RIGHT_WINDOW_SPANS_H (sizeof(weapon_window_right_hires)/sizeof(*weapon_window_right_hires))
658 // defining box boundries for weapon pictures
660 #define PRIMARY_W_BOX_LEFT_L 63
661 #define PRIMARY_W_BOX_TOP_L 151 //154
662 #define PRIMARY_W_BOX_RIGHT_L (PRIMARY_W_BOX_LEFT_L+58)
663 #define PRIMARY_W_BOX_BOT_L (PRIMARY_W_BOX_TOP_L+N_LEFT_WINDOW_SPANS-1)
665 #define PRIMARY_W_BOX_LEFT_H 121
666 #define PRIMARY_W_BOX_TOP_H 364
667 #define PRIMARY_W_BOX_RIGHT_H 242
668 #define PRIMARY_W_BOX_BOT_H (PRIMARY_W_BOX_TOP_H+N_LEFT_WINDOW_SPANS_H-1) //470
670 #define PRIMARY_W_BOX_LEFT (SM_HIRES?PRIMARY_W_BOX_LEFT_H:PRIMARY_W_BOX_LEFT_L)
671 #define PRIMARY_W_BOX_TOP (SM_HIRES?PRIMARY_W_BOX_TOP_H:PRIMARY_W_BOX_TOP_L)
672 #define PRIMARY_W_BOX_RIGHT (SM_HIRES?PRIMARY_W_BOX_RIGHT_H:PRIMARY_W_BOX_RIGHT_L)
673 #define PRIMARY_W_BOX_BOT (SM_HIRES?PRIMARY_W_BOX_BOT_H:PRIMARY_W_BOX_BOT_L)
675 #define SECONDARY_W_BOX_LEFT_L 202 //207
676 #define SECONDARY_W_BOX_TOP_L 151
677 #define SECONDARY_W_BOX_RIGHT_L 263 //(SECONDARY_W_BOX_LEFT+54)
678 #define SECONDARY_W_BOX_BOT_L (SECONDARY_W_BOX_TOP_L+N_RIGHT_WINDOW_SPANS-1)
680 #define SECONDARY_W_BOX_LEFT_H 404
681 #define SECONDARY_W_BOX_TOP_H 363
682 #define SECONDARY_W_BOX_RIGHT_H 529
683 #define SECONDARY_W_BOX_BOT_H (SECONDARY_W_BOX_TOP_H+N_RIGHT_WINDOW_SPANS_H-1) //470
685 #define SECONDARY_W_BOX_LEFT (SM_HIRES?SECONDARY_W_BOX_LEFT_H:SECONDARY_W_BOX_LEFT_L)
686 #define SECONDARY_W_BOX_TOP (SM_HIRES?SECONDARY_W_BOX_TOP_H:SECONDARY_W_BOX_TOP_L)
687 #define SECONDARY_W_BOX_RIGHT (SM_HIRES?SECONDARY_W_BOX_RIGHT_H:SECONDARY_W_BOX_RIGHT_L)
688 #define SECONDARY_W_BOX_BOT (SM_HIRES?SECONDARY_W_BOX_BOT_H:SECONDARY_W_BOX_BOT_L)
690 #define SB_PRIMARY_W_BOX_LEFT_L 34 //50
691 #define SB_PRIMARY_W_BOX_TOP_L 153
692 #define SB_PRIMARY_W_BOX_RIGHT_L (SB_PRIMARY_W_BOX_LEFT_L+53+2)
693 #define SB_PRIMARY_W_BOX_BOT_L (195+1)
695 #define SB_PRIMARY_W_BOX_LEFT_H 68
696 #define SB_PRIMARY_W_BOX_TOP_H 381
697 #define SB_PRIMARY_W_BOX_RIGHT_H 179
698 #define SB_PRIMARY_W_BOX_BOT_H 473
700 #define SB_PRIMARY_W_BOX_LEFT (SM_HIRES?SB_PRIMARY_W_BOX_LEFT_H:SB_PRIMARY_W_BOX_LEFT_L)
701 #define SB_PRIMARY_W_BOX_TOP (SM_HIRES?SB_PRIMARY_W_BOX_TOP_H:SB_PRIMARY_W_BOX_TOP_L)
702 #define SB_PRIMARY_W_BOX_RIGHT (SM_HIRES?SB_PRIMARY_W_BOX_RIGHT_H:SB_PRIMARY_W_BOX_RIGHT_L)
703 #define SB_PRIMARY_W_BOX_BOT (SM_HIRES?SB_PRIMARY_W_BOX_BOT_H:SB_PRIMARY_W_BOX_BOT_L)
705 #define SB_SECONDARY_W_BOX_LEFT_L 169
706 #define SB_SECONDARY_W_BOX_TOP_L 153
707 #define SB_SECONDARY_W_BOX_RIGHT_L (SB_SECONDARY_W_BOX_LEFT_L+54+1)
708 #define SB_SECONDARY_W_BOX_BOT_L (153+43)
710 #define SB_SECONDARY_W_BOX_LEFT_H 338
711 #define SB_SECONDARY_W_BOX_TOP_H 381
712 #define SB_SECONDARY_W_BOX_RIGHT_H 449
713 #define SB_SECONDARY_W_BOX_BOT_H 473
715 #define SB_SECONDARY_W_BOX_LEFT (SM_HIRES?SB_SECONDARY_W_BOX_LEFT_H:SB_SECONDARY_W_BOX_LEFT_L) //210
716 #define SB_SECONDARY_W_BOX_TOP (SM_HIRES?SB_SECONDARY_W_BOX_TOP_H:SB_SECONDARY_W_BOX_TOP_L)
717 #define SB_SECONDARY_W_BOX_RIGHT (SM_HIRES?SB_SECONDARY_W_BOX_RIGHT_H:SB_SECONDARY_W_BOX_RIGHT_L)
718 #define SB_SECONDARY_W_BOX_BOT (SM_HIRES?SB_SECONDARY_W_BOX_BOT_H:SB_SECONDARY_W_BOX_BOT_L)
720 #define SB_PRIMARY_W_PIC_X (SB_PRIMARY_W_BOX_LEFT+1) //51
721 #define SB_PRIMARY_W_PIC_Y (SM_HIRES?382:154)
722 #define SB_PRIMARY_W_TEXT_X (SB_PRIMARY_W_BOX_LEFT+(SM_HIRES?50:24)) //(51+23)
723 #define SB_PRIMARY_W_TEXT_Y (SM_HIRES?390:157)
724 #define SB_PRIMARY_AMMO_X (SB_PRIMARY_W_BOX_LEFT+(SM_HIRES?(38+20):30)) //((SB_PRIMARY_W_BOX_LEFT+33)-3) //(51+32)
725 #define SB_PRIMARY_AMMO_Y (SM_HIRES?410:171)
727 #define SB_SECONDARY_W_PIC_X (SM_HIRES?385:(SB_SECONDARY_W_BOX_LEFT+29)) //(212+27)
728 #define SB_SECONDARY_W_PIC_Y (SM_HIRES?382:154)
729 #define SB_SECONDARY_W_TEXT_X (SB_SECONDARY_W_BOX_LEFT+2) //212
730 #define SB_SECONDARY_W_TEXT_Y (SM_HIRES?389:157)
731 #define SB_SECONDARY_AMMO_X (SB_SECONDARY_W_BOX_LEFT+(SM_HIRES?(14-4):11)) //(212+9)
732 #define SB_SECONDARY_AMMO_Y (SM_HIRES?414:171)
734 typedef struct gauge_box {
736 int right,bot; //maximal box
737 span *spanlist; //list of left,right spans for copy
740 gauge_box gauge_boxes[] = {
742 // primary left/right low res
743 {PRIMARY_W_BOX_LEFT_L,PRIMARY_W_BOX_TOP_L,PRIMARY_W_BOX_RIGHT_L,PRIMARY_W_BOX_BOT_L,weapon_window_left},
744 {SECONDARY_W_BOX_LEFT_L,SECONDARY_W_BOX_TOP_L,SECONDARY_W_BOX_RIGHT_L,SECONDARY_W_BOX_BOT_L,weapon_window_right},
746 //sb left/right low res
747 {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},
748 {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},
750 // primary left/right hires
751 {PRIMARY_W_BOX_LEFT_H,PRIMARY_W_BOX_TOP_H,PRIMARY_W_BOX_RIGHT_H,PRIMARY_W_BOX_BOT_H,weapon_window_left_hires},
752 {SECONDARY_W_BOX_LEFT_H,SECONDARY_W_BOX_TOP_H,SECONDARY_W_BOX_RIGHT_H,SECONDARY_W_BOX_BOT_H,weapon_window_right_hires},
754 // sb left/right hires
755 {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},
756 {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},
759 // these macros refer to arrays above
761 #define COCKPIT_PRIMARY_BOX (SM_HIRES?4:0)
762 #define COCKPIT_SECONDARY_BOX (SM_HIRES?5:1)
763 #define SB_PRIMARY_BOX (SM_HIRES?6:2)
764 #define SB_SECONDARY_BOX (SM_HIRES?7:3)
766 int Color_0_31_0 = -1;
768 //copy a box from the off-screen buffer to the visible page
769 void copy_gauge_box(gauge_box *box,grs_bitmap *bm)
772 int n_spans = box->bot-box->top+1;
775 //gr_setcolor(BM_XRGB(31,0,0));
777 for (cnt=0,y=box->top;cnt<n_spans;cnt++,y++) {
778 gr_bm_ubitblt(box->spanlist[cnt].r-box->spanlist[cnt].l+1,1,
779 box->left+box->spanlist[cnt].l,y,box->left+box->spanlist[cnt].l,y,bm,&grd_curcanv->cv_bitmap);
781 //gr_scanline(box->left+box->spanlist[cnt].l,box->left+box->spanlist[cnt].r,y);
786 gr_bm_ubitblt(box->right-box->left+1,box->bot-box->top+1,
787 box->left,box->top,box->left,box->top,
788 bm,&grd_curcanv->cv_bitmap);
792 //fills in the coords of the hostage video window
793 void get_hostage_window_coords(int *x,int *y,int *w,int *h)
795 if (Cockpit_mode.intval == CM_STATUS_BAR) {
796 *x = SB_SECONDARY_W_BOX_LEFT;
797 *y = SB_SECONDARY_W_BOX_TOP;
798 *w = SB_SECONDARY_W_BOX_RIGHT - SB_SECONDARY_W_BOX_LEFT + 1;
799 *h = SB_SECONDARY_W_BOX_BOT - SB_SECONDARY_W_BOX_TOP + 1;
802 *x = SECONDARY_W_BOX_LEFT;
803 *y = SECONDARY_W_BOX_TOP;
804 *w = SECONDARY_W_BOX_RIGHT - SECONDARY_W_BOX_LEFT + 1;
805 *h = SECONDARY_W_BOX_BOT - SECONDARY_W_BOX_TOP + 1;
810 //these should be in gr.h
811 #define cv_w cv_bitmap.bm_w
812 #define cv_h cv_bitmap.bm_h
814 extern int HUD_nmessages, hud_first; // From hud.c
815 extern char HUD_messages[HUD_MAX_NUM][HUD_MESSAGE_LENGTH+5];
816 extern fix ThisLevelTime;
817 extern fix Omega_charge;
819 void hud_show_score()
824 if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
827 gr_set_curfont( GAME_FONT );
829 if ( ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP)) ) {
830 sprintf(score_str, "%s: %5d", TXT_KILLS, Players[Player_num].net_kills_total);
832 sprintf(score_str, "%s: %5d", TXT_SCORE, Players[Player_num].score);
835 gr_get_string_size(score_str, &w, &h, &aw );
837 if (Color_0_31_0 == -1)
838 Color_0_31_0 = gr_getcolor(0,31,0);
839 gr_set_fontcolor(Color_0_31_0, -1);
841 gr_printf(grd_curcanv->cv_w-w-LHX(2), 3, score_str);
844 void hud_show_timer_count()
852 if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
856 if ((Game_mode & GM_NETWORK) && Netgame.PlayTimeAllowed)
858 timevar=i2f (Netgame.PlayTimeAllowed*5*60);
859 i=f2i(timevar-ThisLevelTime);
862 sprintf(score_str, "T - %5d", i);
864 gr_get_string_size(score_str, &w, &h, &aw );
866 if (Color_0_31_0 == -1)
867 Color_0_31_0 = gr_getcolor(0,31,0);
868 gr_set_fontcolor(Color_0_31_0, -1);
870 if (i>-1 && !Control_center_destroyed)
871 gr_printf(grd_curcanv->cv_w-w-LHX(10), LHX(11), score_str);
877 //y offset between lines on HUD
880 void hud_show_score_added()
886 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
889 if (score_display[0] == 0)
892 gr_set_curfont( GAME_FONT );
894 score_time -= FrameTime;
895 if (score_time > 0) {
896 color = f2i(score_time * 20) + 12;
898 if (color < 10) color = 12;
899 if (color > 31) color = 30;
901 color = color - (color % 4); // Only allowing colors 12,16,20,24,28 speeds up gr_getcolor, improves caching
903 if (Cheats_enabled.intval)
904 sprintf(score_str, "%s", TXT_CHEATER);
906 sprintf(score_str, "%5d", score_display[0]);
908 gr_get_string_size(score_str, &w, &h, &aw );
909 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
910 gr_printf(grd_curcanv->cv_w-w-LHX(2+10), Line_spacing+4, score_str);
913 score_display[0] = 0;
923 static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
926 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
931 //if (old_score[VR_current_page] == redraw_score)
933 gr_set_curfont( GAME_FONT );
934 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
936 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
938 gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_KILLS);
942 gr_printf(SB_SCORE_LABEL_X,SB_SCORE_Y,"%s:", TXT_SCORE);
946 gr_set_curfont( GAME_FONT );
947 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
948 sprintf(score_str, "%5d", Players[Player_num].net_kills_total);
950 sprintf(score_str, "%5d", Players[Player_num].score);
951 gr_get_string_size(score_str, &w, &h, &aw );
953 x = SB_SCORE_RIGHT-w-LHX(2);
957 gr_setcolor(BM_XRGB(0,0,0));
958 gr_rect(last_x[(SM_HIRES?2:0) + VR_current_page], y, SB_SCORE_RIGHT, y + GAME_FONT->ft_h);
960 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
961 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
963 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
965 gr_printf(x,y,score_str);
967 last_x[(SM_HIRES?2:0) + VR_current_page] = x;
970 void sb_show_score_added()
976 static int last_x[4]={SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
977 static int last_score_display[2] = { -1, -1};
979 if ( (Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP) )
982 if (score_display[VR_current_page] == 0)
985 gr_set_curfont( GAME_FONT );
987 score_time -= FrameTime;
988 if (score_time > 0) {
989 if (score_display[VR_current_page] != last_score_display[VR_current_page])
991 gr_setcolor(BM_XRGB(0,0,0));
992 gr_rect(last_x[(SM_HIRES?2:0) + VR_current_page], SB_SCORE_ADDED_Y, SB_SCORE_ADDED_RIGHT, SB_SCORE_ADDED_Y + GAME_FONT->ft_h);
994 last_score_display[VR_current_page] = score_display[VR_current_page];
997 color = f2i(score_time * 20) + 10;
999 if (color < 10) color = 10;
1000 if (color > 31) color = 31;
1002 if (Cheats_enabled.intval)
1003 sprintf(score_str, "%s", TXT_CHEATER);
1005 sprintf(score_str, "%5d", score_display[VR_current_page]);
1007 gr_get_string_size(score_str, &w, &h, &aw );
1009 x = SB_SCORE_ADDED_RIGHT-w-LHX(2);
1011 gr_set_fontcolor(gr_getcolor(0, color, 0),-1 );
1013 gr_printf(x, SB_SCORE_ADDED_Y, score_str);
1016 last_x[(SM_HIRES?2:0) + VR_current_page] = x;
1020 gr_setcolor(BM_XRGB(0,0,0));
1021 gr_rect(last_x[(SM_HIRES?2:0) + VR_current_page], SB_SCORE_ADDED_Y, SB_SCORE_ADDED_RIGHT, SB_SCORE_ADDED_Y + GAME_FONT->ft_h);
1024 score_display[VR_current_page] = 0;
1029 fix Last_warning_beep_time[2] = {0,0}; // Time we last played homing missile warning beep.
1031 // -----------------------------------------------------------------------------
1032 void play_homing_warning(void)
1036 if (Endlevel_sequence || Player_is_dead)
1039 if (Players[Player_num].homing_object_dist >= 0) {
1040 beep_delay = Players[Player_num].homing_object_dist/128;
1041 if (beep_delay > F1_0)
1043 else if (beep_delay < F1_0/8)
1044 beep_delay = F1_0/8;
1046 if (Last_warning_beep_time[VR_current_page] > GameTime)
1047 Last_warning_beep_time[VR_current_page] = 0;
1049 if (GameTime - Last_warning_beep_time[VR_current_page] > beep_delay/2) {
1050 digi_play_sample( SOUND_HOMING_WARNING, F1_0 );
1051 Last_warning_beep_time[VR_current_page] = GameTime;
1056 int Last_homing_warning_shown[2]={-1,-1};
1058 // -----------------------------------------------------------------------------
1059 void show_homing_warning(void)
1061 if ((Cockpit_mode.intval == CM_STATUS_BAR) || (Endlevel_sequence)) {
1062 if (Last_homing_warning_shown[VR_current_page] == 1) {
1063 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1065 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1067 Last_homing_warning_shown[VR_current_page] = 0;
1072 gr_set_current_canvas( get_current_game_screen() );
1075 if (Players[Player_num].homing_object_dist >= 0) {
1077 if (GameTime & 0x4000) {
1078 if (Last_homing_warning_shown[VR_current_page] != 1) {
1079 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_ON );
1080 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_ON) ] );
1081 Last_homing_warning_shown[VR_current_page] = 1;
1084 if (Last_homing_warning_shown[VR_current_page] != 0) {
1085 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1086 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1087 Last_homing_warning_shown[VR_current_page] = 0;
1090 } else if (Last_homing_warning_shown[VR_current_page] != 0) {
1091 PAGE_IN_GAUGE( GAUGE_HOMING_WARNING_OFF );
1092 gr_ubitmapm( HOMING_WARNING_X, HOMING_WARNING_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_HOMING_WARNING_OFF) ] );
1093 Last_homing_warning_shown[VR_current_page] = 0;
1097 #define MAX_SHOWN_LIVES 4
1099 extern int Game_window_y;
1102 void hud_show_homing_warning(void)
1104 if (Players[Player_num].homing_object_dist >= 0) {
1105 if (GameTime & 0x4000) {
1106 int x=0x8000, y=grd_curcanv->cv_h-Line_spacing;
1108 if (weapon_box_user[0] != WBU_WEAPON || weapon_box_user[1] != WBU_WEAPON) {
1109 int wy = (weapon_box_user[0] != WBU_WEAPON)?SW_y[0]:SW_y[1];
1110 y = min(y,(wy - Line_spacing - Game_window_y));
1113 gr_set_curfont( GAME_FONT );
1114 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1115 gr_printf(x,y,TXT_LOCK);
1120 void hud_show_keys(void)
1122 int y = 3*Line_spacing;
1123 int dx = GAME_FONT->ft_w+GAME_FONT->ft_w/2;
1125 if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY) {
1126 PAGE_IN_GAUGE( KEY_ICON_BLUE );
1127 gr_ubitmapm(2,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_BLUE) ] );
1131 if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY) {
1132 PAGE_IN_GAUGE( KEY_ICON_YELLOW );
1133 gr_ubitmapm(2+dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_YELLOW) ] );
1136 if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY) {
1137 PAGE_IN_GAUGE( KEY_ICON_RED );
1138 gr_ubitmapm(2+2*dx,y,&GameBitmaps[ GET_GAUGE_INDEX(KEY_ICON_RED) ] );
1144 extern grs_bitmap Orb_icons[2];
1146 void hud_show_orbs (void)
1148 if (Game_mode & GM_HOARD) {
1154 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
1156 x = 4*GAME_FONT->ft_w;
1158 else if (Cockpit_mode.intval == CM_STATUS_BAR) {
1160 x = GAME_FONT->ft_w;
1162 else if (Cockpit_mode.intval == CM_FULL_SCREEN) {
1164 x = GAME_FONT->ft_w;
1169 Int3(); //what sort of cockpit?
1171 bm = &Orb_icons[FontHires];
1172 gr_ubitmapm(x,y,bm);
1174 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1175 gr_printf(x+bm->bm_w+bm->bm_w/2, y+(FontHires?2:1), "x %d", Players[Player_num].secondary_ammo[PROXIMITY_INDEX]);
1180 void hud_show_flag(void)
1182 if ((Game_mode & GM_CAPTURE) && (Players[Player_num].flags & PLAYER_FLAGS_FLAG)) {
1187 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
1189 x = 4*GAME_FONT->ft_w;
1191 else if (Cockpit_mode.intval == CM_STATUS_BAR) {
1193 x = GAME_FONT->ft_w;
1195 else if (Cockpit_mode.intval == CM_FULL_SCREEN) {
1197 x = GAME_FONT->ft_w;
1202 Int3(); //what sort of cockpit?
1205 icon = (get_team(Player_num) == TEAM_BLUE)?FLAG_ICON_RED:FLAG_ICON_BLUE;
1207 PAGE_IN_GAUGE( icon );
1208 gr_ubitmapm(x,y,&GameBitmaps[ GET_GAUGE_INDEX(icon) ] );
1214 void hud_show_energy(void)
1216 //gr_set_current_canvas(&VR_render_sub_buffer[0]); //render off-screen
1217 gr_set_curfont( GAME_FONT );
1218 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1219 if (Game_mode & GM_MULTI)
1220 gr_printf(2, grd_curcanv->cv_h-5*Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1222 gr_printf(2, grd_curcanv->cv_h-Line_spacing,"%s: %i", TXT_ENERGY, f2ir(Players[Player_num].energy));
1224 if (Newdemo_state==ND_STATE_RECORDING ) {
1225 int energy = f2ir(Players[Player_num].energy);
1227 if (energy != old_energy[VR_current_page]) {
1228 newdemo_record_player_energy(old_energy[VR_current_page], energy);
1229 old_energy[VR_current_page] = energy;
1234 void hud_show_afterburner(void)
1238 if (! (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER))
1239 return; //don't draw if don't have
1241 gr_set_curfont( GAME_FONT );
1242 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1244 y = (Game_mode & GM_MULTI)?(-8*Line_spacing):(-3*Line_spacing);
1246 gr_printf(2, grd_curcanv->cv_h+y, "burn: %d%%" , fixmul(Afterburner_charge,100));
1248 if (Newdemo_state==ND_STATE_RECORDING ) {
1250 if (Afterburner_charge != old_afterburner[VR_current_page]) {
1251 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
1252 old_afterburner[VR_current_page] = Afterburner_charge;
1257 char *d2_very_short_secondary_weapon_names[] =
1258 {"Flash","Guided","SmrtMine","Mercury","Shaker"};
1260 #define SECONDARY_WEAPON_NAMES_VERY_SHORT(weapon_num) \
1261 ((weapon_num <= MEGA_INDEX)?(*(&TXT_CONCUSSION + (weapon_num))): \
1262 d2_very_short_secondary_weapon_names[weapon_num-SMISSILE1_INDEX])
1264 //return which bomb will be dropped next time the bomb key is pressed
1265 extern int which_bomb(void);
1267 void show_bomb_count(int x,int y,int bg_color,int always_show)
1269 int bomb,count,countx;
1272 bomb = which_bomb();
1273 count = Players[Player_num].secondary_ammo[bomb];
1276 count = min(count,99); //only have room for 2 digits - cheating give 200
1279 countx = (bomb==PROXIMITY_INDEX)?count:-count;
1281 if (always_show && count == 0) //no bombs, draw nothing on HUD
1284 //if (!always_show && countx == old_bombcount[VR_current_page])
1287 // I hate doing this off of hard coded coords!!!!
1289 if (Cockpit_mode.intval == CM_STATUS_BAR) { //draw background
1290 gr_setcolor(bg_color);
1292 gr_rect(169,189,189,196);
1293 gr_setcolor(gr_find_closest_color(10,10,10));
1294 gr_scanline(168,189,189);
1296 gr_rect(338,453,378,470);
1298 gr_setcolor(gr_find_closest_color(10,10,10));
1299 gr_scanline(336,378,453);
1304 gr_set_fontcolor((bomb==PROXIMITY_INDEX)?gr_find_closest_color(55,0,0):gr_getcolor(59,50,21),bg_color);
1306 gr_set_fontcolor(bg_color,bg_color); //erase by drawing in background color
1308 snprintf(txt, sizeof(txt)-1, "B:%02d", count);
1310 while ((t=strchr(txt,'1')) != NULL)
1311 *t = '\x84'; //convert to wide '1'
1315 old_bombcount[VR_current_page] = countx;
1318 void draw_primary_ammo_info(int ammo_count)
1320 if (Cockpit_mode.intval == CM_STATUS_BAR)
1321 draw_ammo_info(SB_PRIMARY_AMMO_X,SB_PRIMARY_AMMO_Y,ammo_count,1);
1323 draw_ammo_info(PRIMARY_AMMO_X,PRIMARY_AMMO_Y,ammo_count,1);
1326 //convert '1' characters to special wide ones
1327 #define convert_1s(s) do {char *p=s; while ((p=strchr(p,'1')) != NULL) *p=(char)132;} while(0)
1329 void hud_show_weapons(void)
1334 char weapon_str[32];
1336 // gr_set_current_canvas(&VR_render_sub_buffer[0]); //render off-screen
1337 gr_set_curfont( GAME_FONT );
1338 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1340 y = grd_curcanv->cv_h;
1342 if (Game_mode & GM_MULTI)
1343 y -= 4*Line_spacing;
1345 weapon_name = PRIMARY_WEAPON_NAMES_SHORT(Primary_weapon);
1347 switch (Primary_weapon) {
1349 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)
1350 sprintf(weapon_str, "%s %s %i", TXT_QUAD, weapon_name, Players[Player_num].laser_level+1);
1352 sprintf(weapon_str, "%s %i", weapon_name, Players[Player_num].laser_level+1);
1355 case SUPER_LASER_INDEX: Int3(); break; //no such thing as super laser
1359 sprintf(weapon_str, "%s: %i", weapon_name, f2i((unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX] * (unsigned) VULCAN_AMMO_SCALE));
1360 convert_1s(weapon_str);
1363 case SPREADFIRE_INDEX:
1368 strcpy(weapon_str, weapon_name);
1371 sprintf(weapon_str, "%s: %03i", weapon_name, Omega_charge * 100/MAX_OMEGA_CHARGE);
1372 convert_1s(weapon_str);
1375 default: Int3(); weapon_str[0] = 0; break;
1378 gr_get_string_size(weapon_str, &w, &h, &aw );
1379 gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-2*Line_spacing, weapon_str);
1381 if (Primary_weapon == VULCAN_INDEX) {
1382 if (Players[Player_num].primary_ammo[Primary_weapon] != old_ammo_count[0][VR_current_page]) {
1383 if (Newdemo_state == ND_STATE_RECORDING)
1384 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[Primary_weapon]);
1385 old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[Primary_weapon];
1389 if (Primary_weapon == OMEGA_INDEX) {
1390 if (Omega_charge != Old_Omega_charge[VR_current_page]) {
1391 if (Newdemo_state == ND_STATE_RECORDING)
1392 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
1393 Old_Omega_charge[VR_current_page] = Omega_charge;
1397 weapon_name = SECONDARY_WEAPON_NAMES_VERY_SHORT(Secondary_weapon);
1399 sprintf(weapon_str, "%s %d",weapon_name,Players[Player_num].secondary_ammo[Secondary_weapon]);
1400 gr_get_string_size(weapon_str, &w, &h, &aw );
1401 gr_printf(grd_curcanv->cv_bitmap.bm_w-5-w, y-Line_spacing, weapon_str);
1403 if (Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page]) {
1404 if (Newdemo_state == ND_STATE_RECORDING)
1405 newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
1406 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
1409 show_bomb_count(grd_curcanv->cv_bitmap.bm_w-(3*GAME_FONT->ft_w+(FontHires?0:2)), y-3*Line_spacing,-1,1);
1412 void hud_show_cloak_invuln(void)
1414 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1416 if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
1417 int y = grd_curcanv->cv_h;
1419 if (Game_mode & GM_MULTI)
1420 y -= 7*Line_spacing;
1422 y -= 4*Line_spacing;
1424 if ((Players[Player_num].cloak_time+CLOAK_TIME_MAX - GameTime > F1_0*3 ) || (GameTime & 0x8000))
1425 gr_printf(2, y, "%s", TXT_CLOAKED);
1428 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
1429 int y = grd_curcanv->cv_h;
1431 if (Game_mode & GM_MULTI)
1432 y -= 10*Line_spacing;
1434 y -= 5*Line_spacing;
1436 if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000))
1437 gr_printf(2, y, "%s", TXT_INVULNERABLE);
1442 void hud_show_shield(void)
1444 // gr_set_current_canvas(&VR_render_sub_buffer[0]); //render off-screen
1445 gr_set_curfont( GAME_FONT );
1446 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1448 if ( Players[Player_num].shields >= 0 ) {
1449 if (Game_mode & GM_MULTI)
1450 gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1452 gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: %i", TXT_SHIELD, f2ir(Players[Player_num].shields));
1454 if (Game_mode & GM_MULTI)
1455 gr_printf(2, grd_curcanv->cv_h-6*Line_spacing,"%s: 0", TXT_SHIELD );
1457 gr_printf(2, grd_curcanv->cv_h-2*Line_spacing,"%s: 0", TXT_SHIELD );
1460 if (Newdemo_state==ND_STATE_RECORDING ) {
1461 int shields = f2ir(Players[Player_num].shields);
1463 if (shields != old_shields[VR_current_page]) { // Draw the shield gauge
1464 newdemo_record_player_shields(old_shields[VR_current_page], shields);
1465 old_shields[VR_current_page] = shields;
1470 //draw the icons for number of lives
1471 void hud_show_lives()
1473 if ((HUD_nmessages > 0) && (strlen(HUD_messages[hud_first]) > 38))
1476 if (Game_mode & GM_MULTI) {
1477 gr_set_curfont( GAME_FONT );
1478 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
1479 gr_printf(10, 3, "%s: %d", TXT_DEATHS, Players[Player_num].net_killed_total);
1481 else if (Players[Player_num].lives > 1) {
1483 gr_set_curfont( GAME_FONT );
1484 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1485 PAGE_IN_GAUGE( GAUGE_LIVES );
1486 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1487 gr_ubitmapm(10,3,bm);
1488 gr_printf(10+bm->bm_w+bm->bm_w/2, 4, "x %d", Players[Player_num].lives-1);
1493 void sb_show_lives()
1496 grs_bitmap * bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_LIVES) ];
1500 //if (old_lives[VR_current_page] == -1)
1502 gr_set_curfont( GAME_FONT );
1503 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1504 if (Game_mode & GM_MULTI)
1505 gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_DEATHS);
1507 gr_printf(SB_LIVES_LABEL_X,SB_LIVES_LABEL_Y,"%s:", TXT_LIVES);
1511 if (Game_mode & GM_MULTI)
1513 char killed_str[20];
1515 static int last_x[4] = {SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_L,SB_SCORE_RIGHT_H,SB_SCORE_RIGHT_H};
1518 sprintf(killed_str, "%5d", Players[Player_num].net_killed_total);
1519 gr_get_string_size(killed_str, &w, &h, &aw);
1520 gr_setcolor(BM_XRGB(0,0,0));
1521 gr_rect(last_x[(SM_HIRES?2:0) + VR_current_page], y + 1, SB_SCORE_RIGHT, y + GAME_FONT->ft_h);
1522 gr_set_fontcolor(gr_getcolor(0,20,0),-1);
1523 x = SB_SCORE_RIGHT-w-2;
1524 gr_printf(x, y+1, killed_str);
1525 last_x[(SM_HIRES?2:0) + VR_current_page] = x;
1529 //if (old_lives[VR_current_page]==-1 || Players[Player_num].lives != old_lives[VR_current_page])
1534 gr_setcolor(BM_XRGB(0,0,0));
1536 gr_rect(x, y, SB_SCORE_RIGHT, y+bm->bm_h);
1538 if (Players[Player_num].lives-1 > 0) {
1539 gr_set_curfont( GAME_FONT );
1540 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
1541 PAGE_IN_GAUGE( GAUGE_LIVES );
1543 gr_ubitmapm(x, y,bm);
1544 gr_printf(x+bm->bm_w+GAME_FONT->ft_w, y, "x %d", Players[Player_num].lives-1);
1546 // gr_printf(x+12, y, "x %d", Players[Player_num].lives-1);
1550 // for (i=0;i<draw_count;i++,x+=bm->bm_w+2)
1551 // gr_ubitmapm(x,y,bm);
1557 #ifdef PIGGY_USE_PAGING
1558 extern int Piggy_bitmap_cache_next;
1563 int secs = f2i(Players[Player_num].time_level) % 60;
1564 int mins = f2i(Players[Player_num].time_level) / 60;
1566 gr_set_curfont( GAME_FONT );
1568 if (Color_0_31_0 == -1)
1569 Color_0_31_0 = gr_getcolor(0,31,0);
1570 gr_set_fontcolor(Color_0_31_0, -1 );
1572 gr_printf(grd_curcanv->cv_w-4*GAME_FONT->ft_w,grd_curcanv->cv_h-4*Line_spacing,"%d:%02d", mins, secs);
1574 //@@#ifdef PIGGY_USE_PAGING
1578 //@@ sprintf( text, "%d KB", Piggy_bitmap_cache_next/1024 );
1579 //@@ gr_get_string_size( text, &w, &h, &aw );
1580 //@@ gr_printf(grd_curcanv->cv_w-10-w,grd_curcanv->cv_h/2, text );
1587 #define EXTRA_SHIP_SCORE 50000 //get new ship every this many points
1589 void add_points_to_score(int points)
1593 score_time += f1_0*2;
1594 score_display[0] += points;
1595 score_display[1] += points;
1596 if (score_time > f1_0*4) score_time = f1_0*4;
1598 if (points == 0 || Cheats_enabled.intval)
1601 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
1604 prev_score=Players[Player_num].score;
1606 Players[Player_num].score += points;
1608 if (Newdemo_state == ND_STATE_RECORDING)
1609 newdemo_record_player_score(points);
1612 if (Game_mode & GM_MULTI_COOP)
1615 if (Game_mode & GM_MULTI)
1619 if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1621 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1622 powerup_basic(20, 20, 20, 0, TXT_EXTRA_LIFE);
1623 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1624 digi_play_sample( snd, F1_0 );
1628 void add_bonus_points_to_score(int points)
1632 if (points == 0 || Cheats_enabled.intval)
1635 prev_score=Players[Player_num].score;
1637 Players[Player_num].score += points;
1640 if (Newdemo_state == ND_STATE_RECORDING)
1641 newdemo_record_player_score(points);
1643 if (Game_mode & GM_MULTI)
1646 if (Players[Player_num].score/EXTRA_SHIP_SCORE != prev_score/EXTRA_SHIP_SCORE) {
1648 Players[Player_num].lives += Players[Player_num].score/EXTRA_SHIP_SCORE - prev_score/EXTRA_SHIP_SCORE;
1649 if ((snd=Powerup_info[POW_EXTRA_LIFE].hit_sound) > -1 )
1650 digi_play_sample( snd, F1_0 );
1656 void init_gauge_canvases()
1658 grs_font *save_font = grd_curcanv->cv_font;
1660 gr_set_curfont(GAME_FONT);
1662 PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
1663 PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
1665 Canv_LeftEnergyGauge = gr_create_sub_canvas( grd_curcanv, LEFT_ENERGY_GAUGE_X, LEFT_ENERGY_GAUGE_Y, LEFT_ENERGY_GAUGE_W, LEFT_ENERGY_GAUGE_H );
1666 Canv_SBEnergyGauge = gr_create_sub_canvas( grd_curcanv, SB_ENERGY_GAUGE_X, SB_ENERGY_GAUGE_Y, SB_ENERGY_GAUGE_W, SB_ENERGY_GAUGE_H );
1667 Canv_SBAfterburnerGauge = gr_create_sub_canvas( grd_curcanv, SB_AFTERBURNER_GAUGE_X, SB_AFTERBURNER_GAUGE_Y, SB_AFTERBURNER_GAUGE_W, SB_AFTERBURNER_GAUGE_H );
1668 Canv_RightEnergyGauge = gr_create_sub_canvas( grd_curcanv, RIGHT_ENERGY_GAUGE_X, RIGHT_ENERGY_GAUGE_Y, RIGHT_ENERGY_GAUGE_W, RIGHT_ENERGY_GAUGE_H );
1669 Canv_NumericalGauge = gr_create_sub_canvas( grd_curcanv, NUMERICAL_GAUGE_X, NUMERICAL_GAUGE_Y, NUMERICAL_GAUGE_W, NUMERICAL_GAUGE_H );
1670 Canv_AfterburnerGauge = gr_create_sub_canvas( grd_curcanv, AFTERBURNER_GAUGE_X, AFTERBURNER_GAUGE_Y, AFTERBURNER_GAUGE_W, AFTERBURNER_GAUGE_H );
1672 gr_set_curfont(save_font);
1675 void close_gauge_canvases()
1677 if (Canv_LeftEnergyGauge)
1679 gr_free_sub_canvas( Canv_LeftEnergyGauge );
1680 gr_free_sub_canvas( Canv_SBEnergyGauge );
1681 gr_free_sub_canvas( Canv_SBAfterburnerGauge );
1682 gr_free_sub_canvas( Canv_RightEnergyGauge );
1683 gr_free_sub_canvas( Canv_NumericalGauge );
1684 gr_free_sub_canvas( Canv_AfterburnerGauge );
1692 //draw_gauges_on = 1;
1694 for (i=0; i<2; i++ ) {
1695 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)) )
1700 old_shields[i] = -1;
1704 old_afterburner[i] = -1;
1705 old_bombcount[i] = 0;
1706 old_laser_level[i] = 0;
1708 old_weapon[0][i] = old_weapon[1][i] = -1;
1709 old_ammo_count[0][i] = old_ammo_count[1][i] = -1;
1710 Old_Omega_charge[i] = -1;
1713 cloak_fade_state = 0;
1715 weapon_box_user[0] = weapon_box_user[1] = WBU_WEAPON;
1718 void draw_energy_bar(int energy)
1723 // Draw left energy bar
1724 gr_set_current_canvas( Canv_LeftEnergyGauge );
1725 PAGE_IN_GAUGE( GAUGE_ENERGY_LEFT );
1726 gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_LEFT)] );
1727 gr_setcolor( BM_XRGB(0,0,0) );
1730 not_energy = 61 - (energy*61)/100;
1732 not_energy = 125 - (energy*125)/100;
1735 for (y=0; y < LEFT_ENERGY_GAUGE_H; y++) {
1736 x1 = LEFT_ENERGY_GAUGE_H - 1 - y;
1737 x2 = LEFT_ENERGY_GAUGE_H - 1 - y + not_energy;
1739 if (x2 > LEFT_ENERGY_GAUGE_W - y/3)
1740 x2 = LEFT_ENERGY_GAUGE_W - y/3;
1742 if (x2 > x1) gr_uline( i2f(x1), i2f(y), i2f(x2), i2f(y) );
1745 gr_set_current_canvas( get_current_game_screen() );
1747 // Draw right energy bar
1748 gr_set_current_canvas( Canv_RightEnergyGauge );
1749 PAGE_IN_GAUGE( GAUGE_ENERGY_RIGHT );
1750 gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_ENERGY_RIGHT) ] );
1751 gr_setcolor( BM_XRGB(0,0,0) );
1754 for (y=0; y < RIGHT_ENERGY_GAUGE_H; y++) {
1755 x1 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + 1 + y - not_energy;
1756 x2 = RIGHT_ENERGY_GAUGE_W - RIGHT_ENERGY_GAUGE_H + 1 + y;
1761 if (x2 > x1) gr_uline( i2f(x1), i2f(y), i2f(x2), i2f(y) );
1764 gr_set_current_canvas( get_current_game_screen() );
1767 ubyte afterburner_bar_table[AFTERBURNER_GAUGE_H_L*2] = {
1802 ubyte afterburner_bar_table_hires[AFTERBURNER_GAUGE_H_H*2] = {
1877 void draw_afterburner_bar(int afterburner)
1879 int not_afterburner;
1882 // Draw afterburner bar
1883 gr_set_current_canvas( Canv_AfterburnerGauge );
1884 PAGE_IN_GAUGE( GAUGE_AFTERBURNER );
1885 gr_ubitmapm( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_AFTERBURNER) ] );
1886 gr_setcolor( BM_XRGB(0,0,0) );
1888 not_afterburner = fixmul(f1_0 - afterburner,AFTERBURNER_GAUGE_H);
1890 for (y=0;y<not_afterburner;y++) {
1892 gr_uline( i2f(SM_HIRES ? afterburner_bar_table_hires[y*2] : afterburner_bar_table[y*2]), i2f(y),
1893 i2f((SM_HIRES ? afterburner_bar_table_hires[y*2 + 1] : afterburner_bar_table[y*2 + 1]) + 1), i2f(y) );
1896 gr_set_current_canvas( get_current_game_screen() );
1899 void draw_shield_bar(int shield)
1901 int bm_num = shield>=100?9:(shield / 10);
1903 PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num );
1904 gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
1907 #define CLOAK_FADE_WAIT_TIME 0x400
1909 void draw_player_ship(int cloak_state,int old_cloak_state,int x, int y)
1911 static fix cloak_fade_timer=0;
1912 static int cloak_fade_value=GR_FADE_LEVELS-1;
1913 static int refade = 0;
1914 grs_bitmap *bm = NULL;
1916 if (Game_mode & GM_TEAM) {
1918 PAGE_IN_GAUGE( GAUGE_SHIPS+get_team(Player_num) );
1919 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+get_team(Player_num)) ];
1922 PAGE_IN_GAUGE( GAUGE_SHIPS+Player_num );
1923 bm = &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_SHIPS+Player_num) ];
1927 if (old_cloak_state==-1 && cloak_state)
1930 // mprintf((0, "cloak/oldcloak %d/%d", cloak_state, old_cloak_state));
1933 cloak_fade_value=GR_FADE_LEVELS-1;
1934 cloak_fade_state = 0;
1937 if (cloak_state==1 && old_cloak_state==0)
1938 cloak_fade_state = -1;
1939 //else if (cloak_state==0 && old_cloak_state==1)
1940 // cloak_fade_state = 1;
1942 if (cloak_state && GameTime > Players[Player_num].cloak_time + CLOAK_TIME_MAX - i2f(3)) //doing "about-to-uncloak" effect
1943 if (cloak_fade_state==0)
1944 cloak_fade_state = 2;
1947 if (cloak_fade_state)
1948 cloak_fade_timer -= FrameTime;
1950 while (cloak_fade_state && cloak_fade_timer < 0) {
1952 cloak_fade_timer += CLOAK_FADE_WAIT_TIME;
1954 cloak_fade_value += cloak_fade_state;
1956 if (cloak_fade_value >= GR_FADE_LEVELS-1) {
1957 cloak_fade_value = GR_FADE_LEVELS-1;
1958 if (cloak_fade_state == 2 && cloak_state)
1959 cloak_fade_state = -2;
1961 cloak_fade_state = 0;
1963 else if (cloak_fade_value <= 0) {
1964 cloak_fade_value = 0;
1965 if (cloak_fade_state == -2)
1966 cloak_fade_state = 2;
1968 cloak_fade_state = 0;
1972 // To fade out both pages in a paged mode.
1973 if (refade) refade = 0;
1974 else if (cloak_state && old_cloak_state && !cloak_fade_state && !refade) {
1975 cloak_fade_state = -1;
1979 gr_set_current_canvas(&VR_render_buffer[0]);
1981 gr_ubitmap( x, y, bm);
1983 Gr_scanline_darkening_level = cloak_fade_value;
1984 gr_rect(x, y, x+bm->bm_w-1, y+bm->bm_h-1);
1985 Gr_scanline_darkening_level = GR_FADE_LEVELS;
1987 gr_set_current_canvas( get_current_game_screen() );
1989 gr_bm_ubitbltm( bm->bm_w, bm->bm_h, x, y, x, y, &VR_render_buffer[0].cv_bitmap, &grd_curcanv->cv_bitmap);
1992 #define INV_FRAME_TIME (f1_0/10) //how long for each frame
1994 void draw_numerical_display(int shield, int energy)
1996 gr_set_current_canvas( Canv_NumericalGauge );
1997 gr_set_curfont( GAME_FONT );
1998 PAGE_IN_GAUGE( GAUGE_NUMERICAL );
1999 gr_ubitmap( 0, 0, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_NUMERICAL) ] );
2001 gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2004 gr_printf((shield>99)?3:((shield>9)?5:7),15,"%d",shield);
2005 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2006 gr_printf((energy>99)?3:((energy>9)?5:7),2,"%d",energy);
2008 gr_printf((shield>99)?7:((shield>9)?11:15),33,"%d",shield);
2009 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2010 gr_printf((energy>99)?7:((energy>9)?11:15),4,"%d",energy);
2013 gr_set_current_canvas( get_current_game_screen() );
2019 gr_set_current_canvas( get_current_game_screen() );
2021 if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY ) {
2022 PAGE_IN_GAUGE( GAUGE_BLUE_KEY );
2023 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY) ] );
2025 PAGE_IN_GAUGE( GAUGE_BLUE_KEY_OFF );
2026 gr_ubitmapm( GAUGE_BLUE_KEY_X, GAUGE_BLUE_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_BLUE_KEY_OFF) ] );
2029 if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY) {
2030 PAGE_IN_GAUGE( GAUGE_GOLD_KEY );
2031 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY) ] );
2033 PAGE_IN_GAUGE( GAUGE_GOLD_KEY_OFF );
2034 gr_ubitmapm( GAUGE_GOLD_KEY_X, GAUGE_GOLD_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_GOLD_KEY_OFF) ] );
2037 if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY) {
2038 PAGE_IN_GAUGE( GAUGE_RED_KEY );
2039 gr_ubitmapm( GAUGE_RED_KEY_X, GAUGE_RED_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY) ] );
2041 PAGE_IN_GAUGE( GAUGE_RED_KEY_OFF );
2042 gr_ubitmapm( GAUGE_RED_KEY_X, GAUGE_RED_KEY_Y, &GameBitmaps[ GET_GAUGE_INDEX(GAUGE_RED_KEY_OFF) ] );
2047 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)
2053 gr_setcolor(BM_XRGB(0,0,0));
2055 gr_rect(box->left,box->top,box->right,box->bot);
2057 if (Piggy_hamfile_version >= 3 // !SHAREWARE
2060 bm=&GameBitmaps[Weapon_info[info_index].hires_picture.index];
2061 PIGGY_PAGE_IN( Weapon_info[info_index].hires_picture );
2063 bm=&GameBitmaps[Weapon_info[info_index].picture.index];
2064 PIGGY_PAGE_IN( Weapon_info[info_index].picture );
2069 gr_ubitmapm(pic_x,pic_y,bm);
2071 gr_set_fontcolor(gr_getcolor(0,20,0),-1 );
2073 if ((p=strchr(name,'\n'))!=NULL) {
2075 gr_printf(text_x,text_y,name);
2076 gr_printf(text_x,text_y+grd_curcanv->cv_font->ft_h+1,p+1);
2079 gr_printf(text_x,text_y,name);
2081 // For laser, show level and quadness
2082 if (info_index == LASER_ID || info_index == SUPER_LASER_ID) {
2085 sprintf(temp_str, "%s: 0", TXT_LVL);
2087 temp_str[5] = Players[Player_num].laser_level+1 + '0';
2089 gr_printf(text_x,text_y+Line_spacing, temp_str);
2091 if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) {
2092 strcpy(temp_str, TXT_QUAD);
2093 gr_printf(text_x,text_y+2*Line_spacing, temp_str);
2101 void draw_weapon_info(int weapon_type,int weapon_num,int laser_level)
2105 if (weapon_type == 0) {
2106 info_index = Primary_weapon_to_weapon_info[weapon_num];
2108 if (info_index == LASER_ID && laser_level > MAX_LASER_LEVEL)
2109 info_index = SUPER_LASER_ID;
2111 if (Cockpit_mode.intval == CM_STATUS_BAR)
2112 draw_weapon_info_sub(info_index,
2113 &gauge_boxes[SB_PRIMARY_BOX],
2114 SB_PRIMARY_W_PIC_X,SB_PRIMARY_W_PIC_Y,
2115 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2116 SB_PRIMARY_W_TEXT_X,SB_PRIMARY_W_TEXT_Y);
2118 draw_weapon_info_sub(info_index,
2119 &gauge_boxes[COCKPIT_PRIMARY_BOX],
2120 PRIMARY_W_PIC_X,PRIMARY_W_PIC_Y,
2121 PRIMARY_WEAPON_NAMES_SHORT(weapon_num),
2122 PRIMARY_W_TEXT_X,PRIMARY_W_TEXT_Y);
2126 info_index = Secondary_weapon_to_weapon_info[weapon_num];
2128 if (Cockpit_mode.intval == CM_STATUS_BAR)
2129 draw_weapon_info_sub(info_index,
2130 &gauge_boxes[SB_SECONDARY_BOX],
2131 SB_SECONDARY_W_PIC_X,SB_SECONDARY_W_PIC_Y,
2132 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2133 SB_SECONDARY_W_TEXT_X,SB_SECONDARY_W_TEXT_Y);
2135 draw_weapon_info_sub(info_index,
2136 &gauge_boxes[COCKPIT_SECONDARY_BOX],
2137 SECONDARY_W_PIC_X,SECONDARY_W_PIC_Y,
2138 SECONDARY_WEAPON_NAMES_SHORT(weapon_num),
2139 SECONDARY_W_TEXT_X,SECONDARY_W_TEXT_Y);
2143 void draw_ammo_info(int x,int y,int ammo_count,int primary)
2149 w = (grd_curcanv->cv_font->ft_w*7)/2;
2151 w = (grd_curcanv->cv_font->ft_w*5)/2;
2153 gr_setcolor(BM_XRGB(0,0,0));
2154 gr_rect(x,y,x+w,y+grd_curcanv->cv_font->ft_h);
2155 gr_set_fontcolor(gr_getcolor(20,0,0),-1 );
2156 sprintf(str,"%03d",ammo_count);
2161 void draw_secondary_ammo_info(int ammo_count)
2163 if (Cockpit_mode.intval == CM_STATUS_BAR)
2164 draw_ammo_info(SB_SECONDARY_AMMO_X,SB_SECONDARY_AMMO_Y,ammo_count,0);
2166 draw_ammo_info(SECONDARY_AMMO_X,SECONDARY_AMMO_Y,ammo_count,0);
2169 //returns true if drew picture
2170 int draw_weapon_box(int weapon_type,int weapon_num)
2173 int laser_level_changed;
2175 gr_set_current_canvas(&VR_render_buffer[0]);
2177 gr_set_curfont( GAME_FONT );
2179 laser_level_changed = (weapon_type==0 && weapon_num==LASER_INDEX && (Players[Player_num].laser_level != old_laser_level[VR_current_page]));
2181 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))
2183 weapon_box_states[weapon_type] = WS_FADING_OUT;
2184 weapon_box_fade_values[weapon_type]=i2f(GR_FADE_LEVELS-1);
2187 if (weapon_box_states[weapon_type] == WS_FADING_OUT) {
2188 draw_weapon_info(weapon_type,old_weapon[weapon_type][VR_current_page],old_laser_level[VR_current_page]);
2189 old_ammo_count[weapon_type][VR_current_page]=-1;
2190 Old_Omega_charge[VR_current_page]=-1;
2192 weapon_box_fade_values[weapon_type] -= FrameTime * FADE_SCALE;
2193 if (weapon_box_fade_values[weapon_type] <= 0) {
2194 weapon_box_states[weapon_type] = WS_FADING_IN;
2195 old_weapon[weapon_type][VR_current_page] = weapon_num;
2196 old_weapon[weapon_type][!VR_current_page] = weapon_num;
2197 old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2198 old_laser_level[!VR_current_page] = Players[Player_num].laser_level;
2199 weapon_box_fade_values[weapon_type] = 0;
2202 else if (weapon_box_states[weapon_type] == WS_FADING_IN) {
2203 if (weapon_num != old_weapon[weapon_type][VR_current_page]) {
2204 weapon_box_states[weapon_type] = WS_FADING_OUT;
2207 draw_weapon_info(weapon_type,weapon_num,Players[Player_num].laser_level);
2208 old_ammo_count[weapon_type][VR_current_page]=-1;
2209 Old_Omega_charge[VR_current_page]=-1;
2211 weapon_box_fade_values[weapon_type] += FrameTime * FADE_SCALE;
2212 if (weapon_box_fade_values[weapon_type] >= i2f(GR_FADE_LEVELS-1)) {
2213 weapon_box_states[weapon_type] = WS_SET;
2214 old_weapon[weapon_type][!VR_current_page] = -1; //force redraw (at full fade-in) of other page
2218 // if (old_weapon[weapon_type][VR_current_page] == -1)
2220 //@@if (laser_level_changed)
2221 //@@ old_weapon[weapon_type][VR_current_page] = LASER_INDEX;
2224 draw_weapon_info(weapon_type, weapon_num, Players[Player_num].laser_level);
2225 old_weapon[weapon_type][VR_current_page] = weapon_num;
2226 old_ammo_count[weapon_type][VR_current_page] = -1;
2227 Old_Omega_charge[VR_current_page] = -1;
2228 old_laser_level[VR_current_page] = Players[Player_num].laser_level;
2233 if (weapon_box_states[weapon_type] != WS_SET) { //fade gauge
2234 int fade_value = f2i(weapon_box_fade_values[weapon_type]);
2235 int boxofs = (Cockpit_mode.intval == CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2237 Gr_scanline_darkening_level = fade_value;
2238 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);
2240 Gr_scanline_darkening_level = GR_FADE_LEVELS;
2243 gr_set_current_canvas(get_current_game_screen());
2249 void draw_static(int win)
2251 vclip *vc = &Vclip[VCLIP_MONITOR_STATIC];
2254 int boxofs = (Cockpit_mode.intval == CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2257 static_time[win] += FrameTime;
2258 if (static_time[win] >= vc->play_time) {
2259 weapon_box_user[win] = WBU_WEAPON;
2263 framenum = static_time[win] * vc->num_frames / vc->play_time;
2265 PIGGY_PAGE_IN(vc->frames[framenum]);
2267 bmp = &GameBitmaps[vc->frames[framenum].index];
2269 gr_set_current_canvas(&VR_render_buffer[0]);
2271 for (x=gauge_boxes[boxofs+win].left;x<gauge_boxes[boxofs+win].right;x+=bmp->bm_w)
2272 for (y=gauge_boxes[boxofs+win].top;y<gauge_boxes[boxofs+win].bot;y+=bmp->bm_h)
2275 gr_set_current_canvas(get_current_game_screen());
2277 copy_gauge_box(&gauge_boxes[boxofs+win],&VR_render_buffer[0].cv_bitmap);
2280 void draw_weapon_boxes()
2282 int boxofs = (Cockpit_mode.intval == CM_STATUS_BAR)?SB_PRIMARY_BOX:COCKPIT_PRIMARY_BOX;
2285 if (weapon_box_user[0] == WBU_WEAPON) {
2286 drew = draw_weapon_box(0,Primary_weapon);
2288 copy_gauge_box(&gauge_boxes[boxofs+0],&VR_render_buffer[0].cv_bitmap);
2290 if (weapon_box_states[0] == WS_SET) {
2291 if ((Primary_weapon == VULCAN_INDEX) || (Primary_weapon == GAUSS_INDEX))
2293 if (Newdemo_state == ND_STATE_RECORDING &&
2294 Players[Player_num].primary_ammo[VULCAN_INDEX] != old_ammo_count[0][VR_current_page])
2295 newdemo_record_primary_ammo(old_ammo_count[0][VR_current_page], Players[Player_num].primary_ammo[VULCAN_INDEX]);
2296 draw_primary_ammo_info(f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) Players[Player_num].primary_ammo[VULCAN_INDEX]));
2297 old_ammo_count[0][VR_current_page] = Players[Player_num].primary_ammo[VULCAN_INDEX];
2300 if (Primary_weapon == OMEGA_INDEX)
2302 if (Newdemo_state == ND_STATE_RECORDING &&
2303 Omega_charge != Old_Omega_charge[VR_current_page])
2304 newdemo_record_primary_ammo(Old_Omega_charge[VR_current_page], Omega_charge);
2305 draw_primary_ammo_info(Omega_charge * 100/MAX_OMEGA_CHARGE);
2306 Old_Omega_charge[VR_current_page] = Omega_charge;
2310 else if (weapon_box_user[0] == WBU_STATIC)
2313 if (weapon_box_user[1] == WBU_WEAPON) {
2314 drew = draw_weapon_box(1,Secondary_weapon);
2316 copy_gauge_box(&gauge_boxes[boxofs+1],&VR_render_buffer[0].cv_bitmap);
2318 if (weapon_box_states[1] == WS_SET)
2320 old_bombcount[VR_current_page] = 0x7fff; //force redraw
2321 if (Newdemo_state == ND_STATE_RECORDING &&
2322 Players[Player_num].secondary_ammo[Secondary_weapon] != old_ammo_count[1][VR_current_page])
2323 newdemo_record_secondary_ammo(old_ammo_count[1][VR_current_page], Players[Player_num].secondary_ammo[Secondary_weapon]);
2324 draw_secondary_ammo_info(Players[Player_num].secondary_ammo[Secondary_weapon]);
2325 old_ammo_count[1][VR_current_page] = Players[Player_num].secondary_ammo[Secondary_weapon];
2327 if (Cockpit_mode.intval == CM_STATUS_BAR)
2328 show_bomb_count(SB_BOMB_COUNT_X, SB_BOMB_COUNT_Y, gr_find_closest_color(0, 0, 0), 0);
2330 show_bomb_count(BOMB_COUNT_X, BOMB_COUNT_Y, gr_find_closest_color(0, 0, 0), 0);
2333 else if (weapon_box_user[1] == WBU_STATIC)
2338 void sb_draw_energy_bar(int energy)
2340 int erase_height, w, h, aw;
2341 char energy_str[20];
2343 gr_set_current_canvas( Canv_SBEnergyGauge );
2345 PAGE_IN_GAUGE( SB_GAUGE_ENERGY );
2346 gr_ubitmapm(0, 0, &GameBitmaps[GET_GAUGE_INDEX(SB_GAUGE_ENERGY)]);
2348 erase_height = (100 - energy) * SB_ENERGY_GAUGE_H / 100;
2350 if (erase_height > 0) {
2351 gr_setcolor( BM_XRGB(0,0,0) );
2352 gr_rect(0, 0, SB_ENERGY_GAUGE_W - 1, erase_height - 1);
2356 sprintf(energy_str, "%d", energy);
2357 gr_get_string_size(energy_str, &w, &h, &aw );
2358 gr_set_fontcolor(gr_getcolor(25,18,6),-1 );
2359 gr_printf(((SB_ENERGY_GAUGE_W - w)/2), SB_ENERGY_GAUGE_H - GAME_FONT->ft_h - (GAME_FONT->ft_h / 4), "%d", energy);
2361 gr_set_current_canvas(get_current_game_screen());
2364 void sb_draw_afterburner()
2366 int erase_height, w, h, aw;
2367 char ab_str[3] = "AB";
2369 gr_set_current_canvas( Canv_SBAfterburnerGauge );
2370 PAGE_IN_GAUGE( SB_GAUGE_AFTERBURNER );
2371 gr_ubitmapm(0, 0, &GameBitmaps[GET_GAUGE_INDEX(SB_GAUGE_AFTERBURNER)]);
2373 erase_height = fixmul((f1_0 - Afterburner_charge),SB_AFTERBURNER_GAUGE_H);
2375 if (erase_height > 0) {
2376 gr_setcolor( BM_XRGB(0,0,0) );
2377 gr_rect(0, 0, SB_AFTERBURNER_GAUGE_W - 1, erase_height - 1);
2381 if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
2382 gr_set_fontcolor(gr_getcolor(45,0,0),-1 );
2384 gr_set_fontcolor(gr_getcolor(12,12,12),-1 );
2386 gr_get_string_size(ab_str, &w, &h, &aw );
2387 gr_printf(((SB_AFTERBURNER_GAUGE_W - w)/2), SB_AFTERBURNER_GAUGE_H - GAME_FONT->ft_h - (GAME_FONT->ft_h / 4), "AB");
2388 gr_set_current_canvas(get_current_game_screen());
2391 void sb_draw_shield_num(int shield)
2395 gr_set_curfont( GAME_FONT );
2396 gr_set_fontcolor(gr_getcolor(14,14,23),-1 );
2399 // PIGGY_PAGE_IN(cockpit_bitmap[Cockpit_mode.intval + (SM_HIRES ? (Num_cockpits/2) : 0)]);
2401 // gr_setcolor(gr_gpixel(&grd_curcanv->cv_bitmap, SB_SHIELD_NUM_X - 1, SB_SHIELD_NUM_Y - 1));
2403 // gr_rect(SB_SHIELD_NUM_X, SB_SHIELD_NUM_Y, SB_SHIELD_NUM_X + (SM_HIRES ? 27 : 13), SB_SHIELD_NUM_Y + GAME_FONT->ft_h);
2404 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);
2407 void sb_draw_shield_bar(int shield)
2409 int bm_num = shield>=100?9:(shield / 10);
2411 gr_set_current_canvas(get_current_game_screen());
2412 PAGE_IN_GAUGE( GAUGE_SHIELDS+9-bm_num );
2413 gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_SHIELDS+9-bm_num) ] );
2419 int flags = Players[Player_num].flags;
2421 gr_set_current_canvas(get_current_game_screen());
2422 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF) ];
2423 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_BLUE_KEY)?SB_GAUGE_BLUE_KEY:SB_GAUGE_BLUE_KEY_OFF );
2424 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_BLUE_KEY_Y, bm );
2425 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF) ];
2426 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_GOLD_KEY)?SB_GAUGE_GOLD_KEY:SB_GAUGE_GOLD_KEY_OFF );
2427 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_GOLD_KEY_Y, bm );
2428 bm = &GameBitmaps[ GET_GAUGE_INDEX((flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF) ];
2429 PAGE_IN_GAUGE( (flags&PLAYER_FLAGS_RED_KEY)?SB_GAUGE_RED_KEY:SB_GAUGE_RED_KEY_OFF );
2430 gr_ubitmapm( SB_GAUGE_KEYS_X, SB_GAUGE_RED_KEY_Y, bm );
2433 // Draws invulnerable ship, or maybe the flashing ship, depending on invulnerability time left.
2434 void draw_invulnerable_ship()
2438 gr_set_current_canvas(get_current_game_screen());
2440 if (((Players[Player_num].invulnerable_time + INVULNERABLE_TIME_MAX - GameTime) > F1_0*4) || (GameTime & 0x8000)) {
2442 if (Cockpit_mode.intval == CM_STATUS_BAR) {
2443 PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
2444 gr_ubitmapm( SB_SHIELD_GAUGE_X, SB_SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame) ] );
2446 PAGE_IN_GAUGE( GAUGE_INVULNERABLE+invulnerable_frame );
2447 gr_ubitmapm( SHIELD_GAUGE_X, SHIELD_GAUGE_Y, &GameBitmaps[GET_GAUGE_INDEX(GAUGE_INVULNERABLE+invulnerable_frame)] );
2452 while (time > INV_FRAME_TIME) {
2453 time -= INV_FRAME_TIME;
2454 if (++invulnerable_frame == N_INVULNERABLE_FRAMES)
2455 invulnerable_frame=0;
2457 } else if (Cockpit_mode.intval == CM_STATUS_BAR)
2458 sb_draw_shield_bar(f2ir(Players[Player_num].shields));
2460 draw_shield_bar(f2ir(Players[Player_num].shields));
2463 extern int Missile_gun;
2464 extern int allowed_to_fire_laser(void);
2465 extern int allowed_to_fire_missile(void);
2467 rgb player_rgb[] = {
2478 extern ubyte Newdemo_flying_guided;
2479 extern int max_window_w;
2485 //offsets for reticle parts: high-big high-sml low-big low-sml
2486 xy cross_offsets[4] = { {-8,-5}, {-4,-2}, {-4,-2}, {-2,-1} };
2487 xy primary_offsets[4] = { {-30,14}, {-16,6}, {-15,6}, {-8, 2} };
2488 xy secondary_offsets[4] = { {-24,2}, {-12,0}, {-12,1}, {-6,-2} };
2491 void show_reticle(int force_big_one)
2494 int laser_ready,missile_ready,laser_ammo,missile_ammo;
2495 int cross_bm_num,primary_bm_num,secondary_bm_num;
2496 int use_hires_reticle,small_reticle,ofs,gauge_index;
2498 if (Newdemo_state==ND_STATE_PLAYBACK && Newdemo_flying_guided)
2500 draw_guided_crosshair();
2504 x = grd_curcanv->cv_w/2;
2505 y = grd_curcanv->cv_h/2;
2507 laser_ready = allowed_to_fire_laser();
2508 missile_ready = allowed_to_fire_missile();
2510 laser_ammo = player_has_weapon(Primary_weapon,0);
2511 missile_ammo = player_has_weapon(Secondary_weapon,1);
2513 primary_bm_num = (laser_ready && laser_ammo==HAS_ALL);
2514 secondary_bm_num = (missile_ready && missile_ammo==HAS_ALL);
2516 if (primary_bm_num && Primary_weapon==LASER_INDEX && (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS))
2519 if (Secondary_weapon_to_gun_num[Secondary_weapon]==7)
2520 secondary_bm_num += 3; //now value is 0,1 or 3,4
2521 else if (secondary_bm_num && !(Missile_gun&1))
2524 cross_bm_num = ((primary_bm_num > 0) || (secondary_bm_num > 0));
2526 Assert(primary_bm_num <= 2);
2527 Assert(secondary_bm_num <= 4);
2528 Assert(cross_bm_num <= 1);
2530 if (gl_reticle==2 || (gl_reticle && grd_curcanv->cv_bitmap.bm_w > 320))
2532 ogl_draw_reticle(cross_bm_num,primary_bm_num,secondary_bm_num);
2539 use_hires_reticle = (FontHires != 0);
2541 small_reticle = !(grd_curcanv->cv_bitmap.bm_w*3 > max_window_w*2 || force_big_one);
2542 ofs = (use_hires_reticle?0:2) + small_reticle;
2544 gauge_index = (small_reticle?SML_RETICLE_CROSS:RETICLE_CROSS) + cross_bm_num;
2545 PAGE_IN_GAUGE( gauge_index );
2546 gr_ubitmapm(x+cross_offsets[ofs].x,y+cross_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
2548 gauge_index = (small_reticle?SML_RETICLE_PRIMARY:RETICLE_PRIMARY) + primary_bm_num;
2549 PAGE_IN_GAUGE( gauge_index );
2550 gr_ubitmapm(x+primary_offsets[ofs].x,y+primary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
2552 gauge_index = (small_reticle?SML_RETICLE_SECONDARY:RETICLE_SECONDARY) + secondary_bm_num;
2553 PAGE_IN_GAUGE( gauge_index );
2554 gr_ubitmapm(x+secondary_offsets[ofs].x,y+secondary_offsets[ofs].y,&GameBitmaps[GET_GAUGE_INDEX(gauge_index)] );
2562 void hud_show_kill_list()
2564 int n_players,player_list[MAX_NUM_NET_PLAYERS];
2565 int n_left,i,x0,x1,y,save_y,fth;
2567 // ugly hack since placement of netgame players and kills is based off of
2568 // menuhires (which is always 1 for mac). This throws off placement of
2569 // players in pixel double mode.
2571 if (Show_kill_list_timer > 0)
2573 Show_kill_list_timer -= FrameTime;
2574 if (Show_kill_list_timer < 0)
2578 gr_set_curfont( GAME_FONT );
2580 n_players = multi_get_kill_list(player_list);
2582 if (Show_kill_list == 3)
2588 n_left = (n_players+1)/2;
2590 //If font size changes, this code might not work right anymore
2591 //Assert(GAME_FONT->ft_h==5 && GAME_FONT->ft_w==7);
2593 fth = GAME_FONT->ft_h;
2595 x0 = LHX(1); x1 = LHX(43);
2597 if (Game_mode & GM_MULTI_COOP)
2600 save_y = y = grd_curcanv->cv_h - n_left*(fth+1);
2602 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
2603 save_y = y -= LHX(6);
2604 if (Game_mode & GM_MULTI_COOP)
2610 for (i=0;i<n_players;i++) {
2616 if (Cockpit_mode.intval == CM_FULL_COCKPIT)
2617 x0 = grd_curcanv->cv_w - LHX(53);
2619 x0 = grd_curcanv->cv_w - LHX(60);
2620 if (Game_mode & GM_MULTI_COOP)
2621 x1 = grd_curcanv->cv_w - LHX(27);
2623 x1 = grd_curcanv->cv_w - LHX(15); // Right edge of name, change this for width problems
2627 if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
2633 else if (Netgame.KillGoal || Netgame.PlayTimeAllowed)
2641 if (Show_kill_list == 3)
2644 player_num = player_list[i];
2646 if (Show_kill_list == 1 || Show_kill_list==2)
2650 if (Players[player_num].connected != 1)
2651 gr_set_fontcolor(gr_getcolor(12, 12, 12), -1);
2652 else if (Game_mode & GM_TEAM) {
2653 color = get_team(player_num);
2654 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
2658 gr_set_fontcolor(gr_getcolor(player_rgb[color].r,player_rgb[color].g,player_rgb[color].b),-1 );
2664 gr_set_fontcolor(gr_getcolor(player_rgb[player_num].r,player_rgb[player_num].g,player_rgb[player_num].b),-1 );
2667 if (Show_kill_list == 3)
2668 strcpy(name, Netgame.team_name[i]);
2670 strcpy(name,Players[player_num].callsign); // Note link to above if!!
2671 gr_get_string_size(name,&sw,&sh,&aw);
2672 while (sw > (x1-x0-LHX(2))) {
2673 name[strlen(name)-1]=0;
2674 gr_get_string_size(name,&sw,&sh,&aw);
2676 gr_printf(x0,y,"%s",name);
2678 if (Show_kill_list==2)
2680 if (Players[player_num].net_killed_total+Players[player_num].net_kills_total==0)
2681 gr_printf (x1,y,"NA");
2683 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));
2685 else if (Show_kill_list == 3)
2686 gr_printf(x1,y,"%3d",team_kills[i]);
2687 else if (Game_mode & GM_MULTI_COOP)
2688 gr_printf(x1,y,"%-6d",Players[player_num].score);
2689 else if (Netgame.PlayTimeAllowed || Netgame.KillGoal)
2690 gr_printf(x1,y,"%3d(%d)",Players[player_num].net_kills_total,Players[player_num].KillGoalCount);
2692 gr_printf(x1,y,"%3d",Players[player_num].net_kills_total);
2701 extern int Saving_movie_frames;
2703 #define Saving_movie_frames 0
2706 //returns true if viewer can see object
2707 int see_object(int objnum)
2713 //see if we can see this player
2715 fq.p0 = &Viewer->pos;
2716 fq.p1 = &Objects[objnum].pos;
2718 fq.thisobjnum = OBJECT_NUMBER(Viewer);
2719 fq.flags = FQ_TRANSWALL | FQ_CHECK_OBJS;
2720 fq.startseg = Viewer->segnum;
2721 fq.ignore_obj_list = NULL;
2723 hit_type = find_vector_intersection(&fq, &hit_data);
2725 return (hit_type == HIT_OBJECT && hit_data.hit_object == objnum);
2729 //show names of teammates & players carrying flags
2730 void show_HUD_names()
2732 int show_team_names,show_all_names,show_flags,player_team;
2735 show_all_names = ((Newdemo_state == ND_STATE_PLAYBACK) || (Netgame.ShowAllNames && Show_reticle_name));
2736 show_team_names = (((Game_mode & GM_MULTI_COOP) || (Game_mode & GM_TEAM)) && Show_reticle_name);
2737 show_flags = (Game_mode & GM_CAPTURE) | (Game_mode & GM_HOARD);
2739 if (! (show_all_names || show_team_names || show_flags))
2742 player_team = get_team(Player_num);
2744 for (p=0;p<N_players;p++) { //check all players
2746 int show_name,has_flag;
2748 show_name = ((show_all_names && !(Players[p].flags & PLAYER_FLAGS_CLOAKED)) || (show_team_names && get_team(p)==player_team));
2749 has_flag = (Players[p].connected && Players[p].flags & PLAYER_FLAGS_FLAG);
2751 if (Newdemo_state == ND_STATE_PLAYBACK) {
2752 //if this is a demo, the objnum in the player struct is wrong,
2753 //so we search the object list for the objnum
2755 for (objnum=0;objnum<=Highest_object_index;objnum++)
2756 if (Objects[objnum].type==OBJ_PLAYER && Objects[objnum].id == p)
2758 if (objnum > Highest_object_index) //not in list, thus not visible
2759 show_name = has_flag = 0; //..so don't show name
2762 objnum = Players[p].objnum;
2764 if ((show_name || has_flag) && see_object(objnum)) {
2765 g3s_point player_point;
2767 g3_rotate_point(&player_point,&Objects[objnum].pos);
2769 if (player_point.p3_codes == 0) { //on screen
2771 g3_project_point(&player_point);
2773 if (! (player_point.p3_flags & PF_OVERFLOW)) {
2776 x = player_point.p3_sx;
2777 y = player_point.p3_sy;
2779 if (show_name) { // Draw callsign on HUD
2780 char s[CALLSIGN_LEN+1];
2785 color_num = (Game_mode & GM_TEAM)?get_team(p):p;
2787 sprintf(s, "%.7s", Players[p].callsign);
2788 gr_get_string_size(s, &w, &h, &aw);
2789 gr_set_fontcolor(gr_getcolor(player_rgb[color_num].r,player_rgb[color_num].g,player_rgb[color_num].b),-1 );
2792 gr_string (x1, y1, s);
2795 if (has_flag) { // Draw box on HUD
2798 dy = -fixmuldiv(fixmul(Objects[objnum].size,Matrix_scale.y),i2f(grd_curcanv->cv_h)/2,player_point.p3_z);
2799 dx = fixmul(dy,grd_curscreen->sc_aspect);
2804 if (Game_mode & GM_CAPTURE)
2805 gr_setcolor((get_team(p) == TEAM_BLUE)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
2806 else if (Game_mode & GM_HOARD)
2808 if (Game_mode & GM_TEAM)
2809 gr_setcolor((get_team(p) == TEAM_RED)?BM_XRGB(31,0,0):BM_XRGB(0,0,31));
2811 gr_setcolor(BM_XRGB(0,31,0));
2814 gr_line(x+dx-w,y-dy,x+dx,y-dy);
2815 gr_line(x+dx,y-dy,x+dx,y-dy+h);
2817 gr_line(x-dx,y-dy,x-dx+w,y-dy);
2818 gr_line(x-dx,y-dy,x-dx,y-dy+h);
2820 gr_line(x+dx-w,y+dy,x+dx,y+dy);
2821 gr_line(x+dx,y+dy,x+dx,y+dy-h);
2823 gr_line(x-dx,y+dy,x-dx+w,y+dy);
2824 gr_line(x-dx,y+dy,x-dx,y+dy-h);
2834 extern int last_drawn_cockpit[2];
2836 //draw all the things on the HUD
2841 if (Cockpit_mode.intval == CM_STATUS_BAR) {
2842 //ogl needs to redraw every frame, at least currently.
2844 last_drawn_cockpit[0]=-1;
2845 last_drawn_cockpit[1]=-1;
2848 // vr_reset_display();
2853 Line_spacing = GAME_FONT->ft_h + GAME_FONT->ft_h/4;
2855 // Show score so long as not in rearview
2856 if ( !Rear_view && Cockpit_mode.intval != CM_REAR_VIEW && Cockpit_mode.intval != CM_STATUS_BAR && !Saving_movie_frames) {
2859 hud_show_score_added();
2862 if ( !Rear_view && Cockpit_mode.intval != CM_REAR_VIEW && !Saving_movie_frames)
2863 hud_show_timer_count();
2865 // Show other stuff if not in rearview or letterbox.
2866 if (!Rear_view && Cockpit_mode.intval != CM_REAR_VIEW) { // && Cockpit_mode.intval!=CM_LETTERBOX) {
2867 if (Cockpit_mode.intval == CM_STATUS_BAR || Cockpit_mode.intval == CM_FULL_SCREEN)
2868 hud_show_homing_warning();
2870 if (Cockpit_mode.intval == CM_FULL_SCREEN) {
2873 hud_show_afterburner();
2875 if (!Saving_movie_frames)
2877 hud_show_cloak_invuln();
2879 if ( ( Newdemo_state == ND_STATE_RECORDING ) && ( Players[Player_num].flags != old_flags[VR_current_page] )) {
2880 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
2881 old_flags[VR_current_page] = Players[Player_num].flags;
2887 if (!(Game_mode&GM_MULTI && Show_kill_list) && !Saving_movie_frames)
2891 if (Reticle_on.intval && Cockpit_mode.intval != CM_LETTERBOX && (!Use_player_head_angles))
2897 if (Cockpit_mode.intval != CM_LETTERBOX && Cockpit_mode.intval != CM_REAR_VIEW)
2900 if (Cockpit_mode.intval != CM_LETTERBOX && Cockpit_mode.intval != CM_REAR_VIEW)
2904 if (!Saving_movie_frames)
2905 HUD_render_message_frame();
2907 if (Cockpit_mode.intval != CM_STATUS_BAR && !Saving_movie_frames)
2911 if (Game_mode&GM_MULTI && Show_kill_list)
2912 hud_show_kill_list();
2916 if (Rear_view && Cockpit_mode.intval != CM_REAR_VIEW) {
2917 HUD_render_message_frame();
2918 gr_set_curfont( GAME_FONT );
2919 gr_set_fontcolor(gr_getcolor(0,31,0),-1 );
2920 if (Newdemo_state == ND_STATE_PLAYBACK)
2921 gr_printf(0x8000,grd_curcanv->cv_h-14,TXT_REAR_VIEW);
2923 gr_printf(0x8000,grd_curcanv->cv_h-10,TXT_REAR_VIEW);
2927 extern short *BackBuffer;
2929 //print out some player statistics
2930 void render_gauges()
2932 static uint32_t old_display_mode = 0xfffffffe;
2933 int energy = f2ir(Players[Player_num].energy);
2934 int shields = f2ir(Players[Player_num].shields);
2935 int cloak = ((Players[Player_num].flags&PLAYER_FLAGS_CLOAKED) != 0);
2937 Assert(Cockpit_mode.intval == CM_FULL_COCKPIT || Cockpit_mode.intval == CM_STATUS_BAR);
2939 // check to see if our display mode has changed since last render time --
2940 // if so, then we need to make new gauge canvases.
2941 // Also make the first gauge canvases here, in the game,
2942 // because they are [now] sub-canvases.
2945 if (old_display_mode != Current_display_mode)
2947 close_gauge_canvases();
2948 init_gauge_canvases();
2949 old_display_mode = Current_display_mode;
2952 if (shields < 0 ) shields = 0;
2954 gr_set_current_canvas(get_current_game_screen());
2955 gr_set_curfont( GAME_FONT );
2957 if (Newdemo_state == ND_STATE_RECORDING)
2958 if (Players[Player_num].homing_object_dist >= 0)
2959 newdemo_record_homing_distance(Players[Player_num].homing_object_dist);
2961 if (Cockpit_mode.intval == CM_FULL_COCKPIT)
2962 draw_player_ship(cloak, old_cloak[VR_current_page], SHIP_GAUGE_X, SHIP_GAUGE_Y);
2964 draw_player_ship(cloak, old_cloak[VR_current_page], SB_SHIP_GAUGE_X, SB_SHIP_GAUGE_Y);
2966 old_cloak[VR_current_page] = cloak;
2968 if (Cockpit_mode.intval == CM_FULL_COCKPIT) {
2969 if (Newdemo_state == ND_STATE_RECORDING && (energy != old_energy[VR_current_page]))
2971 newdemo_record_player_energy(old_energy[VR_current_page], energy);
2972 old_energy[VR_current_page] = energy;
2974 draw_energy_bar(energy);
2975 draw_numerical_display(shields, energy);
2977 if (Newdemo_state == ND_STATE_RECORDING && (Afterburner_charge != old_afterburner[VR_current_page]))
2979 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
2980 old_afterburner[VR_current_page] = Afterburner_charge;
2982 draw_afterburner_bar(Afterburner_charge);
2984 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
2985 draw_invulnerable_ship();
2986 old_shields[VR_current_page] = shields ^ 1;
2987 } else { // Draw the shield gauge
2988 if (Newdemo_state == ND_STATE_RECORDING && (shields != old_shields[VR_current_page]))
2990 newdemo_record_player_shields(old_shields[VR_current_page], shields);
2991 old_shields[VR_current_page] = shields;
2993 draw_shield_bar(shields);
2995 draw_numerical_display(shields, energy);
2997 if (Newdemo_state == ND_STATE_RECORDING && (Players[Player_num].flags != old_flags[VR_current_page]))
2999 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3000 old_flags[VR_current_page] = Players[Player_num].flags;
3004 show_homing_warning();
3006 } else if (Cockpit_mode.intval == CM_STATUS_BAR) {
3008 if (Newdemo_state == ND_STATE_RECORDING && (energy != old_energy[VR_current_page]))
3010 newdemo_record_player_energy(old_energy[VR_current_page], energy);
3011 old_energy[VR_current_page] = energy;
3013 sb_draw_energy_bar(energy);
3015 if (Newdemo_state == ND_STATE_RECORDING && (Afterburner_charge != old_afterburner[VR_current_page]))
3017 newdemo_record_player_afterburner(old_afterburner[VR_current_page], Afterburner_charge);
3018 old_afterburner[VR_current_page] = Afterburner_charge;
3020 sb_draw_afterburner();
3022 if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE)
3024 draw_invulnerable_ship();
3025 old_shields[VR_current_page] = shields ^ 1;
3028 { // Draw the shield gauge
3029 if (Newdemo_state == ND_STATE_RECORDING && (shields != old_shields[VR_current_page]))
3031 newdemo_record_player_shields(old_shields[VR_current_page], shields);
3032 old_shields[VR_current_page] = shields;
3034 sb_draw_shield_bar(shields);
3036 sb_draw_shield_num(shields);
3038 if (Newdemo_state == ND_STATE_RECORDING && (Players[Player_num].flags != old_flags[VR_current_page]))
3040 newdemo_record_player_flags(old_flags[VR_current_page], Players[Player_num].flags);
3041 old_flags[VR_current_page] = Players[Player_num].flags;
3046 // May want to record this in a demo...
3047 if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3050 old_lives[VR_current_page] = Players[Player_num].net_killed_total;
3055 old_lives[VR_current_page] = Players[Player_num].lives;
3058 if ((Game_mode&GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
3061 old_score[VR_current_page] = Players[Player_num].net_kills_total;
3066 old_score[VR_current_page] = Players[Player_num].score;
3069 sb_show_score_added();
3074 draw_weapon_boxes();
3078 // ---------------------------------------------------------------------------------------------------------
3079 // Call when picked up a laser powerup.
3080 // If laser is active, set old_weapon[0] to -1 to force redraw.
3081 void update_laser_weapon_info(void)
3083 if (old_weapon[0][VR_current_page] == 0)
3084 if (! (Players[Player_num].laser_level > MAX_LASER_LEVEL && old_laser_level[VR_current_page] <= MAX_LASER_LEVEL))
3085 old_weapon[0][VR_current_page] = -1;
3088 extern int Game_window_y;
3089 void fill_background(void);
3091 int SW_drawn[2], SW_x[2], SW_y[2], SW_w[2], SW_h[2];
3093 //draws a 3d view into one of the cockpit windows. win is 0 for left,
3094 //1 for right. viewer is object. NULL object means give up window
3095 //user is one of the WBU_ constants. If rear_view_flag is set, show a
3096 //rear view. If label is non-NULL, print the label at the top of the
3098 void do_cockpit_window_view(int win,object *viewer,int rear_view_flag,int user,const char *label)
3100 grs_canvas window_canv;
3101 static grs_canvas overlap_canv;
3102 object *viewer_save = Viewer;
3103 static int overlap_dirty[2]={0,0};
3105 static int window_x,window_y;
3107 int rear_view_save = Rear_view;
3112 if (viewer == NULL) { //this user is done
3114 Assert(user == WBU_WEAPON || user == WBU_STATIC);
3116 if (user == WBU_STATIC && weapon_box_user[win] != WBU_STATIC)
3117 static_time[win] = 0;
3119 if (weapon_box_user[win] == WBU_WEAPON || weapon_box_user[win] == WBU_STATIC)
3120 return; //already set
3122 weapon_box_user[win] = user;
3124 if (overlap_dirty[win]) {
3125 gr_set_current_canvas(&VR_screen_pages[VR_current_page]);
3127 overlap_dirty[win] = 0;
3133 update_rendered_data(win+1, viewer, rear_view_flag, user);
3135 weapon_box_user[win] = user; //say who's using window
3138 Rear_view = rear_view_flag;
3140 if (Cockpit_mode.intval == CM_FULL_SCREEN)
3143 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
3145 h = i2f(w) / grd_curscreen->sc_aspect;
3147 dx = (win==0)?-(w+(w/10)):(w/10);
3149 window_x = VR_render_buffer[0].cv_bitmap.bm_w/2+dx;
3150 window_y = VR_render_buffer[0].cv_bitmap.bm_h-h-(h/10);
3152 //copy these vars so stereo code can get at them
3153 SW_drawn[win]=1; SW_x[win] = window_x; SW_y[win] = window_y; SW_w[win] = w; SW_h[win] = h;
3155 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],window_x,window_y,w,h);
3158 if (Cockpit_mode.intval == CM_FULL_COCKPIT)
3159 boxnum = (COCKPIT_PRIMARY_BOX)+win;
3160 else if (Cockpit_mode.intval == CM_STATUS_BAR)
3161 boxnum = (SB_PRIMARY_BOX)+win;
3165 box = &gauge_boxes[boxnum];
3167 gr_init_sub_canvas(&window_canv,&VR_render_buffer[0],box->left,box->top,box->right-box->left+1,box->bot-box->top+1);
3170 gr_set_current_canvas(&window_canv);
3172 render_frame(0, win+1);
3174 // HACK! If guided missile, wake up robots as necessary.
3175 if (viewer->type == OBJ_WEAPON) {
3176 // -- Used to require to be GUIDED -- if (viewer->id == GUIDEDMISS_ID)
3177 wake_up_rendered_objects(viewer, win+1);
3181 gr_set_curfont( GAME_FONT );
3182 if (Color_0_31_0 == -1)
3183 Color_0_31_0 = gr_getcolor(0,31,0);
3184 gr_set_fontcolor(Color_0_31_0, -1);
3185 gr_printf(0x8000,2,label);
3188 if (user == WBU_GUIDED)
3189 draw_guided_crosshair();
3191 if (Cockpit_mode.intval == CM_FULL_SCREEN) {
3192 int small_window_bottom,big_window_bottom,extra_part_h;
3195 gr_setcolor(BM_XRGB(0,0,32));
3196 gr_ubox(0,0,grd_curcanv->cv_bitmap.bm_w-1,grd_curcanv->cv_bitmap.bm_h-1);
3199 //if the window only partially overlaps the big 3d window, copy
3200 //the extra part to the visible screen
3202 big_window_bottom = Game_window_y + Game_window_h.intval - 1;
3204 if (window_y > big_window_bottom) {
3206 //the small window is completely outside the big 3d window, so
3207 //copy it to the visible screen
3209 if (VR_screen_flags & VRF_USE_PAGING)
3210 gr_set_current_canvas(&VR_screen_pages[!VR_current_page]);
3212 gr_set_current_canvas(get_current_game_screen());
3214 gr_bitmap(window_x,window_y,&window_canv.cv_bitmap);
3216 overlap_dirty[win] = 1;
3220 small_window_bottom = window_y + window_canv.cv_bitmap.bm_h - 1;
3222 extra_part_h = small_window_bottom - big_window_bottom;
3224 if (extra_part_h > 0) {
3226 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);
3228 if (VR_screen_flags & VRF_USE_PAGING)
3229 gr_set_current_canvas(&VR_screen_pages[!VR_current_page]);
3231 gr_set_current_canvas(get_current_game_screen());
3233 gr_bitmap(window_x,big_window_bottom+1,&overlap_canv.cv_bitmap);
3235 overlap_dirty[win] = 1;
3241 gr_set_current_canvas(get_current_game_screen());
3242 copy_gauge_box(box,&VR_render_buffer[0].cv_bitmap);
3245 //force redraw when done
3246 old_weapon[win][VR_current_page] = old_ammo_count[win][VR_current_page] = -1;
3250 Viewer = viewer_save;
3252 Rear_view = rear_view_save;
3256 void calculate_sub_view_window_bounds(int inSubWindowNum, TQARect* outBoundsRect)
3259 gauge_box* currentGaugeBox = NULL;
3266 Assert(outBoundsRect);
3267 Assert((inSubWindowNum == 0) || (inSubWindowNum == 1));
3269 switch (Cockpit_mode.intval)
3271 case CM_FULL_SCREEN:
3272 // note: this calculation is taken from do_cockpit_window_view for the full
3275 w = (VR_render_buffer[0].cv_bitmap.bm_w) / 6;
3276 h = (i2f(w)) / (grd_curscreen->sc_aspect);
3278 dx = (inSubWindowNum==0)?-(w+(w/10)):(w/10);
3280 window_x = ((VR_render_buffer[0].cv_bitmap.bm_w) / 2) + dx;
3281 window_y = (VR_render_buffer[0].cv_bitmap.bm_h) - h - (h/10);
3283 outBoundsRect->top = window_x;
3284 outBoundsRect->left = window_y;
3285 outBoundsRect->bottom = window_x + w;
3286 outBoundsRect->right = window_y + h;
3289 case CM_FULL_COCKPIT:
3291 if (inSubWindowNum == 0)
3293 boxNumber = SB_PRIMARY_BOX;
3297 boxNumber = SB_SECONDARY_BOX;
3300 //boxNumber = (Current_display_mode * 4) + (Cockpit_mode.intval * 2) + inSubWindowNum;
3301 currentGaugeBox = &gauge_boxes[boxNumber];
3302 Assert(currentGaugeBox);
3304 outBoundsRect->top = currentGaugeBox->top;
3305 outBoundsRect->left = currentGaugeBox->left;
3306 outBoundsRect->bottom = currentGaugeBox->bot + 1;
3307 outBoundsRect->right = currentGaugeBox->right + 1;