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
44 #include <simgear/constants.h>
45 #include <simgear/debug/logstream.hxx>
46 #include <simgear/misc/props.hxx>
47 //#include <simgear/math/fg_random.h>
48 //#include <simgear/math/polar3d.hxx>
50 #include <Aircraft/aircraft.hxx>
51 #include <Autopilot/newauto.hxx>
53 #include <Main/globals.hxx>
54 #include <Main/fg_props.hxx>
55 #include <Main/viewmgr.hxx>
57 #include <NetworkOLK/network.h>
59 #include <Scenery/scenery.hxx>
60 //#include <Time/fg_timer.hxx>
62 #if defined ( __sun__ ) || defined ( __sgi )
64 extern void *memmove(void *, const void *, size_t);
72 // The following routines obtain information concerning the aircraft's
73 // current state and return it to calling instrument display routines.
74 // They should eventually be member functions of the aircraft.
77 deque< instr_item * > HUD_deque;
79 fgTextList HUD_TextList;
80 fgLineList HUD_LineList;
81 fgLineList HUD_StippleLineList;
83 fntRenderer *HUDtext = 0;
84 float HUD_TextSize = 0;
88 static float hud_trans_alpha = 0.67f;
91 //$$$ begin - added, Neetha, 28 Nov 2k
99 static float span_units;
100 static float division_units;
101 static float minor_division = 0;
102 static UINT screen_hole;
105 static string loadfn;
107 static float maxValue;
108 static float minValue;
109 static float scaling;
110 static UINT major_divs;
111 static UINT minor_divs;
112 static UINT modulator;
113 static int dp_showing = 0;
114 static string label_format;
115 static string prelabel;
116 static string postlabel;
119 static float maxBankAngle;
120 static float maxSlipAngle;
121 static UINT gap_width;
122 static bool latitude;
123 static bool longitude;
124 static bool tick_bottom;
125 static bool tick_top;
126 static bool tick_right;
127 static bool tick_left;
128 static bool cap_bottom;
130 static bool cap_right;
131 static bool cap_left;
132 static float marker_off;
134 static bool enable_pointer;
135 static string type_pointer;
136 static bool frl_spot;
138 static bool vel_vector;
142 static bool climb_dive;
144 static float glide_slope_val;
145 static bool worm_energy;
146 static bool waypoint;
148 static FLTFNPTR load_fn;
149 static fgLabelJust justification;
150 static const char *pre_label_string = 0;
151 static const char *post_label_string = 0;
153 int readHud( istream &input );
154 int readInstrument ( const SGPropertyNode * node);
155 static instr_item * readLadder ( const SGPropertyNode * node);
156 static instr_item * readCard ( const SGPropertyNode * node);
157 static instr_item * readLabel( const SGPropertyNode * node);
158 static instr_item * readTBI( const SGPropertyNode * node);
159 //$$$ end - added, Neetha, 28 Nov 2k
161 void fgHUDalphaInit( void );
167 locRECT( UINT left, UINT top, UINT right, UINT bottom);
168 RECT get_rect(void) { return rect;}
171 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
176 rect.bottom = bottom;
182 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
190 void drawOneLine( RECT &rect)
193 glVertex2f(rect.left, rect.top);
194 glVertex2f(rect.right, rect.bottom);
199 // The following code deals with painting the "instrument" on the display
201 /* textString - Bitmap font string */
203 void textString( int x, int y, char *msg, void *font ){
207 // puDrawString ( NULL, msg, x, y );
210 glutBitmapCharacter(font, *msg);
217 /* strokeString - Stroke font string */
218 void strokeString(int x, int y, char *msg, void *font, float theta)
223 float sintheta,costheta;
229 glRotatef(theta * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
230 sintheta = sin(theta);
231 costheta = cos(theta);
232 xx = (int)(x * costheta + y * sintheta);
233 yy = (int)(y * costheta - x * sintheta);
234 glTranslatef( xx, yy, 0);
235 glScalef(.1, .1, 0.0);
236 while( (c=*msg++) ) {
237 glutStrokeCharacter(font, c);
243 int getStringWidth ( char *str )
245 if ( HUDtext && str )
248 guiFntHandle->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
249 return FloatToInt( r - l );
255 //========================= End of Class Implementations===================
258 // Constructs a HUD object and then adds in instruments. At the present
259 // the instruments are hard coded into the routine. Ultimately these need
260 // to be defined by the aircraft's instrumentation records so that the
261 // display for a Piper Cub doesn't show the speed range of a North American
262 // mustange and the engine readouts of a B36!
267 //$$$ begin - added, Neetha, 28 Nov 2k
269 readLadder(const SGPropertyNode * node)
274 name = node->getStringValue("name");
275 x = node->getIntValue("x");
276 y = node->getIntValue("y");
277 width = node->getIntValue("width");
278 height = node->getIntValue("height");
279 factor = node->getFloatValue("compression_factor");
280 span_units = node->getFloatValue("span_units");
281 division_units = node->getFloatValue("division_units");
282 screen_hole = node->getIntValue("screen_hole");
283 lbl_pos = node->getIntValue("lbl_pos");
284 frl_spot = node->getBoolValue("enable_frl",false);
285 target = node->getBoolValue("enable_target_spot",false);
286 vel_vector = node->getBoolValue("enable_velocity_vector",false);
287 drift = node->getBoolValue("enable_drift_marker",false);
288 alpha = node->getBoolValue("enable_alpha_bracket",false);
289 energy = node->getBoolValue("enable_energy_marker",false);
290 climb_dive = node->getBoolValue("enable_climb_dive_marker",false);
291 glide = node->getBoolValue("enable_glide_slope_marker",false);
292 glide_slope_val = node->getFloatValue("glide_slope",-4.0);
293 worm_energy = node->getBoolValue("enable_energy_marker",false);
294 waypoint = node->getBoolValue("enable_waypoint_marker",false);
295 working = node->getBoolValue("working");
297 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
300 p = (instr_item *) new HudLadder( name, x, y,
301 width, height, factor,
303 span_units, division_units, minor_division,
304 screen_hole, lbl_pos, frl_spot, target, vel_vector,
305 drift, alpha, energy, climb_dive,
306 glide, glide_slope_val, worm_energy,
314 readCard(const SGPropertyNode * node)
319 name = node->getStringValue("name");
320 x = node->getIntValue("x");
321 y = node->getIntValue("y");
322 width = node->getIntValue("width");
323 height = node->getIntValue("height");
324 loadfn = node->getStringValue("loadfn");
325 options = node->getIntValue("options");
326 maxValue = node->getFloatValue("maxValue");
327 minValue = node->getFloatValue("minValue");
328 scaling = node->getFloatValue("disp_scaling");
329 major_divs = node->getIntValue("major_divs");
330 minor_divs = node->getIntValue("minor_divs");
331 modulator = node->getIntValue("modulator");
332 span_units = node->getFloatValue("value_span");
333 type = node->getStringValue("type");
334 tick_bottom = node->getBoolValue("tick_bottom",false);
335 tick_top = node->getBoolValue("tick_top",false);
336 tick_right = node->getBoolValue("tick_right",false);
337 tick_left = node->getBoolValue("tick_left",false);
338 cap_bottom = node->getBoolValue("cap_bottom",false);
339 cap_top = node->getBoolValue("cap_top",false);
340 cap_right = node->getBoolValue("cap_right",false);
341 cap_left = node->getBoolValue("cap_left",false);
342 marker_off = node->getFloatValue("marker_offset",0.0);
343 enable_pointer = node->getBoolValue("enable_pointer",true);
344 type_pointer = node->getStringValue("pointer_type");
345 working = node->getBoolValue("working");
348 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
352 span_units = maxValue - minValue;
357 if(loadfn=="heading")
358 load_fn = get_heading;
364 load_fn = get_climb_rate;
366 if(loadfn=="altitude")
367 load_fn = get_altitude;
375 if(loadfn=="view_direction")
376 load_fn = get_view_direction;
378 if(loadfn=="aileronval")
379 load_fn = get_aileronval;
381 if(loadfn=="elevatorval")
382 load_fn = get_elevatorval;
384 if(loadfn=="rudderval")
385 load_fn = get_rudderval;
387 if(loadfn=="throttleval")
388 load_fn = get_throttleval;
391 p = (instr_item *) new hud_card( x,
399 major_divs, minor_divs,
420 readLabel(const SGPropertyNode * node)
424 int font_size = (fgGetInt("/sim/startup/xsize") > 1000) ? LARGE : SMALL;
426 name = node->getStringValue("name");
427 x = node->getIntValue("x");
428 y = node->getIntValue("y");
429 width = node->getIntValue("width");
430 height = node->getIntValue("height");
431 loadfn = node->getStringValue("data_source");
432 label_format = node->getStringValue("label_format");
433 prelabel = node->getStringValue("pre_label_string");
434 postlabel = node->getStringValue("post_label_string");
435 scaling = node->getFloatValue("scale_data");
436 options = node->getIntValue("options");
437 justi = node->getIntValue("justification");
438 blinking = node->getIntValue("blinking");
439 latitude = node->getBoolValue("latitude",false);
440 longitude = node->getBoolValue("longitude",false);
441 working = node->getBoolValue("working");
444 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
448 justification = LEFT_JUST;
451 justification = CENTER_JUST;
454 justification = RIGHT_JUST;
459 if ( prelabel == "NULL" ) {
460 pre_label_string = NULL;
462 if ( prelabel == "blank" ) {
463 pre_label_string = " ";
465 pre_label_string = prelabel.c_str();
469 if ( postlabel == "blank" ) {
470 post_label_string = " ";
472 if ( postlabel == "NULL" ) {
473 post_label_string = NULL;
475 if ( postlabel == "units" ) {
476 post_label_string = units;
478 post_label_string = postlabel.c_str();
483 if ( loadfn == "aux16" ) {
485 } else if ( loadfn == "aux17" ) {
487 } else if ( loadfn == "aux9" ) {
489 } else if ( loadfn == "aux11" ) {
491 } else if ( loadfn == "aux12" ) {
493 } else if ( loadfn == "aux10" ) {
495 } else if ( loadfn == "aux13" ) {
497 } else if ( loadfn == "aux14" ) {
499 } else if ( loadfn == "aux15" ) {
501 } else if ( loadfn == "aux8" ) {
503 } else if ( loadfn == "ax" ) {
505 } else if ( loadfn == "speed" ) {
507 } else if ( loadfn == "mach" ) {
509 } else if ( loadfn == "altitude" ) {
510 load_fn = get_altitude;
511 } else if ( loadfn == "agl" ) {
513 } else if ( loadfn == "framerate" ) {
514 load_fn = get_frame_rate;
515 } else if ( loadfn == "heading" ) {
516 load_fn = get_heading;
517 } else if ( loadfn == "fov" ) {
519 } else if ( loadfn == "vfc_tris_culled" ) {
520 load_fn = get_vfc_tris_culled;
521 } else if ( loadfn == "vfc_tris_drawn" ) {
522 load_fn = get_vfc_tris_drawn;
523 } else if ( loadfn == "aoa" ) {
525 } else if ( loadfn == "latitude" ) {
526 load_fn = get_latitude;
527 } else if ( loadfn == "longitude" ) {
528 load_fn = get_longitude;
531 p = (instr_item *) new instr_label ( x,
536 label_format.c_str(),
552 readTBI(const SGPropertyNode * node)
557 name = node->getStringValue("name");
558 x = node->getIntValue("x");
559 y = node->getIntValue("y");
560 width = node->getIntValue("width");
561 height = node->getIntValue("height");
562 maxBankAngle = node->getFloatValue("maxBankAngle");
563 maxSlipAngle = node->getFloatValue("maxSlipAngle");
564 gap_width = node->getIntValue("gap_width");
565 working = node->getBoolValue("working");
567 SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
570 p = (instr_item *) new fgTBI_instr( x,
585 int readInstrument(const SGPropertyNode * node)
590 if ( fgGetString("/sim/startup/units") == "feet" ) {
591 strcpy(units, " ft");
596 const SGPropertyNode * ladder_group = node->getNode("ladders");
598 if (ladder_group != 0) {
599 int nLadders = ladder_group->nChildren();
600 for (int j = 0; j < nLadders; j++) {
602 HIptr = readLadder(ladder_group->getChild(j));
603 HUD_deque.insert( HUD_deque.begin(), HIptr);
608 const SGPropertyNode * card_group = node->getNode("cards");
609 if (card_group != 0) {
610 int nCards = card_group->nChildren();
611 for (int j = 0; j < nCards; j++) {
613 HIptr = readCard(card_group->getChild(j));
614 HUD_deque.insert( HUD_deque.begin(), HIptr);
619 const SGPropertyNode * label_group = node->getNode("labels");
620 if (label_group != 0) {
621 int nLabels = label_group->nChildren();
622 for (int j = 0; j < nLabels; j++) {
624 HIptr = readLabel(label_group->getChild(j));
625 HUD_deque.insert( HUD_deque.begin(), HIptr);
630 const SGPropertyNode * tbi_group = node->getNode("tbis");
631 if (tbi_group != 0) {
632 int nTbis = tbi_group->nChildren();
633 for (int j = 0; j < nTbis; j++) {
635 HIptr = readTBI(tbi_group->getChild(j));
636 HUD_deque.insert( HUD_deque.begin(), HIptr);
641 }//end readinstrument
644 int readHud( istream &input )
650 readProperties(input, &root);
651 } catch (const sg_exception &e) {
652 guiErrorMessage("Error reading HUD: ", e);
657 SG_LOG(SG_INPUT, SG_INFO, "Read properties for " <<
658 root.getStringValue("name"));
661 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
664 SG_LOG(SG_INPUT, SG_INFO, "Reading Hud instruments");
666 const SGPropertyNode * instrument_group = root.getChild("instruments");
667 int nInstruments = instrument_group->nChildren();
669 for (int i = 0; i < nInstruments; i++) {
671 const SGPropertyNode * node = instrument_group->getChild(i);
673 SGPath path( globals->get_fg_root() );
674 path.append(node->getStringValue("path"));
676 SG_LOG(SG_INPUT, SG_INFO, "Reading Instrument "
682 SGPropertyNode root2;
684 readProperties(path.str(), &root2);
685 } catch (const sg_exception &e) {
686 guiErrorMessage("Error reading HUD instrument: ", e);
689 readInstrument(&root2);
696 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
702 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
705 fgGetString("/sim/hud/path", "Huds/Default/default.xml");
706 SGPath path(globals->get_fg_root());
707 path.append(hud_path);
709 ifstream input(path.c_str());
712 SG_LOG(SG_INPUT, SG_ALERT,
713 "Cannot read Hud configuration from " << path.str());
724 return 0; // For now. Later we may use this for an error code.
728 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
733 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
735 SGPath path(globals->get_fg_root());
736 path.append("Huds/Minimal/default.xml");
739 ifstream input(path.c_str());
741 SG_LOG(SG_INPUT, SG_ALERT,
742 "Cannot read Hud configuration from " << path.str());
749 return 0; // For now. Later we may use this for an error code.
752 //$$$ End - added, Neetha, 28 Nov 2k
754 static int global_day_night_switch = DAY;
756 void HUD_masterswitch( bool incr )
758 if ( fgGetBool("/sim/hud/visibility") ) {
759 if ( global_day_night_switch == DAY ) {
760 global_day_night_switch = NIGHT;
762 fgSetBool("/sim/hud/visibility", false);
765 fgSetBool("/sim/hud/visibility", true);
766 global_day_night_switch = DAY;
770 void HUD_brightkey( bool incr_bright )
772 instr_item *pHUDInstr = HUD_deque[0];
773 int brightness = pHUDInstr->get_brightness();
775 if( fgGetBool("/sim/hud/visibility") ) {
780 brightness = BRT_BLACK;
784 brightness = BRT_LIGHT;
788 brightness = BRT_MEDIUM;
792 brightness = BRT_DARK;
796 brightness = BRT_BLACK;
802 brightness = BRT_MEDIUM;
806 brightness = BRT_DARK;
810 brightness = BRT_BLACK;
814 brightness = BRT_LIGHT;
818 fgSetBool("/sim/hud/visibility", false);
822 fgSetBool("/sim/hud/visibility", true);
825 pHUDInstr->SetBrightness( brightness );
829 #define fgAP_CLAMP(val,min,max) ( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) )
831 static puDialogBox *HUDalphaDialog;
832 static puText *HUDalphaText;
833 static puSlider *HUDalphaHS0;
834 //static puText *HUDtextText;
835 //static puSlider *HUDalphaHS1;
836 static char SliderText[2][ 8 ];
838 static void alpha_adj( puObject *hs ) {
841 hs-> getValue ( &val ) ;
842 fgAP_CLAMP ( val, 0.1, 1.0 ) ;
843 // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ;
844 hud_trans_alpha = val;
845 sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
846 HUDalphaText -> setLabel ( SliderText[ 0 ] ) ;
849 void fgHUDalphaAdjust( puObject * ) {
850 fgSetBool("/sim/hud/antialiased", true);
851 FG_PUSH_PUI_DIALOG( HUDalphaDialog );
854 static void goAwayHUDalphaAdjust (puObject *)
856 FG_POP_PUI_DIALOG( HUDalphaDialog );
859 static void cancelHUDalphaAdjust (puObject *)
861 fgSetBool("/sim/hud/antialiased", false);
862 FG_POP_PUI_DIALOG( HUDalphaDialog );
865 // Done once at system initialization
866 void fgHUDalphaInit( void ) {
868 // printf("fgHUDalphaInit\n");
869 #define HORIZONTAL FALSE
873 int DialogWidth = 240;
875 char Label[] = "HUD Adjuster";
878 int labelX = (DialogWidth / 2) -
879 (puGetStringWidth( puGetDefaultLabelFont(), Label ) / 2);
884 int slider_width = 220;
885 int slider_title_x = 15;
886 int slider_value_x = 160;
887 float slider_delta = 0.05f;
889 puFont HUDalphaLegendFont;
890 puFont HUDalphaLabelFont;
891 puGetDefaultFonts ( &HUDalphaLegendFont, &HUDalphaLabelFont );
893 HUDalphaDialog = new puDialogBox ( DialogX, DialogY ); {
894 int horiz_slider_height = puGetStringHeight (HUDalphaLabelFont) +
895 puGetStringDescender (HUDalphaLabelFont) +
896 PUSTR_TGAP + PUSTR_BGAP + 5;
899 HUDalphaFrame = new puFrame ( 0, 0, DialogWidth,
901 * horiz_slider_height ); */
904 HUDalphaDialogMessage = new puText ( labelX,
906 * horiz_slider_height );
907 HUDalphaDialogMessage -> setDefaultValue ( Label );
908 HUDalphaDialogMessage -> getDefaultValue ( &s );
909 HUDalphaDialogMessage -> setLabel ( s );
911 HUDalphaHS0 = new puSlider ( slider_x, slider_y,
912 slider_width, HORIZONTAL ) ;
913 HUDalphaHS0-> setDelta ( slider_delta ) ;
914 HUDalphaHS0-> setValue ( hud_trans_alpha ) ;
915 HUDalphaHS0-> setCBMode ( PUSLIDER_DELTA ) ;
916 HUDalphaHS0-> setCallback ( alpha_adj ) ;
919 HUDalphaTitle = new puText ( slider_title_x, slider_y ) ;
920 HUDalphaTitle-> setDefaultValue ( "Alpha" ) ;
921 HUDalphaTitle-> getDefaultValue ( &s ) ;
922 HUDalphaTitle-> setLabel ( s ) ;
924 HUDalphaText = new puText ( slider_value_x, slider_y ) ;
925 sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
926 HUDalphaText-> setLabel ( SliderText[ 0 ] ) ;
929 HUDalphaOkButton = new puOneShot ( 10, 10, 60, 45 );
930 HUDalphaOkButton-> setLegend ( gui_msg_OK );
931 HUDalphaOkButton-> makeReturnDefault ( TRUE );
932 HUDalphaOkButton-> setCallback ( goAwayHUDalphaAdjust );
935 HUDalphaNoButton = new puOneShot ( 160, 10, 230, 45 );
936 HUDalphaNoButton-> setLegend ( gui_msg_CANCEL );
937 HUDalphaNoButton-> setCallback ( cancelHUDalphaAdjust );
939 FG_FINALIZE_PUI_DIALOG( HUDalphaDialog );
945 void fgHUDReshape(void) {
947 // this chunk of code is not necessarily thread safe if the
948 // compiler optimizer reorders these statements. Note that
949 // "delete ptr" does not set "ptr = NULL". We have to do that
951 fntRenderer *tmp = HUDtext;
956 HUD_TextSize = fgGetInt("/sim/startup/xsize") / 60;
958 HUDtext = new fntRenderer();
959 HUDtext -> setFont ( guiFntHandle ) ;
960 HUDtext -> setPointSize ( HUD_TextSize ) ;
961 HUD_TextList.setFont( HUDtext );
965 static void set_hud_color(float r, float g, float b) {
966 fgGetBool("/sim/hud/antialiased") ?
967 glColor4f(r,g,b,hud_trans_alpha) :
974 // Performs a once around the list of calls to instruments installed in
975 // the HUD object with requests for redraw. Kinda. It will when this is
978 void fgUpdateHUD( void ) {
980 static const float normal_aspect = float(640) / float(480);
981 // note: win_ratio is Y/X
982 float current_aspect = 1.0f/globals->get_current_view()->get_win_ratio();
983 if( current_aspect > normal_aspect ) {
984 float aspect_adjust = current_aspect / normal_aspect;
985 float adjust = 320.0f*aspect_adjust - 320.0f;
986 fgUpdateHUD( -adjust, 0.0f, 640.0f+adjust, 480.0f );
988 float aspect_adjust = normal_aspect / current_aspect;
989 float adjust = 240.0f*aspect_adjust - 240.0f;
990 fgUpdateHUD( 0.0f, -adjust, 640.0f, 480.0f+adjust );
994 void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
995 GLfloat x_end, GLfloat y_end )
998 // int day_night_sw = current_aircraft.controls->day_night_switch;
999 int day_night_sw = global_day_night_switch;
1000 int hud_displays = HUD_deque.size();
1001 instr_item *pHUDInstr;
1002 // float line_width;
1004 if( !hud_displays ) { // Trust everyone, but ALWAYS cut the cards!
1008 HUD_TextList.erase();
1009 HUD_LineList.erase();
1010 // HUD_StippleLineList.erase();
1012 pHUDInstr = HUD_deque[0];
1013 brightness = pHUDInstr->get_brightness();
1014 // brightness = HUD_deque.at(0)->get_brightness();
1016 glMatrixMode(GL_PROJECTION);
1020 gluOrtho2D(x_start, x_end, y_start, y_end);
1021 glMatrixMode(GL_MODELVIEW);
1025 glDisable(GL_DEPTH_TEST);
1026 glDisable(GL_LIGHTING);
1028 static const SGPropertyNode * antialiased_node
1029 = fgGetNode("/sim/hud/antialiased");
1031 if( antialiased_node->getBoolValue() ) {
1032 glEnable(GL_LINE_SMOOTH);
1033 // glEnable(GL_BLEND);
1034 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1035 glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
1036 // glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
1042 if( day_night_sw == DAY) {
1046 set_hud_color (0.1f, 0.9f, 0.1f);
1050 set_hud_color (0.1f, 0.7f, 0.0f);
1054 set_hud_color (0.0f, 0.6f, 0.0f);
1058 set_hud_color( 0.0f, 0.0f, 0.0f);
1062 set_hud_color (0.1f, 0.9f, 0.1f);
1065 if( day_night_sw == NIGHT) {
1069 set_hud_color (0.9f, 0.1f, 0.1f);
1073 set_hud_color (0.7f, 0.0f, 0.1f);
1077 set_hud_color (0.6f, 0.0f, 0.0f);
1081 set_hud_color( 0.0f, 0.0f, 0.0f);
1085 set_hud_color (0.6f, 0.0f, 0.0f);
1087 } else { // Just in case default
1088 set_hud_color (0.1f, 0.9f, 0.1f);
1092 deque < instr_item * > :: iterator current = HUD_deque.begin();
1093 deque < instr_item * > :: iterator last = HUD_deque.end();
1095 for ( ; current != last; ++current ) {
1096 pHUDInstr = *current;
1098 if( pHUDInstr->enabled()) {
1099 // fgPrintf( SG_COCKPIT, SG_DEBUG, "HUD Code %d Status %d\n",
1100 // hud->code, hud->status );
1106 char *gmt_str = get_formated_gmt_time();
1107 HUD_TextList.add( fgText(40, 10, gmt_str) );
1109 #ifdef FG_NETWORK_OLK
1110 if ( net_hud_display ) {
1117 // extern bool fgAPAltitudeEnabled( void );
1118 // extern bool fgAPHeadingEnabled( void );
1119 // extern bool fgAPWayPointEnabled( void );
1120 // extern char *fgAPget_TargetDistanceStr( void );
1121 // extern char *fgAPget_TargetHeadingStr( void );
1122 // extern char *fgAPget_TargetAltitudeStr( void );
1123 // extern char *fgAPget_TargetLatLonStr( void );
1126 // char scratch[128];
1127 // HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
1129 if( current_autopilot->get_HeadingEnabled() ) {
1130 HUD_TextList.add( fgText( 40, apY,
1131 current_autopilot->get_TargetHeadingStr()) );
1134 if( current_autopilot->get_AltitudeEnabled() ) {
1135 HUD_TextList.add( fgText( 40, apY,
1136 current_autopilot->get_TargetAltitudeStr()) );
1139 if( current_autopilot->get_HeadingMode() ==
1140 FGAutopilot::FG_HEADING_WAYPOINT )
1143 wpstr = current_autopilot->get_TargetWP1Str();
1144 if ( strlen( wpstr ) ) {
1145 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1148 wpstr = current_autopilot->get_TargetWP2Str();
1149 if ( strlen( wpstr ) ) {
1150 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1153 wpstr = current_autopilot->get_TargetWP3Str();
1154 if ( strlen( wpstr ) ) {
1155 HUD_TextList.add( fgText( 40, apY, wpstr ) );
1160 HUD_TextList.draw();
1162 HUD_LineList.draw();
1164 // glEnable(GL_LINE_STIPPLE);
1165 // glLineStipple( 1, 0x00FF );
1166 // HUD_StippleLineList.draw();
1167 // glDisable(GL_LINE_STIPPLE);
1169 if( antialiased_node->getBoolValue() ) {
1170 // glDisable(GL_BLEND);
1171 glDisable(GL_LINE_SMOOTH);
1175 glEnable(GL_DEPTH_TEST);
1176 glEnable(GL_LIGHTING);
1177 glMatrixMode(GL_PROJECTION);
1179 glMatrixMode(GL_MODELVIEW);