1 // hud.cxx -- hud defines and prototypes
3 // Written by Michele America, started September 1997.
5 // Copyright (C) 1997 Michele F. America - micheleamerica@geocities.com
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <simgear/compiler.h>
24 #include <simgear/misc/exception.hxx>
35 # define exception c_exception
42 #include <stdio.h> // char related functions
43 #include <string.h> // strcmp()
47 #include <simgear/constants.h>
48 #include <simgear/debug/logstream.hxx>
49 #include <simgear/misc/props.hxx>
50 #include <simgear/misc/sg_path.hxx>
51 //#include <simgear/math/fg_random.h>
52 //#include <simgear/math/polar3d.hxx>
54 #include <Aircraft/aircraft.hxx>
55 #include <Autopilot/newauto.hxx>
57 #include <Main/globals.hxx>
58 #include <Main/fg_props.hxx>
60 #include <NetworkOLK/network.h>
62 #include <Scenery/scenery.hxx>
63 //#include <Time/fg_timer.hxx>
65 #if defined ( __sun__ ) || defined ( __sgi )
67 extern void *memmove(void *, const void *, size_t);
75 // The following routines obtain information concerning the aircraft's
76 // current state and return it to calling instrument display routines.
77 // They should eventually be member functions of the aircraft.
80 deque< instr_item * > HUD_deque;
82 fgTextList HUD_TextList;
83 fgLineList HUD_LineList;
84 fgLineList HUD_StippleLineList;
86 fntRenderer *HUDtext = 0;
87 float HUD_TextSize = 0;
91 static float hud_trans_alpha = 0.67f;
94 //$$$ begin - added, Neetha, 28 Nov 2k
102 static float span_units;
103 static float division_units;
104 static float minor_division = 0;
105 static UINT screen_hole;
108 static string loadfn;
110 static float maxValue;
111 static float minValue;
112 static float scaling;
113 static UINT major_divs;
114 static UINT minor_divs;
115 static UINT modulator;
116 static int dp_showing = 0;
117 static string label_format;
118 static string prelabel;
119 static string postlabel;
122 static float maxBankAngle;
123 static float maxSlipAngle;
124 static UINT gap_width;
125 static bool latitude;
126 static bool longitude;
127 static bool tick_bottom;
128 static bool tick_top;
129 static bool tick_right;
130 static bool tick_left;
131 static bool cap_bottom;
133 static bool cap_right;
134 static bool cap_left;
135 static float marker_off;
137 static bool enable_pointer;
138 static string type_pointer;
139 static bool frl_spot;
141 static bool vel_vector;
145 static bool climb_dive;
147 static float glide_slope_val;
148 static bool worm_energy;
149 static bool waypoint;
150 static string type_tick;//hud
151 static string length_tick;//hud
152 static bool label_box;//hud
153 static int digits; //suma
154 static float radius; //suma
155 static int divisions; //suma
156 static int zoom; //suma
157 static int zenith; //suma
158 static int nadir ; //suma
159 static int hat; //suma
160 static bool tsi; //suma
161 static float rad; //suma
164 static FLTFNPTR load_fn;
165 static fgLabelJust justification;
166 static const char *pre_label_string = 0;
167 static const char *post_label_string = 0;
169 int readHud( istream &input );
170 int readInstrument ( const SGPropertyNode * node);
171 static instr_item * readLadder ( const SGPropertyNode * node);
172 static instr_item * readCard ( const SGPropertyNode * node);
173 static instr_item * readLabel( const SGPropertyNode * node);
174 static instr_item * readTBI( const SGPropertyNode * node);
175 //$$$ end - added, Neetha, 28 Nov 2k
177 void fgHUDalphaInit( void );
183 locRECT( UINT left, UINT top, UINT right, UINT bottom);
184 RECT get_rect(void) { return rect;}
187 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
192 rect.bottom = bottom;
198 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
206 void drawOneLine( RECT &rect)
209 glVertex2f(rect.left, rect.top);
210 glVertex2f(rect.right, rect.bottom);
215 // The following code deals with painting the "instrument" on the display
217 /* textString - Bitmap font string */
219 void textString( int x, int y, char *msg, void *font,int digit) //suma
223 // puDrawString ( NULL, msg, x, y );
226 glutBitmapCharacter(font, *msg);
233 /* strokeString - Stroke font string */
234 void strokeString(int x, int y, char *msg, void *font, float theta)
239 float sintheta,costheta;
244 glRotatef(theta * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
245 sintheta = sin(theta);
246 costheta = cos(theta);
247 xx = (int)(x * costheta + y * sintheta);
248 yy = (int)(y * costheta - x * sintheta);
249 glTranslatef( xx, yy, 0);
250 glScalef(.1, .1, 0.0);
251 while( (c=*msg++) ) {
252 glutStrokeCharacter(font, c);
258 int getStringWidth ( char *str )
260 if ( HUDtext && str ) {
262 guiFntHandle->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
263 return FloatToInt( r - l );
269 //========================= End of Class Implementations===================
272 // Constructs a HUD object and then adds in instruments. At the present
273 // the instruments are hard coded into the routine. Ultimately these need
274 // to be defined by the aircraft's instrumentation records so that the
275 // display for a Piper Cub doesn't show the speed range of a North American
276 // mustange and the engine readouts of a B36!
281 //$$$ begin - added, Neetha, 28 Nov 2k
283 readLadder(const SGPropertyNode * node)
288 name = node->getStringValue("name");
289 x = node->getIntValue("x");
290 y = node->getIntValue("y");
291 width = node->getIntValue("width");
292 height = node->getIntValue("height");
293 factor = node->getFloatValue("compression_factor");
294 span_units = node->getFloatValue("span_units");
295 division_units = node->getFloatValue("division_units");
296 screen_hole = node->getIntValue("screen_hole");
297 lbl_pos = node->getIntValue("lbl_pos");
298 frl_spot = node->getBoolValue("enable_frl",false);
299 target = node->getBoolValue("enable_target_spot",false);
300 vel_vector = node->getBoolValue("enable_velocity_vector",false);
301 drift = node->getBoolValue("enable_drift_marker",false);
302 alpha = node->getBoolValue("enable_alpha_bracket",false);
303 energy = node->getBoolValue("enable_energy_marker",false);
304 climb_dive = node->getBoolValue("enable_climb_dive_marker",false);
305 glide = node->getBoolValue("enable_glide_slope_marker",false);
306 glide_slope_val = node->getFloatValue("glide_slope",-4.0);
307 worm_energy = node->getBoolValue("enable_energy_marker",false);
308 waypoint = node->getBoolValue("enable_waypoint_marker",false);
309 working = node->getBoolValue("working");
310 zenith = node->getIntValue("zenith"); //suma
311 nadir = node->getIntValue("nadir"); //suma
312 hat = node->getIntValue("hat");
315 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
318 p = (instr_item *) new HudLadder( name, x, y,
319 width, height, factor,
321 span_units, division_units, minor_division,
322 screen_hole, lbl_pos, frl_spot, target, vel_vector,
323 drift, alpha, energy, climb_dive,
324 glide, glide_slope_val, worm_energy,
325 waypoint, working, zenith, nadir, hat);
332 readCard(const SGPropertyNode * node)
337 name = node->getStringValue("name");
338 x = node->getIntValue("x");
339 y = node->getIntValue("y");
340 width = node->getIntValue("width");
341 height = node->getIntValue("height");
342 loadfn = node->getStringValue("loadfn");
343 options = node->getIntValue("options");
344 maxValue = node->getFloatValue("maxValue");
345 minValue = node->getFloatValue("minValue");
346 scaling = node->getFloatValue("disp_scaling");
347 major_divs = node->getIntValue("major_divs");
348 minor_divs = node->getIntValue("minor_divs");
349 modulator = node->getIntValue("modulator");
350 span_units = node->getFloatValue("value_span");
351 type = node->getStringValue("type");
352 tick_bottom = node->getBoolValue("tick_bottom",false);
353 tick_top = node->getBoolValue("tick_top",false);
354 tick_right = node->getBoolValue("tick_right",false);
355 tick_left = node->getBoolValue("tick_left",false);
356 cap_bottom = node->getBoolValue("cap_bottom",false);
357 cap_top = node->getBoolValue("cap_top",false);
358 cap_right = node->getBoolValue("cap_right",false);
359 cap_left = node->getBoolValue("cap_left",false);
360 marker_off = node->getFloatValue("marker_offset",0.0);
361 enable_pointer = node->getBoolValue("enable_pointer",true);
362 type_pointer = node->getStringValue("pointer_type");
363 type_tick = node->getStringValue("tick_type");//hud Can be 'circle' or 'line'
364 length_tick = node->getStringValue("tick_length");//hud For variable length
365 working = node->getBoolValue("working");
366 radius = node->getFloatValue("radius"); //suma
367 divisions = node->getIntValue("divisions"); //suma
368 zoom = node->getIntValue("zoom"); //suma
370 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
374 span_units = maxValue - minValue;
377 if (loadfn=="anzg") {
379 } else if (loadfn=="heading") {
380 load_fn = get_heading;
381 } else if (loadfn=="aoa") {
383 } else if (loadfn=="climb") {
384 load_fn = get_climb_rate;
385 } else if (loadfn=="altitude") {
386 load_fn = get_altitude;
387 } else if (loadfn=="agl") {
389 } else if (loadfn=="speed") {
391 } else if (loadfn=="view_direction") {
392 load_fn = get_view_direction;
393 } else if (loadfn=="aileronval") {
394 load_fn = get_aileronval;
395 } else if (loadfn=="elevatorval") {
396 load_fn = get_elevatorval;
397 } else if (loadfn=="elevatortrimval") {
398 load_fn = get_elev_trimval;
399 } else if (loadfn=="rudderval") {
400 load_fn = get_rudderval;
401 } else if (loadfn=="throttleval") {
402 load_fn = get_throttleval;
406 if ( (type == "dial") | (type == "tape") ) {
407 p = (instr_item *) new hud_card( x,
415 major_divs, minor_divs,
439 p = (instr_item *) new gauge_instr( x, // x
443 load_fn, // data source
447 major_divs, minor_divs,
457 readLabel(const SGPropertyNode * node)
461 int font_size = (fgGetInt("/sim/startup/xsize") > 1000) ? HUD_FONT_LARGE : HUD_FONT_SMALL;
463 name = node->getStringValue("name");
464 x = node->getIntValue("x");
465 y = node->getIntValue("y");
466 width = node->getIntValue("width");
467 height = node->getIntValue("height");
468 loadfn = node->getStringValue("data_source");
469 label_format = node->getStringValue("label_format");
470 prelabel = node->getStringValue("pre_label_string");
471 postlabel = node->getStringValue("post_label_string");
472 scaling = node->getFloatValue("scale_data");
473 options = node->getIntValue("options");
474 justi = node->getIntValue("justification");
475 blinking = node->getIntValue("blinking");
476 latitude = node->getBoolValue("latitude",false);
477 longitude = node->getBoolValue("longitude",false);
478 label_box = node->getBoolValue("label_box",false);//hud
479 working = node->getBoolValue("working");
480 digits = node->getIntValue("digits"); //suma
483 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
487 justification = LEFT_JUST;
490 justification = CENTER_JUST;
493 justification = RIGHT_JUST;
498 if ( prelabel == "NULL" ) {
499 pre_label_string = NULL;
501 if ( prelabel == "blank" ) {
502 pre_label_string = " ";
504 pre_label_string = prelabel.c_str();
508 if ( postlabel == "blank" ) {
509 post_label_string = " ";
511 if ( postlabel == "NULL" ) {
512 post_label_string = NULL;
514 if ( postlabel == "units" ) {
515 post_label_string = units;
517 post_label_string = postlabel.c_str();
522 if ( loadfn== "aux1" ) {
524 } else if ( loadfn == "aux2" ) {
526 } else if ( loadfn == "aux3" ) {
528 } else if ( loadfn == "aux4" ) {
530 } else if ( loadfn == "aux5" ) {
532 } else if ( loadfn == "aux6" ) {
534 } else if ( loadfn == "aux7" ) {
536 } else if ( loadfn == "aux8" ) {
538 } else if ( loadfn == "aux9" ) {
540 } else if ( loadfn == "aux10" ) {
542 } else if ( loadfn == "aux11" ) {
544 } else if ( loadfn == "aux12" ) {
546 } else if ( loadfn == "aux13" ) {
548 } else if ( loadfn == "aux14" ) {
550 } else if ( loadfn == "aux15" ) {
552 } else if ( loadfn == "aux16" ) {
554 } else if ( loadfn == "aux17" ) {
556 } else if ( loadfn == "aux18" ) {
558 } else if ( loadfn == "ax" ) {
560 } else if ( loadfn == "speed" ) {
562 } else if ( loadfn == "mach" ) {
564 } else if ( loadfn == "altitude" ) {
565 load_fn = get_altitude;
566 } else if ( loadfn == "agl" ) {
568 } else if ( loadfn == "framerate" ) {
569 load_fn = get_frame_rate;
570 } else if ( loadfn == "heading" ) {
571 load_fn = get_heading;
572 } else if ( loadfn == "fov" ) {
574 } else if ( loadfn == "vfc_tris_culled" ) {
575 load_fn = get_vfc_tris_culled;
576 } else if ( loadfn == "vfc_tris_drawn" ) {
577 load_fn = get_vfc_tris_drawn;
578 } else if ( loadfn == "aoa" ) {
580 } else if ( loadfn == "latitude" ) {
581 load_fn = get_latitude;
582 } else if ( loadfn == "anzg" ) {
584 } else if ( loadfn == "longitude" ) {
585 load_fn = get_longitude;
586 } else if (loadfn=="throttleval") {
587 load_fn = get_throttleval;
590 p = (instr_item *) new instr_label ( x,
595 label_format.c_str(),
613 readTBI(const SGPropertyNode * node)
618 name = node->getStringValue("name");
619 x = node->getIntValue("x");
620 y = node->getIntValue("y");
621 width = node->getIntValue("width");
622 height = node->getIntValue("height");
623 maxBankAngle = node->getFloatValue("maxBankAngle");
624 maxSlipAngle = node->getFloatValue("maxSlipAngle");
625 gap_width = node->getIntValue("gap_width");
626 working = node->getBoolValue("working");
627 tsi = node->getBoolValue("tsi"); //suma
628 rad = node->getFloatValue("rad"); //suma
630 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
633 p = (instr_item *) new fgTBI_instr( x,
650 int readInstrument(const SGPropertyNode * node)
652 static const SGPropertyNode *startup_units_node
653 = fgGetNode("/sim/startup/units");
657 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
658 strcpy(units, " ft");
663 const SGPropertyNode * ladder_group = node->getNode("ladders");
665 if (ladder_group != 0) {
666 int nLadders = ladder_group->nChildren();
667 for (int j = 0; j < nLadders; j++) {
669 HIptr = readLadder(ladder_group->getChild(j));
670 HUD_deque.insert( HUD_deque.begin(), HIptr);
675 const SGPropertyNode * card_group = node->getNode("cards");
676 if (card_group != 0) {
677 int nCards = card_group->nChildren();
678 for (int j = 0; j < nCards; j++) {
680 HIptr = readCard(card_group->getChild(j));
681 HUD_deque.insert( HUD_deque.begin(), HIptr);
686 const SGPropertyNode * label_group = node->getNode("labels");
687 if (label_group != 0) {
688 int nLabels = label_group->nChildren();
689 for (int j = 0; j < nLabels; j++) {
691 HIptr = readLabel(label_group->getChild(j));
692 HUD_deque.insert( HUD_deque.begin(), HIptr);
697 const SGPropertyNode * tbi_group = node->getNode("tbis");
698 if (tbi_group != 0) {
699 int nTbis = tbi_group->nChildren();
700 for (int j = 0; j < nTbis; j++) {
702 HIptr = readTBI(tbi_group->getChild(j));
703 HUD_deque.insert( HUD_deque.begin(), HIptr);
708 }//end readinstrument
711 int readHud( istream &input )
717 readProperties(input, &root);
718 } catch (const sg_exception &e) {
719 guiErrorMessage("Error reading HUD: ", e);
724 SG_LOG(SG_INPUT, SG_INFO, "Read properties for " <<
725 root.getStringValue("name"));
728 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
731 SG_LOG(SG_INPUT, SG_INFO, "Reading Hud instruments");
733 const SGPropertyNode * instrument_group = root.getChild("instruments");
734 int nInstruments = instrument_group->nChildren();
736 for (int i = 0; i < nInstruments; i++) {
738 const SGPropertyNode * node = instrument_group->getChild(i);
740 SGPath path( globals->get_fg_root() );
741 path.append(node->getStringValue("path"));
743 SG_LOG(SG_INPUT, SG_INFO, "Reading Instrument "
749 SGPropertyNode root2;
751 readProperties(path.str(), &root2);
752 } catch (const sg_exception &e) {
753 guiErrorMessage("Error reading HUD instrument: ", e);
756 readInstrument(&root2);
763 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
769 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
772 fgGetString("/sim/hud/path", "Huds/Default/default.xml");
773 SGPath path(globals->get_fg_root());
774 path.append(hud_path);
776 ifstream input(path.c_str());
778 SG_LOG(SG_INPUT, SG_ALERT,
779 "Cannot read Hud configuration from " << path.str());
788 return 0; // For now. Later we may use this for an error code.
792 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
797 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
799 SGPath path(globals->get_fg_root());
800 path.append("Huds/Minimal/default.xml");
803 ifstream input(path.c_str());
805 SG_LOG(SG_INPUT, SG_ALERT,
806 "Cannot read Hud configuration from " << path.str());
812 return 0; // For now. Later we may use this for an error code.
815 //$$$ End - added, Neetha, 28 Nov 2k
817 static int global_day_night_switch = HUD_DAY;
819 void HUD_masterswitch( bool incr )
821 if ( fgGetBool("/sim/hud/visibility") ) {
822 if ( global_day_night_switch == HUD_DAY ) {
823 global_day_night_switch = HUD_NIGHT;
825 fgSetBool("/sim/hud/visibility", false);
828 fgSetBool("/sim/hud/visibility", true);
829 global_day_night_switch = HUD_DAY;
833 void HUD_brightkey( bool incr_bright )
835 instr_item *pHUDInstr = HUD_deque[0];
836 int brightness = pHUDInstr->get_brightness();
838 if( fgGetBool("/sim/hud/visibility") ) {
843 brightness = HUD_BRT_BLACK;
847 brightness = HUD_BRT_LIGHT;
851 brightness = HUD_BRT_MEDIUM;
855 brightness = HUD_BRT_DARK;
859 brightness = HUD_BRT_BLACK;
865 brightness = HUD_BRT_MEDIUM;
869 brightness = HUD_BRT_DARK;
873 brightness = HUD_BRT_BLACK;
877 brightness = HUD_BRT_LIGHT;
881 fgSetBool("/sim/hud/visibility", false);
885 fgSetBool("/sim/hud/visibility", true);
888 pHUDInstr->SetBrightness( brightness );
892 #define fgAP_CLAMP(val,min,max) ( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) )
894 static puDialogBox *HUDalphaDialog;
895 static puText *HUDalphaText;
896 static puSlider *HUDalphaHS0;
897 //static puText *HUDtextText;
898 //static puSlider *HUDalphaHS1;
899 static char SliderText[2][ 8 ];
901 static void alpha_adj( puObject *hs ) {
904 hs-> getValue ( &val ) ;
905 fgAP_CLAMP ( val, 0.1, 1.0 ) ;
906 // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ;
907 hud_trans_alpha = val;
908 sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
909 HUDalphaText -> setLabel ( SliderText[ 0 ] ) ;
912 void fgHUDalphaAdjust( puObject * ) {
913 fgSetBool("/sim/hud/antialiased", true);
914 FG_PUSH_PUI_DIALOG( HUDalphaDialog );
917 static void goAwayHUDalphaAdjust (puObject *)
919 FG_POP_PUI_DIALOG( HUDalphaDialog );
922 static void cancelHUDalphaAdjust (puObject *)
924 fgSetBool("/sim/hud/antialiased", false);
925 FG_POP_PUI_DIALOG( HUDalphaDialog );
928 // Done once at system initialization
929 void fgHUDalphaInit( void ) {
931 // printf("fgHUDalphaInit\n");
932 #define HORIZONTAL FALSE
936 int DialogWidth = 240;
938 char Label[] = "HUD Adjuster";
941 int labelX = (DialogWidth / 2) -
942 ( puGetDefaultLabelFont().getStringWidth( Label ) / 2);
947 int slider_width = 220;
948 int slider_title_x = 15;
949 int slider_value_x = 160;
950 float slider_delta = 0.05f;
952 puFont HUDalphaLegendFont;
953 puFont HUDalphaLabelFont;
954 puGetDefaultFonts ( &HUDalphaLegendFont, &HUDalphaLabelFont );
956 HUDalphaDialog = new puDialogBox ( DialogX, DialogY ); {
957 int horiz_slider_height = HUDalphaLabelFont.getStringHeight() +
958 HUDalphaLabelFont.getStringDescender() +
959 PUSTR_TGAP + PUSTR_BGAP + 5;
962 HUDalphaFrame = new puFrame ( 0, 0, DialogWidth,
964 * horiz_slider_height ); */
967 HUDalphaDialogMessage = new puText ( labelX,
969 * horiz_slider_height );
970 HUDalphaDialogMessage -> setDefaultValue ( Label );
971 HUDalphaDialogMessage -> getDefaultValue ( &s );
972 HUDalphaDialogMessage -> setLabel ( s );
974 HUDalphaHS0 = new puSlider ( slider_x, slider_y,
975 slider_width, HORIZONTAL ) ;
976 HUDalphaHS0-> setDelta ( slider_delta ) ;
977 HUDalphaHS0-> setValue ( hud_trans_alpha ) ;
978 HUDalphaHS0-> setCBMode ( PUSLIDER_DELTA ) ;
979 HUDalphaHS0-> setCallback ( alpha_adj ) ;
982 HUDalphaTitle = new puText ( slider_title_x, slider_y ) ;
983 HUDalphaTitle-> setDefaultValue ( "Alpha" ) ;
984 HUDalphaTitle-> getDefaultValue ( &s ) ;
985 HUDalphaTitle-> setLabel ( s ) ;
987 HUDalphaText = new puText ( slider_value_x, slider_y ) ;
988 sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
989 HUDalphaText-> setLabel ( SliderText[ 0 ] ) ;
992 HUDalphaOkButton = new puOneShot ( 10, 10, 60, 45 );
993 HUDalphaOkButton-> setLegend ( gui_msg_OK );
994 HUDalphaOkButton-> makeReturnDefault ( TRUE );
995 HUDalphaOkButton-> setCallback ( goAwayHUDalphaAdjust );
998 HUDalphaNoButton = new puOneShot ( 160, 10, 230, 45 );
999 HUDalphaNoButton-> setLegend ( gui_msg_CANCEL );
1000 HUDalphaNoButton-> setCallback ( cancelHUDalphaAdjust );
1002 FG_FINALIZE_PUI_DIALOG( HUDalphaDialog );
1008 void fgHUDReshape(void) {
1010 // this chunk of code is not necessarily thread safe if the
1011 // compiler optimizer reorders these statements. Note that
1012 // "delete ptr" does not set "ptr = NULL". We have to do that
1014 fntRenderer *tmp = HUDtext;
1019 HUD_TextSize = fgGetInt("/sim/startup/xsize") / 60;
1021 HUDtext = new fntRenderer();
1022 HUDtext -> setFont ( guiFntHandle ) ;
1023 HUDtext -> setPointSize ( HUD_TextSize ) ;
1024 HUD_TextList.setFont( HUDtext );
1028 static void set_hud_color(float r, float g, float b) {
1029 fgGetBool("/sim/hud/antialiased") ?
1030 glColor4f(r,g,b,hud_trans_alpha) :
1037 // Performs a once around the list of calls to instruments installed in
1038 // the HUD object with requests for redraw. Kinda. It will when this is
1041 void fgUpdateHUD( void ) {
1043 static const float normal_aspect = float(640) / float(480);
1044 // note: aspect_ratio is Y/X
1045 float current_aspect = 1.0f/globals->get_current_view()->get_aspect_ratio();
1046 if( current_aspect > normal_aspect ) {
1047 float aspect_adjust = current_aspect / normal_aspect;
1048 float adjust = 320.0f*aspect_adjust - 320.0f;
1049 fgUpdateHUD( -adjust, 0.0f, 640.0f+adjust, 480.0f );
1051 float aspect_adjust = normal_aspect / current_aspect;
1052 float adjust = 240.0f*aspect_adjust - 240.0f;
1053 fgUpdateHUD( 0.0f, -adjust, 640.0f, 480.0f+adjust );
1057 void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
1058 GLfloat x_end, GLfloat y_end )
1061 // int day_night_sw = current_aircraft.controls->day_night_switch;
1062 int day_night_sw = global_day_night_switch;
1063 int hud_displays = HUD_deque.size();
1064 instr_item *pHUDInstr;
1065 // float line_width;
1067 if( !hud_displays ) { // Trust everyone, but ALWAYS cut the cards!
1071 HUD_TextList.erase();
1072 HUD_LineList.erase();
1073 // HUD_StippleLineList.erase();
1075 pHUDInstr = HUD_deque[0];
1076 brightness = pHUDInstr->get_brightness();
1077 // brightness = HUD_deque.at(0)->get_brightness();
1079 glMatrixMode(GL_PROJECTION);
1083 gluOrtho2D(x_start, x_end, y_start, y_end);
1084 glMatrixMode(GL_MODELVIEW);
1088 glDisable(GL_DEPTH_TEST);
1089 glDisable(GL_LIGHTING);
1091 static const SGPropertyNode * antialiased_node
1092 = fgGetNode("/sim/hud/antialiased");
1094 if( antialiased_node->getBoolValue() ) {
1095 glEnable(GL_LINE_SMOOTH);
1096 // glEnable(GL_BLEND);
1097 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1098 glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
1104 if( day_night_sw == HUD_DAY) {
1108 set_hud_color (0.1f, 0.9f, 0.1f);
1111 case HUD_BRT_MEDIUM:
1112 set_hud_color (0.1f, 0.7f, 0.0f);
1116 set_hud_color (0.0f, 0.6f, 0.0f);
1120 set_hud_color( 0.0f, 0.0f, 0.0f);
1124 set_hud_color (0.1f, 0.9f, 0.1f);
1127 if( day_night_sw == HUD_NIGHT) {
1131 set_hud_color (0.9f, 0.1f, 0.1f);
1134 case HUD_BRT_MEDIUM:
1135 set_hud_color (0.7f, 0.0f, 0.1f);
1139 set_hud_color (0.6f, 0.0f, 0.0f);
1143 set_hud_color( 0.0f, 0.0f, 0.0f);
1147 set_hud_color (0.6f, 0.0f, 0.0f);
1149 } else { // Just in case default
1150 set_hud_color (0.1f, 0.9f, 0.1f);
1154 deque < instr_item * > :: iterator current = HUD_deque.begin();
1155 deque < instr_item * > :: iterator last = HUD_deque.end();
1157 for ( ; current != last; ++current ) {
1158 pHUDInstr = *current;
1160 if( pHUDInstr->enabled()) {
1161 // fgPrintf( SG_COCKPIT, SG_DEBUG, "HUD Code %d Status %d\n",
1162 // hud->code, hud->status );
1168 char *gmt_str = get_formated_gmt_time();
1169 HUD_TextList.add( fgText(40, 10, gmt_str, 0) );
1171 #ifdef FG_NETWORK_OLK
1172 if ( net_hud_display ) {
1179 // extern bool fgAPAltitudeEnabled( void );
1180 // extern bool fgAPHeadingEnabled( void );
1181 // extern bool fgAPWayPointEnabled( void );
1182 // extern char *fgAPget_TargetDistanceStr( void );
1183 // extern char *fgAPget_TargetHeadingStr( void );
1184 // extern char *fgAPget_TargetAltitudeStr( void );
1185 // extern char *fgAPget_TargetLatLonStr( void );
1188 // char scratch[128];
1189 // HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
1191 if( globals->get_autopilot()->get_HeadingEnabled() ) {
1192 HUD_TextList.add( fgText( 40, apY,
1193 globals->get_autopilot()->get_TargetHeadingStr()) );
1196 if( globals->get_autopilot()->get_AltitudeEnabled() ) {
1197 HUD_TextList.add( fgText( 40, apY,
1198 globals->get_autopilot()->get_TargetAltitudeStr()) );
1201 if( globals->get_autopilot()->get_HeadingMode() ==
1202 FGAutopilot::FG_HEADING_WAYPOINT )
1205 wpstr = globals->get_autopilot()->get_TargetWP1Str();
1206 if ( strlen( wpstr ) ) {
1207 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1210 wpstr = globals->get_autopilot()->get_TargetWP2Str();
1211 if ( strlen( wpstr ) ) {
1212 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1215 wpstr = globals->get_autopilot()->get_TargetWP3Str();
1216 if ( strlen( wpstr ) ) {
1217 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1222 HUD_TextList.draw();
1224 HUD_LineList.draw();
1226 // glEnable(GL_LINE_STIPPLE);
1227 // glLineStipple( 1, 0x00FF );
1228 // HUD_StippleLineList.draw();
1229 // glDisable(GL_LINE_STIPPLE);
1231 if( antialiased_node->getBoolValue() ) {
1232 // glDisable(GL_BLEND);
1233 glDisable(GL_LINE_SMOOTH);
1237 glEnable(GL_DEPTH_TEST);
1238 glEnable(GL_LIGHTING);
1239 glMatrixMode(GL_PROJECTION);
1241 glMatrixMode(GL_MODELVIEW);