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