]> icculus.org git repositories - taylor/freespace2.git/blob - src/hud/hudbrackets.cpp
a few NDEBUG updates.
[taylor/freespace2.git] / src / hud / hudbrackets.cpp
1 /*
2  * $Logfile: /Freespace2/code/Hud/HUDbrackets.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * C file that contains functions for drawing target brackets on the HUD
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  * 6     8/03/99 5:35p Andsager
18  * Dont draw target dot for instructor in training mission
19  * 
20  * 5     6/07/99 4:20p Andsager
21  * Add HUD color for tagged object.  Apply to target and radar.
22  * 
23  * 4     12/28/98 3:17p Dave
24  * Support for multiple hud bitmap filenames for hi-res mode.
25  * 
26  * 3     12/21/98 5:02p Dave
27  * Modified all hud elements to be multi-resolution friendly.
28  * 
29  * 2     10/07/98 10:53a Dave
30  * Initial checkin.
31  * 
32  * 1     10/07/98 10:49a Dave
33  * 
34  * 54    8/25/98 1:48p Dave
35  * First rev of EMP effect. Player side stuff basically done. Next comes
36  * AI code.
37  * 
38  * 53    6/01/98 11:43a John
39  * JAS & MK:  Classified all strings for localization.
40  * 
41  * 52    5/27/98 1:22p Allender
42  * make targeting dots work in multiplayer -- as well as many other minor
43  * targeting problems
44  * 
45  * 51    5/23/98 2:26a Lawrance
46  * Tweak brackets
47  * 
48  * 50    5/14/98 11:26a Lawrance
49  * ensure fighter bays are drawn with correct bracket color
50  * 
51  * 49    5/12/98 9:27a Mike
52  * num-ships-attacking: always showed an additional ship attacking
53  * asteroid or debris.  Fixed.
54  * 
55  * 48    5/08/98 10:16a Lawrance
56  * Add new "ship attacking count" gauge
57  * 
58  * 47    5/07/98 4:07p Mike
59  * Use smaller num-ships-attacking blip.
60  * 
61  * 46    5/06/98 5:30p John
62  * Removed unused cfilearchiver.  Removed/replaced some unused/little used
63  * graphics functions, namely gradient_h and _v and pixel_sp.   Put in new
64  * DirectX header files and libs that fixed the Direct3D alpha blending
65  * problems.
66  * 
67  * 45    5/06/98 2:46p Mike
68  * Modify num-ships-attacking system.
69  * 
70  * 44    5/03/98 1:07a Mike
71  * Show + for ships attacking your target, whether hostile or friendly.
72  * 
73  * 43    4/05/98 7:42p Lawrance
74  * fix inconsistent distance display on the HUD
75  * 
76  * 42    4/01/98 9:21p John
77  * Made NDEBUG, optimized build with no warnings or errors.
78  * 
79  * 41    3/30/98 12:20a Lawrance
80  * Draw subsystem targeting brackets gray if subsystem is destroyed.
81  * 
82  * 40    3/18/98 6:04p Lawrance
83  * Improve when brackets get drawn for large objects
84  * 
85  * 39    3/10/98 6:03p Lawrance
86  * Ensure proper bracket color gets drawn for traitors
87  * 
88  * 38    3/06/98 5:13p Johnson
89  * Put in a check for team traitor in hud_brackets_get_iff_color()
90  * 
91  * 37    3/02/98 11:32p Lawrance
92  * Allow asteroids about to impact ships to be bracketed
93  * 
94  * 36    2/21/98 2:49p Lawrance
95  * Don't do facing check for subsystems when deciding whether to draw
96  * brackets
97  * 
98  * 35    2/19/98 12:48a Lawrance
99  * Ensure subsystem brackets remain between HUD and target monitor
100  * 
101  * 34    2/09/98 8:05p Lawrance
102  * Add new gauges: cmeasure success, warp-out, and missiontime
103  * 
104  * 33    2/07/98 5:46p Lawrance
105  * Show target distance on brackets
106  * 
107  * 32    1/19/98 11:37p Lawrance
108  * Fixing Optimization build warnings
109  * 
110  * 31    1/18/98 5:09p Lawrance
111  * Added support for TEAM_TRAITOR
112  * 
113  * 30    1/02/98 10:01p Lawrance
114  * Ensure correct subsystem bracket color gets drawn once player goes
115  * traitor.
116  * 
117  * 29    1/02/98 9:10p Lawrance
118  * Big changes to how colors get set on the HUD.
119  * 
120  * 28    12/28/97 5:54p Lawrance
121  * Draw HUD brackets the correct IFF color.. taking into account that the
122  * player may be TEAM_NEUTRAL
123  * 
124  * 27    12/18/97 8:46p Lawrance
125  * Move IFF_color definitions from HUD->ship, so FRED can use them.
126  * 
127  * 26    12/17/97 11:14p Mike
128  * Change radar and hud color to red for all neutral.
129  * 
130  * 25    11/27/97 4:24p Lawrance
131  * change appearance of subsystem targeting brackets
132  * 
133  * 24    10/22/97 5:53p Lawrance
134  * change name of subsystem_in_sight() function
135  * 
136  * 23    9/06/97 2:13p Mike
137  * Replace support for TEAM_NEUTRAL
138  * 
139  * 22    7/24/97 10:45a Mike
140  * Fix hole in Unknown team support.
141  * 
142  * 21    7/24/97 10:24a Mike
143  * Restore support for Unknown team
144  * 
145  * 20    6/11/97 1:12p John
146  * Started fixing all the text colors in the game.
147  * 
148  * 19    5/21/97 11:12a Mike
149  * Move more stuff out of player struct, mainly subsys stuff.
150  * 
151  * 18    5/20/97 2:45p Mike
152  * Move current_target and a bunch of other stuff out of player struct.
153  * 
154  * 17    4/09/97 3:30p Lawrance
155  * let target brackets grow to bracket ship entirely
156  * 
157  * 16    4/08/97 1:28p Lawrance
158  * get brackets for targeting and messaging drawing right
159  * 
160  * 15    4/08/97 11:44a Lawrance
161  * get selection and target brackets drawing right at close and far
162  * distances
163  * 
164  * 14    4/08/97 10:55a Allender
165  * draw purple brackets on ship sending a message
166  * 
167  * 13    4/08/97 9:58a Lawrance
168  * center bracket on target center.  Give min and max dimensions to
169  * subsystem target brackets.
170  * 
171  * 12    4/07/97 6:03p Lawrance
172  * draw diamond brackets instead of dashed boxes
173  * 
174  * 11    4/07/97 3:50p Allender
175  * ability to assign > 1 ship to a hotkey.  Enabled use of hotkeys in
176  * squadmate messaging
177  * 
178  * 10    4/02/97 10:08a Lawrance
179  * fixed bracket drawing glitches 
180  * 
181  * 9     3/28/97 2:46p John
182  * added code to make debris chunks target properly.
183  * 
184  * 8     3/27/97 5:44p Lawrance
185  * drawing dashed lines for sub-object targeting box that is not in line
186  * of sight
187  * 
188  * 7     3/27/97 3:59p Lawrance
189  * made brackets draw even if center of target is offscreen
190  * 
191  * 6     3/27/97 9:29a Lawrance
192  * If reach maximum bounding box size, use radius targeting box method
193  * 
194  * 5     3/25/97 3:55p Lawrance
195  * allowing debris to be targeted and shown on radar
196  * 
197  * 4     3/23/97 11:55p Lawrance
198  * made max targeting bracket size of 200x200
199  * 
200  * 3     3/07/97 4:37p Mike
201  * Make rockeye missile home.
202  * Remove UNKNOWN and NEUTRAL teams.
203  * 
204  * 2     12/24/96 4:30p Lawrance
205  * Target bracket drawing code moved to separate files
206  *
207  * $NoKeywords: $
208  */
209
210 #include "hudbrackets.h"
211 #include "hud.h"
212 #include "player.h"
213 #include "hudtarget.h"
214 #include "3d.h"
215 #include "debris.h"
216 #include "ai.h"
217 #include "freespace.h"
218 #include "bmpman.h"
219 #include "linklist.h"
220 #include "emp.h"
221
222 #define FADE_FACTOR     2                       // how much the bounding brackets get faded
223 #define LOWEST_RED      50                      // lowest r value for bounding bracket
224 #define LOWEST_GREEN    50                      // lowest g value for bounding bracket
225 #define LOWEST_BLUE     50                      // lowest b value for bounding bracket
226
227 char Ships_attack_fname[GR_NUM_RESOLUTIONS][MAX_FILENAME_LEN] = {
228         "attacker",
229         "attacker"
230 };
231
232 // resolution adjust factors for the above defines
233 int Min_target_box_width[GR_NUM_RESOLUTIONS] = { 20, 30 };
234 int Min_target_box_height[GR_NUM_RESOLUTIONS] = { 20, 30 };
235 int Min_subtarget_box_width[GR_NUM_RESOLUTIONS] = { 12, 24 };
236 int Min_subtarget_box_height[GR_NUM_RESOLUTIONS] = { 12, 24 };
237
238 void hud_init_brackets()
239 {
240 }
241
242 // find IFF color index for brackets based on team
243 int hud_brackets_get_iff_color(int team)
244 {
245         int color=IFF_COLOR_FRIENDLY;
246
247         switch ( team ) {
248         case TEAM_FRIENDLY:
249         case TEAM_HOSTILE:
250         case TEAM_NEUTRAL:
251         case TEAM_TRAITOR:
252         case TEAM_UNKNOWN:
253                 if ( (team == Player_ship->team) && (team != TEAM_TRAITOR) ) {
254                         color = IFF_COLOR_FRIENDLY;
255                 } else {
256                         switch (team) {
257                         case TEAM_NEUTRAL:
258                                 color = IFF_COLOR_NEUTRAL;
259                                 break;
260                         case TEAM_UNKNOWN:
261                                 color = IFF_COLOR_UNKNOWN;
262                                 break;
263                         case TEAM_HOSTILE:
264                         case TEAM_FRIENDLY:
265                         case TEAM_TRAITOR:
266                                 color = IFF_COLOR_HOSTILE;
267                                 break;
268                         }
269                 }
270                 break;
271         case SELECTION_SET:
272                 color = IFF_COLOR_SELECTION;
273                 break;
274                 
275         case MESSAGE_SENDER:
276                 color = IFF_COLOR_MESSAGE;
277                 break;
278
279         default:
280                 color = IFF_COLOR_UNKNOWN;
281                 Int3();
282         } // end switch
283
284         return color;
285 }
286
287
288 //      Called by draw_bounding_brackets.  
289 void draw_brackets_square(int x1, int y1, int x2, int y2)
290 {
291         int     width, height;
292         
293         width = x2 - x1;
294         Assert( width > 0);
295         height = y2 - y1;
296         Assert( height > 0);
297
298         // make the brackets extend 25% of the way along the width or height
299         int bracket_width = width/4;
300         int bracket_height = height/4;
301
302         // horizontal lines
303         if ( (x1 + bracket_width > 0) && (x1 < gr_screen.clip_width) ){
304                 gr_gradient(x1,y1,x1+bracket_width-1,y1);       // top left
305                 gr_gradient(x1,y2,x1+bracket_width-1,y2);       // bottom left
306         }
307
308         if ( (x2 - bracket_width < gr_screen.clip_width) && (x2 > 0) )  {
309                 gr_gradient(x2, y1, x2-bracket_width+1,y1);     // top right
310                 gr_gradient(x2, y2, x2-bracket_width+1,y2);     // bottom right
311         }
312
313         // vertical lines
314         if ( (y1 + bracket_height > 0) && (y1 < gr_screen.clip_height) ) {
315                 gr_gradient(x1,y1,x1,y1+bracket_height-1);              // top left
316                 gr_gradient(x2,y1,x2,y1+bracket_height-1);              // top right
317         }
318
319         if ( (y2 - bracket_height < gr_screen.clip_height) && (y2 > 0) )        {
320                 gr_gradient(x1,y2,x1,y2-bracket_height+1);      // bottom left
321                 gr_gradient(x2,y2,x2,y2-bracket_height+1);      // bottom right
322         }
323 }
324
325 void draw_brackets_square_quick(int x1, int y1, int x2, int y2, int thick)
326 {
327         int     width, height;
328
329         width = x2 - x1;
330         height = y2 - y1;
331
332         // make the brackets extend 25% of the way along the width or height
333         int bracket_width = width/4;
334         int bracket_height = height/4;
335
336         // top line
337         gr_line(x1,y1,x1+bracket_width,y1);
338         gr_line(x2,y1,x2-bracket_width,y1);
339         if ( thick ) {
340                 gr_line(x1,y1+1,x1+bracket_width,y1+1);
341                 gr_line(x2,y1+1,x2-bracket_width,y1+1);
342         }
343
344         // bottom line
345         gr_line(x1,y2,x1+bracket_width,y2);
346         gr_line(x2,y2,x2-bracket_width,y2);
347         if ( thick ) {
348                 gr_line(x1,y2-1,x1+bracket_width,y2-1);
349                 gr_line(x2,y2-1,x2-bracket_width,y2-1);
350         }
351
352         // left line
353         if ( thick ) {
354                 gr_line(x1,y1+2,x1,y1+bracket_height);
355                 gr_line(x1,y2-2,x1,y2-bracket_height);
356                 gr_line(x1+1,y1+2,x1+1,y1+bracket_height);
357                 gr_line(x1+1,y2-2,x1+1,y2-bracket_height);
358         } else {
359                 gr_line(x1,y1+1,x1,y1+bracket_height);
360                 gr_line(x1,y2-1,x1,y2-bracket_height);
361         }
362
363         // right line
364         if ( thick ) {
365                 gr_line(x2,y1+2,x2,y1+bracket_height);
366                 gr_line(x2,y2-2,x2,y2-bracket_height);
367                 gr_line(x2-1,y1+2,x2-1,y1+bracket_height);
368                 gr_line(x2-1,y2-2,x2-1,y2-bracket_height);
369         } else {
370                 gr_line(x2,y1+1,x2,y1+bracket_height);
371                 gr_line(x2,y2-1,x2,y2-bracket_height);
372         }
373 }
374
375
376 #define NUM_DASHES      2
377 void draw_brackets_dashed_square_quick(int x1, int y1, int x2, int y2)
378 {
379         int     width, height, i;
380
381         width = x2 - x1;
382         height = y2 - y1;
383
384         // make the brackets extend 25% of the way along the width or height
385         float bracket_width = width/4.0f;
386         float bracket_height = height/4.0f;
387
388         int dash_width;
389         dash_width = fl2i(bracket_width / ( NUM_DASHES*2 - 1 ) + 0.5f);
390
391         if ( dash_width < 1 ) {
392                 draw_brackets_square_quick(x1, y1, x2, y2);
393                 return;
394         }
395
396         int dash_height;
397         dash_height = fl2i(bracket_height / ( NUM_DASHES*2 - 1 ) + 0.5f);
398
399         if ( dash_height < 1 ) {
400                 draw_brackets_square_quick(x1, y1, x2, y2);
401                 return;
402         }
403         
404         int dash_x1, dash_x2, dash_y1, dash_y2;
405
406         dash_x1 = x1;
407         dash_x2 = x2;
408         dash_y1 = y1;
409         dash_y2 = y2;
410
411         for ( i = 0; i < NUM_DASHES; i++ ) {
412                 // top line
413                 gr_line(dash_x1, y1, dash_x1+(dash_width-1), y1);
414                 gr_line(dash_x2, y1, dash_x2-(dash_width-1), y1);
415
416                 // bottom line
417                 gr_line(dash_x1, y2, dash_x1+(dash_width-1), y2);
418                 gr_line(dash_x2, y2, dash_x2-(dash_width-1), y2);
419                 
420                 dash_x1 += dash_width*2;
421                 dash_x2 -= dash_width*2;
422
423                 // left line
424                 gr_line(x1, dash_y1, x1, dash_y1+(dash_height-1));
425                 gr_line(x1, dash_y2, x1, dash_y2-(dash_height-1));
426
427                 // right line
428                 gr_line(x2, dash_y1, x2, dash_y1+(dash_height-1));
429                 gr_line(x2, dash_y2, x2, dash_y2-(dash_height-1));
430
431                 dash_y1 += dash_height*2;
432                 dash_y2 -= dash_height*2;
433         }
434
435 }
436
437
438
439 // draw_brackets_diamond()
440 //      Called by draw_bounding_brackets.  
441
442 void draw_brackets_diamond(int x1, int y1, int x2, int y2)
443 {
444         int width, height, half_width, half_height;
445         int center_x, center_y;
446         int x_delta, y_delta;
447
448         float side_len, bracket_len;
449
450         width = x2 - x1;
451         height = y2 - y1;
452
453         half_width = fl2i( width/2.0f + 0.5f );
454         half_height = fl2i( height/2.0f +0.5f );
455
456         side_len = (float)_hypot(half_width, half_height);
457         bracket_len = side_len / 8;
458         
459         x_delta = fl2i(bracket_len * width / side_len + 0.5f);
460         y_delta = fl2i(bracket_len * height / side_len + 0.5f);
461
462
463         center_x = x1 + half_width;
464         center_y = y1 + half_height;
465
466         // top left line
467         gr_gradient(center_x - x_delta, y1 + y_delta,center_x, y1);
468         gr_gradient(x1 + x_delta, center_y - y_delta, x1, center_y);
469
470         // top right line
471         gr_gradient(center_x + x_delta, y1 + y_delta,center_x, y1);
472         gr_gradient(x2 - x_delta, center_y - y_delta, x2, center_y);
473
474         // bottom left line
475         gr_gradient(x1 + x_delta, center_y + y_delta, x1, center_y);
476         gr_gradient(center_x - x_delta, y2 - y_delta, center_x, y2);
477
478         // bottom right line
479         gr_gradient(x2 - x_delta, center_y + y_delta, x2, center_y);
480         gr_gradient(center_x + x_delta, y2 - y_delta, center_x, y2);
481 }
482
483 void draw_brackets_diamond_quick(int x1, int y1, int x2, int y2, int thick)
484 {
485         int width, height, half_width, half_height;
486         int center_x, center_y;
487         int x_delta, y_delta;
488
489         float side_len, bracket_len;
490
491         width = x2 - x1;
492         height = y2 - y1;
493
494         half_width = fl2i( width/2.0f + 0.5f);
495         half_height = fl2i( height/2.0f + 0.5f);
496
497         side_len = (float)_hypot(half_width, half_height);
498         bracket_len = side_len / 8;
499         
500         x_delta = fl2i(bracket_len * width / side_len + 0.5f);
501         y_delta = fl2i(bracket_len * height / side_len + 0.5f);
502
503         center_x = x1 + half_width;
504         center_y = y1 + half_height;
505
506         // top left line
507         gr_line(center_x - x_delta, y1 + y_delta,center_x, y1);
508         gr_line(x1 + x_delta, center_y - y_delta, x1, center_y);
509
510         // top right line
511         gr_line(center_x + x_delta, y1 + y_delta,center_x, y1);
512         gr_line(x2 - x_delta, center_y - y_delta, x2, center_y);
513
514         // bottom left line
515         gr_line(x1 + x_delta, center_y + y_delta, x1, center_y);
516         gr_line(center_x - x_delta, y2 - y_delta, center_x, y2);
517
518         // bottom right line
519         gr_line(x2 - x_delta, center_y + y_delta, x2, center_y);
520         gr_line(center_x + x_delta, y2 - y_delta, center_x, y2);
521
522         // draw an 'X' in the middle of the brackets
523         gr_line(center_x-x_delta, center_y-y_delta, center_x+x_delta, center_y+y_delta);
524         gr_line(center_x-x_delta, center_y+y_delta, center_x+x_delta, center_y-y_delta);
525 }
526
527
528 int subsys_is_fighterbay(ship_subsys *ss)
529 {
530         if ( !strnicmp(NOX("fighter"), ss->system_info->name, 7) ) {
531                 return 1;
532         }
533
534         return 0;
535 }
536
537 //      Draw bounding brackets for a subobject.
538 void draw_bounding_brackets_subobject()
539 {
540         if (Player_ai->targeted_subsys_parent == Player_ai->target_objnum)
541                 if (Player_ai->targeted_subsys != NULL) {
542                         ship_subsys     *subsys;
543                         int             target_objnum;
544                         object* targetp;
545                         vertex subobj_vertex;
546                         vector  subobj_pos;
547                         int x1,x2,y1,y2;
548
549                         subsys = Player_ai->targeted_subsys;
550                         target_objnum = Player_ai->target_objnum;
551                         Assert(target_objnum != -1);
552                         targetp = &Objects[target_objnum];
553                         Assert( targetp->type == OBJ_SHIP );
554
555                         get_subsystem_world_pos(targetp, subsys, &subobj_pos);
556
557                         g3_rotate_vertex(&subobj_vertex,&subobj_pos);
558
559                         g3_project_vertex(&subobj_vertex);
560                         if (subobj_vertex.flags & PF_OVERFLOW)  // if overflow, no point in drawing brackets
561                                 return;
562
563                         int subobj_x = fl2i(subobj_vertex.sx + 0.5f);
564                         int subobj_y = fl2i(subobj_vertex.sy + 0.5f);
565                         int hud_subtarget_w, hud_subtarget_h, bound_rc;
566
567                         bound_rc = subobj_find_2d_bound(subsys->system_info->radius, &targetp->orient, &subobj_pos, &x1,&y1,&x2,&y2);
568                         if ( bound_rc != 0 )
569                                 return;
570
571                         hud_subtarget_w = x2-x1+1;
572                         if ( hud_subtarget_w > gr_screen.clip_width ) {
573                                 hud_subtarget_w = gr_screen.clip_width;
574                         }
575
576                         hud_subtarget_h = y2-y1+1;
577                         if ( hud_subtarget_h > gr_screen.clip_height ) {
578                                 hud_subtarget_h = gr_screen.clip_height;
579                         }
580
581                         if ( hud_subtarget_w > gr_screen.max_w ) {
582                                 x1 = subobj_x - (gr_screen.max_w>>1);
583                                 x2 = subobj_x + (gr_screen.max_w>>1);
584                         }
585                         if ( hud_subtarget_h > gr_screen.max_h ) {
586                                 y1 = subobj_y - (gr_screen.max_h>>1);
587                                 y2 = subobj_y + (gr_screen.max_h>>1);
588                         }
589
590                         if ( hud_subtarget_w < Min_subtarget_box_width[gr_screen.res] ) {
591                                 x1 = subobj_x - (Min_subtarget_box_width[gr_screen.res]>>1);
592                                 x2 = subobj_x + (Min_subtarget_box_width[gr_screen.res]>>1);
593                         }
594                         if ( hud_subtarget_h < Min_subtarget_box_height[gr_screen.res] ) {
595                                 y1 = subobj_y - (Min_subtarget_box_height[gr_screen.res]>>1);
596                                 y2 = subobj_y + (Min_subtarget_box_height[gr_screen.res]>>1);
597                         }
598
599                         // determine if subsystem is on far or near side of the ship
600                         Player->subsys_in_view = ship_subsystem_in_sight(targetp, subsys, &View_position, &subobj_pos, 0);
601
602                         // AL 29-3-98: If subsystem is destroyed, draw gray brackets                                    
603                         if ( (Player_ai->targeted_subsys->current_hits <= 0) && (!subsys_is_fighterbay(Player_ai->targeted_subsys)) ) {
604                                 gr_set_color_fast(&IFF_colors[IFF_COLOR_MESSAGE][1]);
605                         } else {
606                                 hud_set_iff_color( targetp, 1 );
607                         }
608
609                         if ( Player->subsys_in_view ) {
610                                 draw_brackets_square_quick(x1, y1, x2, y2);
611                         } else {
612                                 draw_brackets_diamond_quick(x1, y1, x2, y2);
613                         }
614                         // mprintf(("Drawing subobject brackets at %4i, %4i\n", sx, sy));
615                 }
616 }
617
618 extern int HUD_drew_selection_bracket_on_target;
619
620 // Display the current target distance, right justified at (x,y)
621 void hud_target_show_dist_on_bracket(int x, int y, float distance)
622 {
623         char    text_dist[64];
624         int     w,h;
625
626         if ( y < 0 || y > gr_screen.clip_height ) {
627                 return;
628         }
629
630         if ( x < 0 || x > gr_screen.clip_width ) {
631                 return;
632         }
633
634         sprintf(text_dist, "%d", fl2i(distance+0.5f));
635         hud_num_make_mono(text_dist);
636         gr_get_string_size(&w,&h,text_dist);
637
638         int y_delta = 4;
639         if ( HUD_drew_selection_bracket_on_target ) {
640                 y += 4;
641         }
642
643         gr_string(x - w+2, y+y_delta, text_dist);
644 }
645
646
647 // !!!!!!!!!!!!!!!
648 //      Given an object number, return the number of ships attacking it.
649 // MWA 5/26/98 -- copied from aicode num_attacking_ships()!!!
650 // !!!!!!!!!!!!!!!
651 int hud_bracket_num_ships_attacking(int objnum)
652 {
653         object  *objp;
654         ship_obj        *so;
655         int             count = 0;
656
657         for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
658                 objp = &Objects[so->objnum];
659                 if (objp->instance != -1) {
660                         ai_info *aip;
661                         aip = &Ai_info[Ships[objp->instance].ai_index];
662
663                         // don't count instructor
664                         int is_training_mission();
665                         if ( is_training_mission() && stricmp(Ships[objp->instance].ship_name, "Instructor") == 0) {
666                                 break;
667                         }
668
669                         if ( ((Game_mode & GM_MULTIPLAYER) || (aip->mode == AIM_CHASE)) && (aip->target_objnum == objnum))
670                                 if (Ships[objp->instance].team != Ships[Objects[objnum].instance].team)
671                                         count++;
672                 }
673         }
674
675         return count;
676 }
677
678
679 int     Ships_attacking_bitmap = -1;
680
681 // draw_bounding_brackets() will draw the faded brackets that surround the current target
682 void draw_bounding_brackets(int x1, int y1, int x2, int y2, int w_correction, int h_correction, float distance, int target_objnum)
683 {
684         int width, height;
685
686         if ( ( x1 < 0 && x2 < 0 ) || ( y1 < 0 && y2 < 0 ) )
687                 return;
688
689         if ( ( x1 > gr_screen.clip_width && x2 > gr_screen.clip_width ) ||
690                   ( y1 > gr_screen.clip_height && y2 > gr_screen.clip_height ) )
691                 return;
692
693         width = x2-x1;
694         Assert(width>=0);
695
696         height = y2-y1;
697         Assert(height>=0);
698
699         if ( (width>(gr_screen.max_w - 1)) && (height>(gr_screen.max_h - 1)) ) {
700                 return;
701         }
702         if ( width > 1200 ) {
703                 return;
704
705         }
706         if ( height > 1200) {
707                 return;
708         }
709
710         if (width < Min_target_box_width[gr_screen.res]) {
711                 x1 = x1 - (Min_target_box_width[gr_screen.res]-width)/2;
712                 x2 = x2 + (Min_target_box_width[gr_screen.res]-width)/2;
713         }
714
715         if (height < Min_target_box_height[gr_screen.res]) {
716                 y1 = y1 - (Min_target_box_height[gr_screen.res]-height)/2;
717                 y2 = y2 + (Min_target_box_height[gr_screen.res]-height)/2;
718         }
719                 
720         draw_brackets_square(x1-w_correction, y1-h_correction, x2+w_correction, y2+h_correction);
721
722         // draw distance to target in lower right corner of box
723         if ( distance > 0 ) {
724                 hud_target_show_dist_on_bracket(x2+w_correction,y2+h_correction,distance);
725         }
726
727         //      Maybe show + for each additional fighter or bomber attacking target.
728         if ( (target_objnum != -1) && hud_gauge_active(HUD_ATTACKING_TARGET_COUNT) ) {
729                 int num_attacking = hud_bracket_num_ships_attacking(target_objnum);
730
731                 if (Ships_attacking_bitmap == -1){
732                         Ships_attacking_bitmap = bm_load(Ships_attack_fname[gr_screen.res]);
733                 }
734
735                 if (Ships_attacking_bitmap == -1) {
736                         Int3();
737                         return;
738                 }
739
740                 //      If a ship not on player's team, show one fewer plus since it is targeted and attacked by player.
741                 int     k=0;
742                 if (Objects[target_objnum].type == OBJ_SHIP) {
743                         if (Ships[Objects[target_objnum].instance].team != Player_ship->team){
744                                 k = 1;
745                         }
746                 } else {
747                         k = 1;
748                 }
749
750                 if (num_attacking > k) {
751                         int     i, num_blips;
752                         
753                         num_blips = num_attacking-k;
754                         if (num_blips > 4){
755                                 num_blips = 4;
756                         }
757
758                         //int   bitmap = get_blip_bitmap();
759
760                         if (Ships_attacking_bitmap > -1) {
761                                 if (num_blips > 3)
762                                         y1 -= 3;
763
764                                 for (i=0; i<num_blips; i++) {
765                                         GR_AABITMAP(Ships_attacking_bitmap, x2+3, y1+i*7);                                      
766                                 }
767                         }
768                 }
769         }
770 }
771