]> icculus.org git repositories - taylor/freespace2.git/blob - src/hud/hudreticle.cpp
ryan's struct patch for gcc 2.95
[taylor/freespace2.git] / src / hud / hudreticle.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Hud/HUDreticle.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C module to draw and manage the recticle
16  *
17  * $Log$
18  * Revision 1.4  2002/06/17 06:33:09  relnev
19  * ryan's struct patch for gcc 2.95
20  *
21  * Revision 1.3  2002/06/09 04:41:21  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:45  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:09  root
28  * Initial import.
29  *
30  * 
31  * 14    10/27/99 10:04p Jefff
32  * changed german match speed indicator
33  * 
34  * 13    10/14/99 2:50p Jefff
35  * localization fixes
36  * 
37  * 12    8/28/99 4:54p Dave
38  * Fixed directives display for multiplayer clients for wings with
39  * multiple waves. Fixed hud threat indicator rendering color.
40  * 
41  * 11    8/09/99 3:14p Dave
42  * Make "launch" warning gauge draw in code.
43  * 
44  * 10    6/10/99 3:43p Dave
45  * Do a better job of syncing text colors to HUD gauges.
46  * 
47  * 9     6/08/99 10:48a Jasenw
48  * new coords for new HUD stuff
49  * 
50  * 8     6/03/99 2:31p Jasenw
51  * changed coords and removed weapon indicators.
52  * 
53  * 7     1/07/99 2:21p Jasen
54  * fixed toparc
55  * 
56  * 6     1/07/99 9:07a Jasen
57  * HUD coords
58  * 
59  * 5     12/28/98 3:17p Dave
60  * Support for multiple hud bitmap filenames for hi-res mode.
61  * 
62  * 4     12/21/98 5:02p Dave
63  * Modified all hud elements to be multi-resolution friendly.
64  * 
65  * 3     11/05/98 4:18p Dave
66  * First run nebula support. Beefed up localization a bit. Removed all
67  * conditional compiles for foreign versions. Modified mission file
68  * format.
69  * 
70  * 2     10/07/98 10:53a Dave
71  * Initial checkin.
72  * 
73  * 1     10/07/98 10:49a Dave
74  * 
75  * 69    8/28/98 3:28p Dave
76  * EMP effect done. AI effects may need some tweaking as required.
77  * 
78  * 68    8/25/98 1:48p Dave
79  * First rev of EMP effect. Player side stuff basically done. Next comes
80  * AI code.
81  * 
82  * 67    6/12/98 4:52p Hoffoss
83  * Added support for special characters in in forgeign languages.
84  * 
85  * 66    6/09/98 5:17p Lawrance
86  * French/German localization
87  * 
88  * 65    6/09/98 10:31a Hoffoss
89  * Created index numbers for all xstr() references.  Any new xstr() stuff
90  * added from here on out should be added to the end if the list.  The
91  * current list count can be found in FreeSpace.cpp (search for
92  * XSTR_SIZE).
93  * 
94  * 64    5/21/98 7:18p Lawrance
95  * Don't flash 'launch' for attempted lock
96  * 
97  * 63    5/13/98 1:53p Lawrance
98  * If no secondary banks on a ship, show correct reticle gauge
99  * 
100  * 62    5/06/98 8:05p Dave
101  * Made standalone reset properly under weird conditions. Tweak
102  * optionsmulti screen. Upped MAX_WEAPONS to 350. Put in new launch
103  * countdown anim. Minro ui fixes/tweaks.
104  * 
105  * 61    5/05/98 5:51p Lawrance
106  * Draw HUD center crosshair with bright alpha index
107  * 
108  * 60    5/04/98 6:12p Lawrance
109  * fix progblems with weapon gauges in situation when weapons are on ship
110  * 
111  * 59    5/01/98 4:22p Lawrance
112  * Use ship->weapons instead of sip when displaying weapon linking gauge
113  * 
114  * 58    4/13/98 11:19a Lawrance
115  * fix launch threat indicator
116  * 
117  * 57    4/08/98 10:34p Allender
118  * make threat indicators work in multiplayer.  Fix socket problem (once
119  * and for all???)
120  * 
121  * 56    3/26/98 5:26p John
122  * added new paging code. nonfunctional.
123  * 
124  * 55    2/23/98 6:49p Lawrance
125  * Use gr_aabitmap_ex() instead of clipping regions
126  * 
127  * 54    2/22/98 4:17p John
128  * More string externalization classification... 190 left to go!
129  * 
130  * 53    2/22/98 12:19p John
131  * Externalized some strings
132  * 
133  * 52    2/12/98 4:58p Lawrance
134  * Change to new flashing method.
135  * 
136  * 51    2/09/98 9:07p Lawrance
137  * Ensure 'evaded' popup has precedence over 'launch' popup
138  * 
139  * 50    1/25/98 10:31p Lawrance
140  * Don't draw most hud gauges when viewing from another ship.
141  * 
142  * 49    1/19/98 11:37p Lawrance
143  * Fixing Optimization build warnings
144  * 
145  * 48    1/14/98 10:21a Lawrance
146  * Draw reticle correctly when gauges are disabled.
147  * 
148  * 47    1/08/98 3:20p Johnson
149  * ALAN: Ensure entire throttle gauge flashes
150  * 
151  * 46    1/05/98 9:38p Lawrance
152  * Implement flashing HUD gauges.
153  * 
154  * 45    1/02/98 9:10p Lawrance
155  * Big changes to how colors get set on the HUD.
156  * 
157  * 44    12/16/97 9:13p Lawrance
158  * Integrate new gauges into HUD config.
159  * 
160  * 43    12/10/97 10:02p Lawrance
161  * Change weapon linking to use flags.
162  * 
163  * 42    12/08/97 1:49p Lawrance
164  * only play threat lock sound when a lock is being attempted
165  * 
166  * 41    11/17/97 6:37p Lawrance
167  * new gauges: extended target view, new lock triangles, support ship view
168  * 
169  * 40    11/11/97 10:25p Lawrance
170  * add sound hook for when missile threat flashes
171  * 
172  * 39    11/11/97 5:05p Lawrance
173  * get threat indicator working more reliably
174  * 
175  * 38    11/05/97 11:20p Lawrance
176  * add speed numbers to the reticle
177  * 
178  * 37    11/04/97 7:49p Lawrance
179  * integrating new HUD reticle and shield icons
180  * 
181  * 36    11/03/97 5:38p Dave
182  * Cleaned up more multiplayer sequencing. Added OBJ_OBSERVER module/type.
183  * Restructured HUD_config structs/flags.
184  * 
185  * $NoKeywords: $
186  *
187 */
188
189 #include "2d.h"
190
191 #include "hudreticle.h"
192 #include "hud.h"
193 #include "pixel.h"
194 #include "math.h"
195 #include "player.h"
196 #include "ship.h"
197 #include "freespace.h"
198 #include "ai.h"
199 #include "bmpman.h"
200 #include "key.h"
201 #include "timer.h"
202 #include "math.h"
203 #include "gamesnd.h"
204 #include "hudtargetbox.h"
205 #include "multi.h"
206 #include "emp.h"
207 #include "localize.h"
208
209 static int Reticle_inited = 0;
210
211 #define NUM_RETICLE_ANIS                        6               // keep up to date when modifying the number of reticle ani files
212
213 #define RETICLE_TOP_ARC                         0
214 #define RETICLE_LASER_WARN                      1
215 #define RETICLE_LOCK_WARN                       2
216 #define RETICLE_LEFT_ARC                        3
217 #define RETICLE_RIGHT_ARC                       4
218 //#define RETICLE_ONE_PRIMARY           5
219 //#define RETICLE_TWO_PRIMARY           6
220 //#define RETICLE_ONE_SECONDARY         7
221 //#define RETICLE_TWO_SECONDARY         8
222 //#define RETICLE_THREE_SECONDARY       9
223 // #define RETICLE_LAUNCH_LABEL         5
224 #define RETICLE_CENTER                          5
225
226 int Hud_throttle_frame_h[GR_NUM_RESOLUTIONS] = {
227         85,
228         136
229 };
230 int Hud_throttle_frame_w[GR_NUM_RESOLUTIONS] = {
231         49, 
232         78
233 };
234 int Hud_throttle_frame_bottom_y[GR_NUM_RESOLUTIONS] = {
235         325,
236         520
237 };
238 int Hud_throttle_h[GR_NUM_RESOLUTIONS] = {
239         50,
240         80
241 };
242 int Hud_throttle_bottom_y[GR_NUM_RESOLUTIONS] = {
243         307,
244         491
245 };
246 int Hud_throttle_aburn_h[GR_NUM_RESOLUTIONS] = {
247         17,
248         27
249 };
250 int Hud_throttle_aburn_button[GR_NUM_RESOLUTIONS] = {
251         259,
252         414
253 };
254
255 int Outer_circle_radius[GR_NUM_RESOLUTIONS] = {
256         104,
257         166
258 };
259
260 int Hud_reticle_center[GR_NUM_RESOLUTIONS][2] = {
261         { // GR_640
262                 320, 242
263         },
264         { // GR_1024
265                 512, 385
266         }
267 };
268
269 char Reticle_frame_names[GR_NUM_RESOLUTIONS][NUM_RETICLE_ANIS][MAX_FILENAME_LEN] = 
270 {
271 //XSTR:OFF
272         { // GR_640
273                 "toparc1",
274                 "toparc2",
275                 "toparc3",
276                 "leftarc",
277                 "rightarc1",
278 /*              "rightarc2",
279                 "rightarc3",
280                 "rightarc4",
281                 "rightarc5",
282                 "rightarc6",    
283                 "toparc4",      */
284                 "reticle1",     
285         }, 
286         { // GR_1024
287                 "2_toparc1",
288                 "2_toparc2",
289                 "2_toparc3",
290                 "2_leftarc",
291                 "2_rightarc1",
292 /*              "2_rightarc2",
293                 "2_rightarc3",
294                 "2_rightarc4",
295                 "2_rightarc5",
296                 "2_rightarc6",  
297                 "2_toparc4",    */
298                 "2_reticle1",   
299         }
300 //XSTR:ON
301 };
302
303 // reticle frame coords
304 int Reticle_frame_coords[GR_NUM_RESOLUTIONS][NUM_RETICLE_ANIS][2] = {
305         { // GR_640
306                 {241, 137},
307                 {400, 245},
308                 {394, 261},
309                 {216, 168},
310                 {359, 168},
311 //              {406, 253},
312 //              {406, 253},
313 //              {391, 276},
314 //              {391, 276},
315 //              {391, 276},
316 //              {297, 161},
317                 {308, 235}
318         }, 
319         { // GR_1024
320                 {386, 219},
321                 {640, 393},
322                 {631, 419},
323                 {346, 269},
324                 {574, 269},
325 //              {649, 401},
326 //              {649, 401},
327 //              {625, 438},
328 //              {625, 438},
329 //              {625, 438},
330 //              {475, 258},
331                 {493, 370}
332         }
333 };
334
335 // "launch" gauge coords
336 int Reticle_launch_coords[GR_NUM_RESOLUTIONS][2] = {
337         { // GR_640
338                 297,    161
339         },
340         { // GR_1024
341                 475,    258
342         }
343 };
344
345 hud_frames Reticle_gauges[NUM_RETICLE_ANIS];
346
347 #define THREAT_DUMBFIRE                         (1<<0)
348 #define THREAT_ATTEMPT_LOCK             (1<<1)
349 #define THREAT_LOCK                                     (1<<2)
350
351 #define THREAT_UPDATE_DUMBFIRE_TIME             1000            // time between checking for dumbfire threats
352 #define THREAT_UPDATE_LOCK_TIME                 500             // time between checking for lock threats
353
354 #define THREAT_DUMBFIRE_FLASH                           180
355 #define THREAT_LOCK_FLASH                                       180
356 static int Threat_dumbfire_timer;               // timestamp for when to show next flashing frame for dumbfire threat
357 static int Threat_lock_timer;                           // timestamp for when to show next flashing frame for lock threat
358
359 static int Threat_dumbfire_frame;                       // frame offset of current dumbfire flashing warning
360 static int Threat_lock_frame;                           // frame offset of current lock flashing warning
361
362 // coordinates
363 static int Max_speed_coords[GR_NUM_RESOLUTIONS][2] = 
364 {
365         { // GR_640
366                 236, 254
367         }, 
368         { // GR_1024
369                 377, 406
370         }
371 };
372 static int Zero_speed_coords[GR_NUM_RESOLUTIONS][2] = {
373         { // GR_640
374                 252, 303
375         },
376         { // GR_1024
377                 403, 485
378         }
379 };
380
381 // Called at the start of each level.. use Reticle_inited so we only load frames once
382 void hud_init_reticle()
383 {
384         int                     i;
385         hud_frames      *hfp;
386
387         Threat_dumbfire_timer = timestamp(0);
388         Threat_lock_timer = timestamp(0);
389         Threat_dumbfire_frame = 1;
390         Threat_lock_frame = 1;
391         Player->threat_flags = 0;
392         Player->update_dumbfire_time = timestamp(0);            
393         Player->update_lock_time = timestamp(0);
394
395         if ( Reticle_inited ) {
396                 return;
397         }
398
399         for ( i = 0; i < NUM_RETICLE_ANIS; i++ ) {
400                 hfp = &Reticle_gauges[i];
401                 hfp->first_frame = bm_load_animation(Reticle_frame_names[gr_screen.res][i], &hfp->num_frames);
402                 if ( hfp->first_frame < 0 ) {
403                         Warning(LOCATION,"Cannot load hud ani: %s\n", Reticle_frame_names[gr_screen.res][i]);
404                 }
405         }
406
407         Reticle_inited = 1;
408 }
409
410 // called once per frame to update the reticle gauges.  Makes calls to
411 // ship_dumbfire_threat() and ship_lock_threat() and updates Threat_flags.
412 void hud_update_reticle( player *pp )
413 {
414         int rval;
415         ship *shipp;
416
417         // multiplayer clients won't call this routine
418         if ( MULTIPLAYER_CLIENT || MULTI_OBSERVER(Net_players[MY_NET_PLAYER_NUM]))
419                 return;
420
421         shipp = &Ships[Objects[pp->objnum].instance];
422
423         if ( ship_dumbfire_threat(shipp) ) {
424                 pp->threat_flags |= THREAT_DUMBFIRE;
425                 pp->update_dumbfire_time = timestamp(THREAT_UPDATE_DUMBFIRE_TIME);
426         }
427
428         if ( timestamp_elapsed(pp->update_dumbfire_time) ) {
429                 pp->update_dumbfire_time = timestamp(THREAT_UPDATE_DUMBFIRE_TIME);
430                 pp->threat_flags &= ~THREAT_DUMBFIRE;
431         }
432
433         if ( timestamp_elapsed(pp->update_lock_time) ) {
434                 pp->threat_flags &= ~(THREAT_LOCK | THREAT_ATTEMPT_LOCK);
435                 pp->update_lock_time = timestamp(THREAT_UPDATE_LOCK_TIME);
436                 rval = ship_lock_threat(shipp);
437                 if ( rval == 1 ) {
438                         pp->threat_flags |= THREAT_ATTEMPT_LOCK;
439                 } else if ( rval == 2 ) {
440                         pp->threat_flags |= THREAT_LOCK;
441                 }
442         }
443 }
444
445 // draw left arc (the dark portion of the throttle gauge)
446 void hud_render_throttle_background(int y_end)
447 {
448         int x,y,w,h;
449
450         hud_set_gauge_color(HUD_THROTTLE_GAUGE);
451
452         x = Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][0];
453         y = Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][1];
454
455         bm_get_info( Reticle_gauges[RETICLE_LEFT_ARC].first_frame+1,&w,&h);     
456
457         if ( y_end > y ) {
458                 GR_AABITMAP_EX(Reticle_gauges[RETICLE_LEFT_ARC].first_frame+1, x, y, w, y_end-y+1, 0, 0);               
459         }
460 }
461
462 // draw left arc (the bright portion of the throttle gauge)
463 void hud_render_throttle_foreground(int y_end)
464 {
465         int x,y,w,h;
466
467         hud_set_gauge_color(HUD_THROTTLE_GAUGE);
468
469         x = Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][0];
470         y = Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][1];
471
472         bm_get_info( Reticle_gauges[RETICLE_LEFT_ARC].first_frame+1,&w,&h);
473
474         if ( y_end < Hud_throttle_frame_bottom_y[gr_screen.res] ) {             
475                 GR_AABITMAP_EX(Reticle_gauges[RETICLE_LEFT_ARC].first_frame+2, x, y_end, w, h-(y_end-y), 0, y_end-y);           
476         }
477 }
478
479 // Draw the throttle speed number
480 void hud_render_throttle_speed(float current_speed, int y_end)
481 {
482         char buf[32];
483         int sx, sy, x_pos, y_pos, w, h;
484
485         hud_set_gauge_color(HUD_THROTTLE_GAUGE);
486
487         // y_end is the y-coordinate of the current throttle setting, calc x-coordinate for edge of 
488         // circle (x^2 + y^2 = r^2)
489         y_pos = Hud_reticle_center[gr_screen.res][1] - y_end;
490         x_pos = (int)sqrt(double(Outer_circle_radius[gr_screen.res] * Outer_circle_radius[gr_screen.res] - y_pos * y_pos) );
491         x_pos = Hud_reticle_center[gr_screen.res][0] - x_pos;
492
493         // draw current speed at (x_pos, y_end);
494         sprintf(buf, "%d", fl2i(current_speed+0.5f));
495         hud_num_make_mono(buf);
496         gr_get_string_size(&w, &h, buf);
497         sx = x_pos - w - 2;
498         sy = fl2i(y_end - h/2.0f + 1.5);
499         gr_printf(sx, sy, buf);
500
501         if ( Players[Player_num].flags & PLAYER_FLAGS_MATCH_TARGET ) {
502                 int offset;
503                 if ( current_speed <= 9.5 ) {
504                         offset = 0;
505                 } else {
506                         offset = 3;
507                 }
508 #if defined(GERMAN_BUILD)
509                 // print an m, cuz the voice says its an m.  
510                 // its a normal m cuz the german font has no special m (its an a)
511                 gr_string(sx+offset, sy + h, "m");
512 #else
513                 gr_printf(sx+offset, sy + h, "%c", Lcl_special_chars + 3);
514 #endif
515         }
516 }
517
518 // draw the "desired speed" bar on the throttle
519 void hud_render_throttle_line(int y)
520 {
521         // hud_set_bright_color();
522         hud_set_gauge_color(HUD_THROTTLE_GAUGE, HUD_C_BRIGHT);
523
524         GR_AABITMAP_EX(Reticle_gauges[RETICLE_LEFT_ARC].first_frame+3, Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][0], y, Hud_throttle_frame_w[gr_screen.res], 1, 0, y-Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][1]);     
525 }
526
527 // Draw the throttle gauge along the left arc of the reticle
528 void hud_show_throttle()
529 {
530         float   desired_speed, max_speed, current_speed, percent_max, percent_aburn_max;
531         int     desired_y_pos, y_end;
532
533         ship_info       *sip;
534         sip = &Ship_info[Player_ship->ship_info_index];
535
536         current_speed = Player_obj->phys_info.fspeed;
537         if ( current_speed < 0.0f){
538                 current_speed = 0.0f;
539         }
540
541         max_speed = Ships[Player_obj->instance].current_max_speed;
542         if ( max_speed <= 0 ) {
543                 max_speed = sip->max_vel.xyz.z;
544         }
545
546         desired_speed = Player->ci.forward * max_speed;
547         if ( desired_speed < 0.0f ){            // so ships that go backwards don't force the indicators below where they can go
548                 desired_speed = 0.0f;
549         }
550
551         desired_y_pos = Hud_throttle_bottom_y[gr_screen.res] - fl2i(Hud_throttle_h[gr_screen.res]*desired_speed/max_speed+0.5f) - 1;
552
553         Assert(max_speed != 0);
554         percent_max = current_speed / max_speed;
555
556         percent_aburn_max = 0.0f;
557         if ( percent_max > 1 ) {
558                 percent_max = 1.0f;
559                 percent_aburn_max = (current_speed - max_speed) / (sip->afterburner_max_vel.xyz.z - max_speed);
560                 if ( percent_aburn_max > 1.0f ) {
561                         percent_aburn_max = 1.0f;
562                 }
563                 if ( percent_aburn_max < 0 ) {
564                         percent_aburn_max = 0.0f;
565                 }
566         }
567
568         y_end = Hud_throttle_bottom_y[gr_screen.res] - fl2i(Hud_throttle_h[gr_screen.res]*percent_max+0.5f);
569         if ( percent_aburn_max > 0 ) {
570                 y_end -= fl2i(percent_aburn_max * Hud_throttle_aburn_h[gr_screen.res] + 0.5f);
571         }
572
573         if ( Player_obj->phys_info.flags & PF_AFTERBURNER_ON ) {
574                 desired_y_pos = 240;
575         }
576
577         // draw left arc (the dark portion of the throttle gauge)
578         // hud_render_throttle_background(y_end);
579
580         // draw throttle speed number
581         hud_render_throttle_speed(current_speed, y_end);
582
583         // draw the "desired speed" bar on the throttle
584         hud_render_throttle_line(desired_y_pos);
585
586         // draw left arc (the bright portion of the throttle gauge)
587         hud_render_throttle_foreground(y_end);
588
589         gr_printf(Max_speed_coords[gr_screen.res][0], Max_speed_coords[gr_screen.res][1], "%d",fl2i(max_speed));
590         gr_printf(Zero_speed_coords[gr_screen.res][0], Zero_speed_coords[gr_screen.res][1], XSTR( "0", 292));
591 }
592
593 /*
594 // Draw the primary and secondary weapon indicators along the right arc of the reticle
595 void hud_show_reticle_weapons()
596 {
597         int                     gauge_index=0, frame_offset=0;
598         ship_weapon     *swp;
599
600         swp = &Player_ship->weapons;
601
602         switch( swp->num_primary_banks ) {
603                 case 0:
604                         gauge_index = -1;
605                         break;
606
607                 case 1:
608                         gauge_index = RETICLE_ONE_PRIMARY;
609                         if ( Player_ship->weapons.current_primary_bank == -1 ) {
610                                 frame_offset = 0;       
611                         } else {
612                                 frame_offset = 1;       
613                         }
614                         break;
615
616                 case 2:
617                         gauge_index = RETICLE_TWO_PRIMARY;
618                         if ( swp->current_primary_bank == -1 ) {
619                                 frame_offset = 0;       
620                         } else {
621                                 if ( Player_ship->flags & SF_PRIMARY_LINKED ) {
622                                         frame_offset = 3;
623                                 } else {
624                                         if ( swp->current_primary_bank == 0 ) {
625                                                 frame_offset = 1;
626                                         } else {
627                                                 frame_offset = 2;
628                                         }
629                                 }
630                         }
631                         break;
632
633                 default:
634                         Int3(); // shouldn't happen (get Alan if it does)
635                         return;
636                         break;
637         }
638         
639         if ( gauge_index != -1 ) {
640                 GR_AABITMAP(Reticle_gauges[gauge_index].first_frame+frame_offset, Reticle_frame_coords[gr_screen.res][gauge_index][0], Reticle_frame_coords[gr_screen.res][gauge_index][1]);            
641         }
642
643         int num_banks = swp->num_secondary_banks;
644         if ( num_banks <= 0 ) {
645                 num_banks = Ship_info[Player_ship->ship_info_index].num_secondary_banks;
646         }
647
648         switch( num_banks ) {
649                 case 0:
650                         Int3();
651                         gauge_index = -1;
652                         break;
653
654                 case 1:
655                         gauge_index = RETICLE_ONE_SECONDARY;
656                         break;
657
658                 case 2:
659                         gauge_index = RETICLE_TWO_SECONDARY;
660                         break;
661
662                 case 3:
663                         gauge_index = RETICLE_THREE_SECONDARY;
664                         break;
665
666                 default:
667                         Int3(); // shouldn't happen (get Alan if it does)
668                         return;
669                         break;
670         }
671         
672         if ( gauge_index != -1 ) {
673                 if ( swp->num_secondary_banks <= 0 ) {
674                         frame_offset = 0;
675                 } else {
676                         frame_offset = swp->current_secondary_bank+1;
677                 }
678
679                 GR_AABITMAP(Reticle_gauges[gauge_index].first_frame+frame_offset, Reticle_frame_coords[gr_screen.res][gauge_index][0], Reticle_frame_coords[gr_screen.res][gauge_index][1]);            
680         }
681 }
682 */
683
684 // Draw the lock threat gauge on the HUD.  Use Threat_flags to determine if a 
685 // threat exists, and draw flashing frames.
686 void hud_show_lock_threat()
687 {
688         int frame_offset;
689
690         if ( Player->threat_flags & (THREAT_LOCK | THREAT_ATTEMPT_LOCK) ) {
691                 if ( timestamp_elapsed(Threat_lock_timer) ) {
692                         if ( Player->threat_flags & THREAT_LOCK )  {
693                                 Threat_lock_timer = timestamp(fl2i(THREAT_LOCK_FLASH/2.0f));
694                         } else {
695                                 Threat_lock_timer = timestamp(THREAT_LOCK_FLASH);
696                         }
697                         Threat_lock_frame++;
698                         if ( Threat_lock_frame > 2 ) {
699                                 Threat_lock_frame = 1;
700                         }
701                         if ( (Threat_lock_frame == 2) && (Player->threat_flags & THREAT_ATTEMPT_LOCK ) ) {
702                                 snd_play( &Snds[SND_THREAT_FLASH]);
703                         }
704                 }
705                 frame_offset = Threat_lock_frame;
706         } else {
707                 frame_offset = 0;
708         }
709
710         hud_set_gauge_color(HUD_THREAT_GAUGE);
711
712         GR_AABITMAP(Reticle_gauges[RETICLE_LOCK_WARN].first_frame+frame_offset, Reticle_frame_coords[gr_screen.res][RETICLE_LOCK_WARN][0], Reticle_frame_coords[gr_screen.res][RETICLE_LOCK_WARN][1]);
713
714         // "launch" flash
715         if ( (frame_offset > 0) && (Player->threat_flags & THREAT_LOCK) ) {
716                 if ( hud_targetbox_flash_expired(TBOX_FLASH_CMEASURE) ) {
717                         // hack
718                         int bright;
719                         if(frame_offset % 2){
720                                 bright = 1;
721                         } else {
722                                 bright = 0;
723                         }
724                         // GR_AABITMAP(Reticle_gauges[RETICLE_LAUNCH_LABEL].first_frame+frame_offset%2, Reticle_frame_coords[gr_screen.res][RETICLE_LAUNCH_LABEL][0], Reticle_frame_coords[gr_screen.res][RETICLE_LAUNCH_LABEL][1]);
725
726                         // use hud text flash gauge code
727                         hud_show_text_flash_icon(XSTR("Launch", 1507), Reticle_launch_coords[gr_screen.res][1], bright);
728                 }
729         }
730 }
731
732 // Draw the dumbfire threat gauge on the HUD.  Use Threat_flags to determine if a
733 // threat exists, and draw flashing frames.
734 void hud_show_dumbfire_threat()
735 {
736         int frame_offset;
737
738         if ( Player->threat_flags & THREAT_DUMBFIRE ) {
739                 if ( timestamp_elapsed(Threat_dumbfire_timer) ) {
740                         Threat_dumbfire_timer = timestamp(THREAT_DUMBFIRE_FLASH);
741                         Threat_dumbfire_frame++;
742                         if ( Threat_dumbfire_frame > 2 ) {
743                                 Threat_dumbfire_frame = 1;
744                         }
745                 }
746                 frame_offset = Threat_dumbfire_frame;
747         } else {
748                 frame_offset = 0;
749         }
750
751         hud_set_gauge_color(HUD_THREAT_GAUGE);
752
753         GR_AABITMAP(Reticle_gauges[RETICLE_LASER_WARN].first_frame + frame_offset, Reticle_frame_coords[gr_screen.res][RETICLE_LASER_WARN][0], Reticle_frame_coords[gr_screen.res][RETICLE_LASER_WARN][1]);     
754 }
755
756 // Draw the center of the reticle
757 void hud_show_center_reticle()
758 {
759         Assert(Reticle_gauges[RETICLE_CENTER].first_frame != -1 );
760
761 //      hud_set_default_color();
762         // hud_set_bright_color();
763         hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
764
765         GR_AABITMAP(Reticle_gauges[RETICLE_CENTER].first_frame, Reticle_frame_coords[gr_screen.res][RETICLE_CENTER][0], Reticle_frame_coords[gr_screen.res][RETICLE_CENTER][1]);
766 }
767
768 // Draw top portion of reticle
769 void hud_show_top_arc()
770 {
771         hud_set_gauge_color(HUD_CENTER_RETICLE);
772
773         // hud_set_default_color();
774         if ( hud_gauge_active(HUD_THREAT_GAUGE) ) {     
775                 // draw top arc
776                 GR_AABITMAP(Reticle_gauges[RETICLE_TOP_ARC].first_frame+1, Reticle_frame_coords[gr_screen.res][RETICLE_TOP_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_TOP_ARC][1]);           
777
778                 // draw dumbfire threat
779                 hud_show_dumbfire_threat();
780
781                 // draw lock threat
782                 hud_show_lock_threat();
783         } else {                
784                 // draw top arc without any holes
785                 GR_AABITMAP(Reticle_gauges[RETICLE_TOP_ARC].first_frame, Reticle_frame_coords[gr_screen.res][RETICLE_TOP_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_TOP_ARC][1]);
786         }
787 }
788
789 // Draw right portion of reticle
790 void hud_show_right_arc()
791 {       
792         hud_set_gauge_color(HUD_CENTER_RETICLE);
793
794         GR_AABITMAP(Reticle_gauges[RETICLE_RIGHT_ARC].first_frame+1, Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][1]);             
795                 
796         // draw the weapons indicators in the holes along the right arc
797         /*
798         if ( hud_gauge_active(HUD_WEAPON_LINKING_GAUGE) ) {             
799                 // draw right arc with holes in it
800                 GR_AABITMAP(Reticle_gauges[RETICLE_RIGHT_ARC].first_frame+1, Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][1]);             
801
802 //              the following line was removed by Jasen to get rid of "undeclared identifier"
803 //              hehe - DB
804 //              hud_show_reticle_weapons();
805         } else {                
806                 // draw right arc without any holes
807                 GR_AABITMAP(Reticle_gauges[RETICLE_RIGHT_ARC].first_frame, Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_RIGHT_ARC][1]);
808         }
809         */
810 }
811
812 // Draw the left portion of the reticle
813 void hud_show_left_arc()
814 {                       
815         // draw left arc (the dark portion of the throttle gauge)
816         hud_set_gauge_color(HUD_CENTER_RETICLE);        
817         GR_AABITMAP(Reticle_gauges[RETICLE_LEFT_ARC].first_frame, Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][0], Reticle_frame_coords[gr_screen.res][RETICLE_LEFT_ARC][1]);                  
818         
819         // draw the throttle
820         if ( hud_gauge_active(HUD_THROTTLE_GAUGE) ) {
821                 hud_set_gauge_color(HUD_THROTTLE_GAUGE);
822                 hud_show_throttle();            
823         } 
824 }
825
826 // called once per frame from HUD_render_2d() to draw the reticle gauges
827 void hud_show_reticle()
828 {
829         if ( !(Viewer_mode & VM_OTHER_SHIP) ) {
830                 hud_show_top_arc();
831                 hud_show_right_arc();
832                 hud_show_left_arc();
833         }
834
835         // draw the center of the reticle
836         if ( hud_gauge_active(HUD_CENTER_RETICLE) ) {
837                 hud_show_center_reticle();
838         }
839 }
840
841 void hudreticle_page_in()
842 {
843         hud_frames      *hfp;
844
845         int i;
846         for ( i = 0; i < NUM_RETICLE_ANIS; i++ ) {
847                 hfp = &Reticle_gauges[i];
848                 bm_page_in_aabitmap( hfp->first_frame, hfp->num_frames);
849         }
850
851 }