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