1 /**************************************************************************
2 * hud.c -- hud defines and prototypes
4 * Written by Michele America, started September 1997.
6 * Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * (Log is kept at end of this file)
24 **************************************************************************/
36 # include <values.h> /* for MAXINT */
37 #endif /* not WIN32 */
41 #include <Aircraft/aircraft.h>
42 #include <Include/fg_constants.h>
43 #include <Main/fg_debug.h>
44 #include <Math/fg_random.h>
45 #include <Math/mat3.h>
46 #include <Math/polar.h>
47 #include <Scenery/scenery.h>
48 #include <Time/fg_timer.h>
49 #include <Weather/weather.h>
53 #define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES); \
54 glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd();
56 /* textString - Bitmap font string */
58 static void textString(int x, int y, char *msg, void *font)
62 glutBitmapCharacter(font, *msg);
67 /* strokeString - Stroke font string */
68 /* static void strokeString(int x, int y, char *msg, void *font) */
71 /* glTranslatef(x, y, 0); */
72 /* glScalef(.04, .04, .04); */
74 /* glutStrokeCharacter(font, *msg); */
82 Draws a measuring scale anywhere on the HUD
85 Needs: HUD_scale struct
88 static void drawscale( int type, int sub_type, int min_value, int orientation, int scr_pos, \
89 int scr_min, int scr_max, double total_amount, int min_div, int max_div, \
93 int marker_x, marker_y;
95 // int scale_min, scale_max;
101 vmin = cur_value-total_amount/2;
102 vmax = cur_value+total_amount/2;
104 mid_scr = scr_min+(scr_max-scr_min)/2;
106 if( type == VERTICAL ) // Vertical scale
108 if( orientation == LEFT )
109 marker_x = scr_pos-6;
110 else if( orientation == RIGHT )
112 drawOneLine( scr_pos, scr_min, scr_pos, scr_max );
113 if( orientation == LEFT )
115 drawOneLine( scr_pos-3, scr_min, scr_pos, scr_min );
116 drawOneLine( scr_pos-3, scr_max, scr_pos, scr_max );
117 drawOneLine( scr_pos, mid_scr, scr_pos+6, mid_scr );
118 } else if( orientation == RIGHT )
120 drawOneLine( scr_pos, scr_min, scr_pos+3, scr_min );
121 drawOneLine( scr_pos, scr_max, scr_pos+3, scr_max );
122 drawOneLine( scr_pos, mid_scr, scr_pos-6, mid_scr );
125 factor = (scr_max-scr_min)/total_amount;
127 for( i=vmin; i<=vmax; i+=1 )
129 if( sub_type == LIMIT )
130 condition = i>= min_value;
131 else if( sub_type == NOLIMIT )
136 marker_y = scr_min+(i-vmin)*factor;
138 if( orientation == LEFT )
140 drawOneLine( marker_x+3, marker_y, marker_x+6, marker_y );
142 else if( orientation == RIGHT )
144 drawOneLine( marker_x, marker_y, marker_x+3, marker_y );
148 drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
149 sprintf( TextScale, "%d", i );
150 if( orientation == LEFT )
152 textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
154 else if( orientation == RIGHT )
156 textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
162 if( type == HORIZONTAL ) // Horizontal scale
164 if( orientation == TOP )
166 else if( orientation == BOTTOM )
167 marker_y = scr_pos-6;
168 drawOneLine( scr_min, scr_pos, scr_max, scr_pos );
169 if( orientation == TOP )
171 drawOneLine( scr_min, scr_pos, scr_min, scr_pos-3 );
172 drawOneLine( scr_max, scr_pos, scr_max, scr_pos-3 );
173 drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos-6 );
174 } else if( orientation == BOTTOM )
176 drawOneLine( scr_min, scr_pos, scr_min, scr_pos+3 );
177 drawOneLine( scr_max, scr_pos, scr_max, scr_pos+3 );
178 drawOneLine( mid_scr, scr_pos, mid_scr, scr_pos+6 );
181 factor = (scr_max-scr_min)/total_amount;
183 for( i=vmin; i<=vmax; i+=1 )
185 if( sub_type == LIMIT )
186 condition = i>= min_value;
187 else if( sub_type == NOLIMIT )
192 marker_x = scr_min+(i-vmin)*factor;
194 if( orientation == TOP )
196 drawOneLine( marker_x, marker_y, marker_x, marker_y+3 );
198 else if( orientation == BOTTOM )
200 drawOneLine( marker_x, marker_y+3, marker_x, marker_y+6 );
204 sprintf( TextScale, "%d", i );
205 if( orientation == TOP )
207 drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
208 textString( marker_x-4*strlen(TextScale), marker_y+14, TextScale, GLUT_BITMAP_8_BY_13 );
210 else if( orientation == BOTTOM )
212 drawOneLine( marker_x, marker_y, marker_x, marker_y+6 );
213 textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
224 Draws a climb ladder in the center of the HUD
227 Needs: HUD_ladder struct
230 static void drawladder( struct HUD_ladder ladder )
233 double roll_value, pitch_value;
234 /* double cos_roll, sin_roll; */
235 int marker_x, marker_y;
237 int scr_min, scr_max;
240 int new_x_ini, new_x_end;
241 int new_y_ini, new_y_end;
247 roll_value = (*ladder.load_roll)();
248 pitch_value = (*ladder.load_pitch)()*RAD_TO_DEG;
250 vmin = pitch_value-ladder.width_units/2;
251 vmax = pitch_value+ladder.width_units/2;
253 scr_min = ladder.y_pos-(ladder.scr_height/2);
254 scr_max = scr_min+ladder.scr_height;
256 mid_scr = scr_min+(scr_max-scr_min)/2;
258 marker_x = ladder.x_pos-ladder.scr_width/2;
260 factor = (scr_max-scr_min)/ladder.width_units;
262 for( i=vmin; i<=vmax; i+=1 )
267 marker_y = scr_min+(i-vmin)*factor;
268 if( i%ladder.div_units==0 )
270 sprintf( TextLadder, "%d", i );
271 if( ladder.scr_hole == 0 )
274 x_ini = ladder.x_pos-ladder.scr_width/2;
276 x_ini = ladder.x_pos-ladder.scr_width/2-10;
278 x_end = ladder.x_pos+ladder.scr_width/2;
280 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
281 (y_ini-ladder.y_pos)*sin(roll_value);
282 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
283 (y_ini-ladder.y_pos)*cos(roll_value);
284 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
285 (y_end-ladder.y_pos)*sin(roll_value);
286 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
287 (y_end-ladder.y_pos)*cos(roll_value);
291 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
295 glEnable(GL_LINE_STIPPLE);
296 glLineStipple( 1, 0x00FF );
297 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
298 glDisable(GL_LINE_STIPPLE);
300 textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
301 textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
306 x_ini = ladder.x_pos-ladder.scr_width/2;
308 x_ini = ladder.x_pos-ladder.scr_width/2-10;
310 x_end = ladder.x_pos-ladder.scr_width/2+ladder.scr_hole/2;
312 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
313 (y_ini-ladder.y_pos)*sin(roll_value);
314 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
315 (y_ini-ladder.y_pos)*cos(roll_value);
316 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
317 (y_end-ladder.y_pos)*sin(roll_value);
318 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
319 (y_end-ladder.y_pos)*cos(roll_value);
323 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
327 glEnable(GL_LINE_STIPPLE);
328 glLineStipple( 1, 0x00FF );
329 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
330 glDisable(GL_LINE_STIPPLE);
332 textString( new_x_ini-8*strlen(TextLadder)-8, new_y_ini-4, TextLadder, GLUT_BITMAP_8_BY_13 );
334 x_ini = ladder.x_pos+ladder.scr_width/2-ladder.scr_hole/2;
337 x_end = ladder.x_pos+ladder.scr_width/2;
339 x_end = ladder.x_pos+ladder.scr_width/2+10;
341 new_x_ini = ladder.x_pos+(x_ini-ladder.x_pos)*cos(roll_value)-\
342 (y_ini-ladder.y_pos)*sin(roll_value);
343 new_y_ini = ladder.y_pos+(x_ini-ladder.x_pos)*sin(roll_value)+\
344 (y_ini-ladder.y_pos)*cos(roll_value);
345 new_x_end = ladder.x_pos+(x_end-ladder.x_pos)*cos(roll_value)-\
346 (y_end-ladder.y_pos)*sin(roll_value);
347 new_y_end = ladder.y_pos+(x_end-ladder.x_pos)*sin(roll_value)+\
348 (y_end-ladder.y_pos)*cos(roll_value);
352 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
356 glEnable(GL_LINE_STIPPLE);
357 glLineStipple( 1, 0x00FF );
358 drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
359 glDisable(GL_LINE_STIPPLE);
361 textString( new_x_end+10, new_y_end-4, TextLadder, GLUT_BITMAP_8_BY_13 );
364 /* if( i%max_div==0 )
366 drawOneLine( marker_x, marker_y, marker_x+6, marker_y );
367 sprintf( TextScale, "%d", i );
368 if( orientation == LEFT )
370 textString( marker_x-8*strlen(TextScale)-2, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
372 else if( orientation == RIGHT )
374 textString( marker_x+10, marker_y-4, TextScale, GLUT_BITMAP_8_BY_13 );
384 Draws an artificial horizon line in the center of the HUD
385 (with or without a center hole)
387 Needs: x_center, y_center, length, hole
390 static void drawhorizon( struct HUD_horizon horizon )
394 /* struct fgFLIGHT *f; */
395 double sin_bank, cos_bank;
398 /* f = ¤t_aircraft.flight; */
400 bank_angle = (*horizon.load_value)();
402 // sin_bank = sin( FG_2PI-FG_Phi );
403 // cos_bank = cos( FG_2PI-FG_Phi );
404 sin_bank = sin(FG_2PI-bank_angle);
405 cos_bank = cos(FG_2PI-bank_angle);
406 x_inc1 = (int)(horizon.scr_width*cos_bank);
407 y_inc1 = (int)(horizon.scr_width*sin_bank);
408 x_inc2 = (int)(horizon.scr_hole*cos_bank);
409 y_inc2 = (int)(horizon.scr_hole*sin_bank);
411 if( horizon.scr_hole == 0 )
413 drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
414 horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
418 drawOneLine( horizon.x_pos-x_inc1, horizon.y_pos-y_inc1, \
419 horizon.x_pos-x_inc2, horizon.y_pos-y_inc2 );
420 drawOneLine( horizon.x_pos+x_inc2, horizon.y_pos+y_inc2, \
421 horizon.x_pos+x_inc1, horizon.y_pos+y_inc1 );
427 Draws a representation of the control surfaces in their current state
430 Needs: struct HUD_control_surfaces
433 static void drawcontrolsurfaces( struct HUD_control_surfaces ctrl_surf )
439 struct fgCONTROLS *c;
441 x_ini = ctrl_surf.x_pos;
442 y_ini = ctrl_surf.y_pos;
446 drawOneLine( x_ini, y_ini, x_end, y_ini );
447 drawOneLine( x_ini, y_ini, x_ini, y_end );
448 drawOneLine( x_ini, y_end, x_end, y_end );
449 drawOneLine( x_end, y_end, x_end, y_ini );
450 drawOneLine( x_ini+30, y_ini, x_ini+30, y_end );
451 drawOneLine( x_ini+30, y_ini+30, x_ini+90, y_ini+30 );
452 drawOneLine( x_ini+90, y_ini, x_ini+90, y_end );
453 drawOneLine( x_ini+120, y_ini, x_ini+120, y_end );
455 c = ¤t_aircraft.controls;
457 /* Draw elevator diagram */
458 textString( x_ini+1, y_end-11, "E", GLUT_BITMAP_8_BY_13 );
459 drawOneLine( x_ini+15, y_ini+5, x_ini+15, y_ini+55 );
460 drawOneLine( x_ini+14, y_ini+30, x_ini+16, y_ini+30 );
461 if( FG_Elevator <= -0.01 || FG_Elevator >= 0.01 )
463 drawOneLine( x_ini+10, y_ini+5+(int)(((FG_Elevator+1.0)/2)*50.0), \
464 x_ini+20, y_ini+5+(int)(((FG_Elevator+1.0)/2)*50.0) );
468 drawOneLine( x_ini+7, y_ini+5+(int)(((FG_Elevator+1.0)/2)*50.0), \
469 x_ini+23, y_ini+5+(int)(((FG_Elevator+1.0)/2)*50.0) );
472 /* Draw aileron diagram */
473 textString( x_ini+30+1, y_end-11, "A", GLUT_BITMAP_8_BY_13 );
474 drawOneLine( x_ini+35, y_end-15, x_ini+85, y_end-15 );
475 drawOneLine( x_ini+60, y_end-14, x_ini+60, y_end-16 );
476 if( FG_Aileron <= -0.01 || FG_Aileron >= 0.01 )
478 drawOneLine( x_ini+35+(int)(((FG_Aileron+1.0)/2)*50.0), y_end-20, \
479 x_ini+35+(int)(((FG_Aileron+1.0)/2)*50.0), y_end-10 );
483 drawOneLine( x_ini+35+(int)(((FG_Aileron+1.0)/2)*50.0), y_end-25, \
484 x_ini+35+(int)(((FG_Aileron+1.0)/2)*50.0), y_end-5 );
487 /* Draw rudder diagram */
488 textString( x_ini+30+1, y_ini+21, "R", GLUT_BITMAP_8_BY_13 );
489 drawOneLine( x_ini+35, y_ini+15, x_ini+85, y_ini+15 );
490 drawOneLine( x_ini+60, y_ini+14, x_ini+60, y_ini+16 );
491 if( FG_Rudder <= -0.01 || FG_Rudder >= 0.01 )
493 drawOneLine( x_ini+35+(int)(((FG_Rudder+1.0)/2)*50.0), y_ini+20, \
494 x_ini+35+(int)(((FG_Rudder+1.0)/2)*50.0), y_ini+10 );
498 drawOneLine( x_ini+35+(int)(((FG_Rudder+1.0)/2)*50.0), y_ini+25, \
499 x_ini+35+(int)(((FG_Rudder+1.0)/2)*50.0), y_ini+5 );
503 /* Draw throttle diagram */
504 textString( x_ini+90+1, y_end-11, "T", GLUT_BITMAP_8_BY_13 );
505 textString( x_ini+90+1, y_end-21, "r", GLUT_BITMAP_8_BY_13 );
506 drawOneLine( x_ini+105, y_ini+5, x_ini+105, y_ini+55 );
507 drawOneLine( x_ini+100, y_ini+5+(int)(FG_Throttle[0]*50.0), \
508 x_ini+110, y_ini+5+(int)(FG_Throttle[0]*50.0) );
511 /* Draw elevator trim diagram */
512 textString( x_ini+121, y_end-11, "T", GLUT_BITMAP_8_BY_13 );
513 textString( x_ini+121, y_end-22, "m", GLUT_BITMAP_8_BY_13 );
514 drawOneLine( x_ini+135, y_ini+5, x_ini+135, y_ini+55 );
515 drawOneLine( x_ini+134, y_ini+30, x_ini+136, y_ini+30 );
516 if( FG_Elev_Trim <= -0.01 || FG_Elev_Trim >= 0.01 )
518 drawOneLine( x_ini+130, y_ini+5+(int)(((FG_Elev_Trim+1)/2)*50.0), \
519 x_ini+140, y_ini+5+(int)(((FG_Elev_Trim+1.0)/2)*50.0) );
523 drawOneLine( x_ini+127, y_ini+5+(int)(((FG_Elev_Trim+1.0)/2)*50.0), \
524 x_ini+143, y_ini+5+(int)(((FG_Elev_Trim+1.0)/2)*50.0) );
531 Draws a label anywhere in the HUD
533 Needs: HUD_label struct
536 static void drawlabel( struct HUD_label label )
543 if( label.pre_str != NULL && label.post_str != NULL )
544 sprintf( buffer, "%s%s%s", label.pre_str, label.format, label.post_str );
545 else if( label.pre_str == NULL && label.post_str != NULL )
546 sprintf( buffer, "%s%s", label.format, label.post_str );
547 else if( label.pre_str != NULL && label.post_str == NULL )
548 sprintf( buffer, "%s%s", label.pre_str, label.format );
550 sprintf( string, buffer, (*label.load_value)() );
552 fgPrintf( FG_COCKPIT, FG_DEBUG, buffer );
553 fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" );
554 fgPrintf( FG_COCKPIT, FG_DEBUG, string );
555 fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" );
557 lenstr = strlen( string );
558 if( label.justify == LEFT_JUST )
560 else if( label.justify == CENTER_JUST )
562 else if( label.justify == RIGHT_JUST )
565 if( label.size == SMALL )
566 textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_8_BY_13);
567 else if( label.size == LARGE )
568 textString( label.x_pos+posincr, label.y_pos, string, GLUT_BITMAP_9_BY_15);
572 double get_speed( void )
576 f = ¤t_aircraft.flight;
577 return( FG_V_equiv_kts );
580 double get_aoa( void )
584 f = ¤t_aircraft.flight;
585 return( FG_Gamma_vert_rad*RAD_TO_DEG );
588 double get_roll( void )
592 f = ¤t_aircraft.flight;
596 double get_pitch( void )
600 f = ¤t_aircraft.flight;
604 double get_heading( void )
608 f = ¤t_aircraft.flight;
609 return( FG_Psi*RAD_TO_DEG );
612 double get_altitude( void )
615 /* double rough_elev; */
617 f = ¤t_aircraft.flight;
618 /* rough_elev = mesh_altitude(FG_Longitude * RAD_TO_ARCSEC,
619 FG_Latitude * RAD_TO_ARCSEC); */
621 return( FG_Altitude * FEET_TO_METER /* -rough_elev */ );
624 void add_instrument( Hptr hud, HIptr instrument )
628 instruments = hud->instruments;
629 // while( ++instruments
632 Hptr fgHUDInit( struct fgAIRCRAFT current_aircraft, int color )
636 hud = (Hptr)calloc(sizeof(struct HUD),1);
640 hud->code = 1; /* It will be aircraft dependent */
643 // For now lets just hardcode a hud here .
644 // In the future, hud information has to come from the same place
645 // aircraft information came
647 fgHUDAddHorizon( hud, 590, 50, 40, 20, get_roll );
648 fgHUDAddScale( hud, VERTICAL, 220, 100, 280, 5, 10, LEFT, LEFT, 0, 100, get_speed );
649 fgHUDAddScale( hud, VERTICAL, 440, 100, 280, 1, 5, RIGHT, RIGHT, -400, 25, get_aoa );
650 fgHUDAddScale( hud, HORIZONTAL, 280, 220, 440, 5, 10, TOP, TOP, 0, 50, get_heading );
651 fgHUDAddLabel( hud, 180, 85, SMALL, NOBLINK, RIGHT_JUST, NULL, " Kts", "%5.0f", get_speed );
652 fgHUDAddLabel( hud, 180, 73, SMALL, NOBLINK, RIGHT_JUST, NULL, " m", "%5.0f", get_altitude );
653 fgHUDAddLadder( hud, 330, 190, 90, 180, 70, 10, NONE, 45, get_roll, get_pitch );
654 fgHUDAddControlSurfaces( hud, 10, 10, get_heading );
659 Hptr fgHUDAddHorizon( Hptr hud, int x_pos, int y_pos, int length, \
660 int hole_len, double (*load_value)() )
662 struct HUD_horizon *horizon;
663 struct HUD_instr *instrument;
664 HIptr tmp_first, tmp_next;
666 tmp_first = hud->instruments;
667 if( tmp_first != NULL )
668 tmp_next = tmp_first->next;
672 instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
673 if( instrument == NULL )
676 horizon = (struct HUD_horizon *)calloc(sizeof(struct HUD_horizon),1);
677 if( horizon == NULL )
680 instrument->type = ARTIFICIAL_HORIZON;
681 instrument->instr.horizon = *horizon;
682 instrument->instr.horizon.x_pos = x_pos;
683 instrument->instr.horizon.y_pos = y_pos;
684 instrument->instr.horizon.scr_width = length;
685 instrument->instr.horizon.scr_hole = hole_len;
686 instrument->instr.horizon.load_value = load_value;
687 instrument->next = tmp_first;
689 hud->instruments = instrument;
694 Hptr fgHUDAddScale( Hptr hud, int type, int scr_pos, int scr_min, int scr_max, int div_min, int div_max, \
695 int orientation, int with_min, int min_value, int width_units, double (*load_value)() )
697 struct HUD_scale *scale;
698 struct HUD_instr *instrument;
699 HIptr tmp_first, tmp_next;
701 tmp_first = hud->instruments;
702 if( tmp_first != NULL )
703 tmp_next = tmp_first->next;
707 instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
708 if( instrument == NULL )
711 scale = (struct HUD_scale *)calloc(sizeof(struct HUD_scale),1);
715 instrument->type = SCALE;
716 instrument->instr.scale = *scale;
717 instrument->instr.scale.type = type;
718 instrument->instr.scale.scr_pos = scr_pos;
719 instrument->instr.scale.scr_min = scr_min;
720 instrument->instr.scale.scr_max = scr_max;
721 instrument->instr.scale.div_min = div_min;
722 instrument->instr.scale.div_max = div_max;
723 instrument->instr.scale.orientation = orientation;
724 instrument->instr.scale.with_minimum = with_min;
725 instrument->instr.scale.minimum_value = min_value;
726 instrument->instr.scale.width_units = width_units;
727 instrument->instr.scale.load_value = load_value;
728 instrument->next = tmp_first;
730 hud->instruments = instrument;
735 Hptr fgHUDAddLabel( Hptr hud, int x_pos, int y_pos, int size, int blink, int justify, \
736 char *pre_str, char *post_str, char *format, double (*load_value)() )
738 struct HUD_label *label;
739 struct HUD_instr *instrument;
740 HIptr tmp_first, tmp_next;
742 tmp_first = hud->instruments;
743 if( tmp_first != NULL )
744 tmp_next = tmp_first->next;
748 instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
749 if( instrument == NULL )
752 label = (struct HUD_label *)calloc(sizeof(struct HUD_label),1);
756 instrument->type = LABEL;
757 instrument->instr.label = *label;
758 instrument->instr.label.x_pos = x_pos;
759 instrument->instr.label.y_pos = y_pos;
760 instrument->instr.label.size = size;
761 instrument->instr.label.blink = blink;
762 instrument->instr.label.justify = justify;
763 instrument->instr.label.pre_str = pre_str;
764 instrument->instr.label.post_str = post_str;
765 instrument->instr.label.format = format;
766 instrument->instr.label.load_value = load_value;
767 instrument->next = tmp_first;
769 hud->instruments = instrument;
774 Hptr fgHUDAddLadder( Hptr hud, int x_pos, int y_pos, int scr_width, int scr_height, \
775 int hole_len, int div_units, int label_pos, int width_units, \
776 double (*load_roll)(), double (*load_pitch)() )
778 struct HUD_ladder *ladder;
779 struct HUD_instr *instrument;
780 HIptr tmp_first, tmp_next;
782 tmp_first = hud->instruments;
783 if( tmp_first != NULL )
784 tmp_next = tmp_first->next;
788 instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
789 if( instrument == NULL )
792 ladder = (struct HUD_ladder *)calloc(sizeof(struct HUD_ladder),1);
796 instrument->type = LADDER;
797 instrument->instr.ladder = *ladder;
798 instrument->instr.ladder.type = 0; // Not used.
799 instrument->instr.ladder.x_pos = x_pos;
800 instrument->instr.ladder.y_pos = y_pos;
801 instrument->instr.ladder.scr_width = scr_width;
802 instrument->instr.ladder.scr_height = scr_height;
803 instrument->instr.ladder.scr_hole = hole_len;
804 instrument->instr.ladder.div_units = div_units;
805 instrument->instr.ladder.label_position = label_pos;
806 instrument->instr.ladder.width_units = width_units;
807 instrument->instr.ladder.load_roll = load_roll;
808 instrument->instr.ladder.load_pitch = load_pitch;
809 instrument->next = tmp_first;
811 hud->instruments = instrument;
816 Hptr fgHUDAddControlSurfaces( Hptr hud, int x_pos, int y_pos, double (*load_value)() )
818 struct HUD_control_surfaces *ctrl_surf;
819 struct HUD_instr *instrument;
820 HIptr tmp_first, tmp_next;
822 tmp_first = hud->instruments;
823 if( tmp_first != NULL )
824 tmp_next = tmp_first->next;
828 instrument = (HIptr)calloc(sizeof(struct HUD_instr),1);
829 if( instrument == NULL )
832 ctrl_surf = (struct HUD_control_surfaces *)calloc(sizeof(struct HUD_control_surfaces),1);
833 if( ctrl_surf == NULL )
836 instrument->type = CONTROL_SURFACES;
837 instrument->instr.control_surfaces = *ctrl_surf;
838 instrument->instr.control_surfaces.x_pos = x_pos;
839 instrument->instr.control_surfaces.y_pos = y_pos;
840 instrument->instr.horizon.load_value = load_value;
841 instrument->next = tmp_first;
843 hud->instruments = instrument;
849 Hptr fgHUDAddMovingHorizon( Hptr hud, int x_pos, int y_pos, int length, int hole_len, \
855 Hptr fgHUDAddCircularLadder( Hptr hud, int scr_min, int scr_max, int div_min, int div_max, \
861 Hptr fgHUDAddNumDisp( Hptr hud, int x_pos, int y_pos, int size, int color, int blink, \
862 char *pre_str, char *post_str )
868 void fgUpdateHUD( Hptr hud )
871 union HUD_instr_data instr_data;
873 glMatrixMode(GL_PROJECTION);
877 gluOrtho2D(0, 640, 0, 480);
878 glMatrixMode(GL_MODELVIEW);
882 glColor3f(1.0, 1.0, 1.0);
885 glDisable(GL_DEPTH_TEST);
886 glDisable(GL_LIGHTING);
889 glColor3f (0.1, 0.9, 0.1);
891 fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d Status %d\n",
892 hud->code, hud->status );
893 hud_instr = hud->instruments;
894 while( hud_instr != NULL )
896 instr_data = hud_instr->instr;
897 fgPrintf( FG_COCKPIT, FG_DEBUG,
898 "Instr Type %d SubType %d Orient %d\n",
899 hud_instr->type, hud_instr->sub_type, hud_instr->orientation );
900 if( hud_instr->type == ARTIFICIAL_HORIZON )
902 drawhorizon( instr_data.horizon );
903 /* drawhorizon( instr_data.horizon.x_pos, instr_data.horizon.y_pos, \
904 instr_data.horizon.scr_width, instr_data.horizon.scr_hole ); */
906 else if( hud_instr->type == SCALE )
908 drawscale( instr_data.scale.type, instr_data.scale.with_minimum, \
909 instr_data.scale.minimum_value, instr_data.scale.orientation, \
910 instr_data.scale.scr_pos, instr_data.scale.scr_min, \
911 instr_data.scale.scr_max, instr_data.scale.width_units, \
912 instr_data.scale.div_min, instr_data.scale.div_max, \
913 (*instr_data.scale.load_value)() );
915 else if( hud_instr->type == CONTROL_SURFACES )
917 drawcontrolsurfaces( instr_data.control_surfaces );
919 else if( hud_instr->type == LABEL )
921 drawlabel( instr_data.label );
922 /* drawlabel( instr_data.label.x_pos, instr_data.label.y_pos, instr_data.label.size, \
923 instr_data.label.blink, instr_data.label.pre_str, instr_data.label.post_str, \
924 instr_data.label.format, (*instr_data.label.load_value)() ); */
926 else if( hud_instr->type == LADDER )
928 drawladder( instr_data.ladder );
930 hud_instr = hud_instr->next;
934 glEnable(GL_DEPTH_TEST);
935 glEnable(GL_LIGHTING);
936 glMatrixMode(GL_PROJECTION);
938 glMatrixMode(GL_MODELVIEW);
945 /* Revision 1.10 1998/02/03 23:20:14 curt
946 /* Lots of little tweaks to fix various consistency problems discovered by
947 /* Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
948 /* passed arguments along to the real printf(). Also incorporated HUD changes
949 /* by Michele America.
951 * Revision 1.9 1998/01/31 00:43:04 curt
952 * Added MetroWorks patches from Carmen Volpe.
954 * Revision 1.8 1998/01/27 00:47:51 curt
955 * Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
956 * system and commandline/config file processing code.
958 * Revision 1.7 1998/01/19 18:40:20 curt
959 * Tons of little changes to clean up the code and to remove fatal errors
960 * when building with the c++ compiler.
962 * Revision 1.6 1997/12/15 23:54:34 curt
963 * Add xgl wrappers for debugging.
964 * Generate terrain normals on the fly.
966 * Revision 1.5 1997/12/10 22:37:39 curt
967 * Prepended "fg" on the name of all global structures that didn't have it yet.
968 * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
970 * Revision 1.4 1997/09/23 00:29:32 curt
971 * Tweaks to get things to compile with gcc-win32.
973 * Revision 1.3 1997/09/05 14:17:26 curt
974 * More tweaking with stars.
976 * Revision 1.2 1997/09/04 02:17:30 curt
979 * Revision 1.1 1997/08/29 18:03:22 curt