]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud.cxx
17082b83012973c67f0e0bde0586798113955245
[flightgear.git] / src / Cockpit / hud.cxx
1 // hud.cxx -- hud defines and prototypes
2 //
3 // Written by Michele America, started September 1997.
4 //
5 // Copyright (C) 1997  Michele F. America  - micheleamerica@geocities.com
6 //
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.
11 //
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.
16 //
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.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H
29 #  include <windows.h>
30 #endif
31
32 #ifdef __BORLANDC__
33 #  define exception c_exception
34 #endif
35 #include <math.h>
36
37 #include <GL/glut.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <fstream.h>
41
42 #include <simgear/constants.h>
43 #include <simgear/debug/logstream.hxx>
44 #include <simgear/misc/props.hxx>
45 //#include <simgear/math/fg_random.h>
46 //#include <simgear/math/polar3d.hxx>
47
48 #include <Aircraft/aircraft.hxx>
49 #include <Autopilot/newauto.hxx>
50 #include <GUI/gui.h>
51 #include <Main/globals.hxx>
52 #ifdef FG_NETWORK_OLK
53 #include <NetworkOLK/network.h>
54 #endif
55 #include <Scenery/scenery.hxx>
56 //#include <Time/fg_timer.hxx>
57
58 #if defined ( __sun__ ) || defined ( __sgi )
59 extern "C" {
60   extern void *memmove(void *, const void *, size_t);
61 }
62 #endif
63
64 #include "hud.hxx"
65
66 static char units[5];
67
68 // The following routines obtain information concerning the aircraft's
69 // current state and return it to calling instrument display routines.
70 // They should eventually be member functions of the aircraft.
71 //
72
73 deque< instr_item * > HUD_deque;
74
75 fgTextList         HUD_TextList;
76 fgLineList         HUD_LineList;
77 fgLineList         HUD_StippleLineList;
78
79 fntRenderer *HUDtext = 0;
80 float  HUD_TextSize = 0;
81 int HUD_style = 0;
82
83 float HUD_matrix[16];
84 static float hud_trans_alpha = 0.67f;
85
86
87 //$$$ begin - added, Neetha, 28 Nov 2k
88
89 static string   name;
90 static int              x;
91 static int              y;
92 static UINT    width;
93 static UINT    height;
94 static float    factor;
95 static float   span_units;
96 static float   division_units;
97 static float   minor_division = 0;
98 static UINT    screen_hole;
99 static UINT    lbl_pos;
100 static bool    working;
101 static string  loadfn;
102 static UINT     options;
103 static float   maxValue;
104 static float   minValue;
105 static float   scaling;
106 static UINT    major_divs;
107 static UINT    minor_divs;
108 static UINT    modulator;
109 static int     dp_showing = 0;
110 static string  label_format;
111 static string  prelabel;
112 static string  postlabel;
113 static int     justi;
114 static int              blinking;
115 static float   maxBankAngle;
116 static float   maxSlipAngle;
117 static UINT    gap_width;
118 static bool     latitude;
119 static bool     longitude;
120 static bool     tick_bottom;
121 static bool     tick_top;
122 static bool     tick_right;
123 static bool     tick_left;
124 static bool     cap_bottom;
125 static bool     cap_top;
126 static bool     cap_right;
127 static bool     cap_left;
128 static float   marker_off;
129 static string  type;
130 static bool    enable_pointer;
131 static string  type_pointer;
132 static bool    frl_spot;
133 static bool     target;
134 static bool    vel_vector;
135 static bool    drift;
136 static bool    alpha;
137 static bool     energy;
138 static bool     climb_dive;
139 static bool     glide;
140 static float    glide_slope_val;
141 static bool     worm_energy;
142 static bool     waypoint;
143
144 static FLTFNPTR load_fn;    
145 static fgLabelJust justification;
146 static const char *pre_label_string  = 0;
147 static const char *post_label_string = 0;
148
149 int readHud( istream &input );
150 int readInstrument ( const SGPropertyNode * node);
151 static instr_item * readLadder ( const SGPropertyNode * node);
152 static instr_item * readCard ( const SGPropertyNode * node);
153 static instr_item * readLabel( const SGPropertyNode * node);
154 static instr_item * readTBI( const SGPropertyNode * node);
155 //$$$ end   - added, Neetha, 28 Nov 2k
156
157 void fgHUDalphaInit( void );
158
159 class locRECT {
160   public:
161     RECT rect;
162
163     locRECT( UINT left, UINT top, UINT right, UINT bottom);
164     RECT get_rect(void) { return rect;}
165 };
166
167 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
168 {
169   rect.left   =  left;
170   rect.top    =  top;
171   rect.right  =  right;
172   rect.bottom =  bottom;
173
174 }
175 // #define DEBUG
176
177 #ifdef OLD_CODE
178 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
179 {
180   glBegin(GL_LINES);
181   glVertex2f(x1, y1);
182   glVertex2f(x2, y2);
183   glEnd();
184 }
185
186 void drawOneLine( RECT &rect)
187 {
188   glBegin(GL_LINES);
189   glVertex2f(rect.left, rect.top);
190   glVertex2f(rect.right, rect.bottom);
191   glEnd();
192 }
193
194 //
195 // The following code deals with painting the "instrument" on the display
196 //
197    /* textString - Bitmap font string */
198
199 void textString( int x, int y, char *msg, void *font ){
200
201     if(*msg)
202     {
203 //      puDrawString (  NULL, msg, x, y );
204         glRasterPos2f(x, y);
205         while (*msg) {
206             glutBitmapCharacter(font, *msg);
207             msg++;
208         }
209     }
210 }
211
212
213 /* strokeString - Stroke font string */
214 void strokeString(int x, int y, char *msg, void *font, float theta)
215 {
216     int xx;
217     int yy;
218     int c;
219     float sintheta,costheta;
220     
221
222     if(*msg)
223     {
224     glPushMatrix();
225     glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
226     sintheta = sin(theta);
227     costheta = cos(theta);
228     xx = (int)(x * costheta + y * sintheta);
229     yy = (int)(y * costheta - x * sintheta);
230     glTranslatef( xx, yy, 0);
231     glScalef(.1, .1, 0.0);
232     while( (c=*msg++) ) {
233         glutStrokeCharacter(font, c);
234     }
235     glPopMatrix();
236     }
237 }
238
239 int getStringWidth ( char *str )
240 {
241     if ( HUDtext && str )
242     {
243         float r, l ;
244         guiFntHandle->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
245         return FloatToInt( r - l );
246     }
247     return 0 ;
248 }
249 #endif // OLD_CODE
250
251 //========================= End of Class Implementations===================
252 // fgHUDInit
253 //
254 // Constructs a HUD object and then adds in instruments. At the present
255 // the instruments are hard coded into the routine. Ultimately these need
256 // to be defined by the aircraft's instrumentation records so that the
257 // display for a Piper Cub doesn't show the speed range of a North American
258 // mustange and the engine readouts of a B36!
259 //
260
261 #define INSTRDEFS 21
262
263 //$$$ begin - added, Neetha, 28 Nov 2k
264 static instr_item * 
265 readLadder(const SGPropertyNode * node)
266 {
267
268         instr_item *p;
269
270                                 name                    = node->getStringValue("name");
271                                 x                               = node->getIntValue("x");
272                                 y                               = node->getIntValue("y");
273                                 width                   = node->getIntValue("width");
274                                 height                  = node->getIntValue("height");
275                                 factor                  = node->getFloatValue("compression_factor");
276                                 span_units              = node->getFloatValue("span_units");
277                                 division_units  = node->getFloatValue("division_units");
278                                 screen_hole             = node->getIntValue("screen_hole");
279                                 lbl_pos                 = node->getIntValue("lbl_pos");
280                                 frl_spot                = node->getBoolValue("enable_frl",false);
281                                 target                  = node->getBoolValue("enable_target_spot",false);
282                                 vel_vector              = node->getBoolValue("enable_velocity_vector",false);
283                                 drift                   = node->getBoolValue("enable_drift_marker",false);
284                                 alpha                   = node->getBoolValue("enable_alpha_bracket",false);
285                                 energy                  = node->getBoolValue("enable_energy_marker",false);
286                                 climb_dive              = node->getBoolValue("enable_climb_dive_marker",false);
287                                 glide                   = node->getBoolValue("enable_glide_slope_marker",false);
288                                 glide_slope_val = node->getFloatValue("glide_slope",-4.0);
289                                 worm_energy             = node->getBoolValue("enable_energy_marker",false);
290                                 waypoint                = node->getBoolValue("enable_waypoint_marker",false);
291                                 working                 = node->getBoolValue("working");
292
293                                 FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
294         
295                                 
296                                 p = (instr_item *) new HudLadder( name, x, y,
297                                         width, height, factor,
298                                                                                 get_roll, get_pitch,
299                                                                                 span_units, division_units, minor_division,
300                                                                                 screen_hole, lbl_pos, frl_spot, target, vel_vector, 
301                                                                                 drift, alpha, energy, climb_dive, 
302                                                                                 glide, glide_slope_val, worm_energy, 
303                                                                                 waypoint, working);
304                                 
305                                 return p;
306                 
307 } //end readLadder
308
309 static instr_item * 
310 readCard(const SGPropertyNode * node)
311 {
312
313         instr_item *p;
314
315                                 name                    = node->getStringValue("name");
316                                 x                               = node->getIntValue("x");
317                                 y                               = node->getIntValue("y");
318                                 width                   = node->getIntValue("width");
319                                 height                  = node->getIntValue("height");
320                                 loadfn                  = node->getStringValue("loadfn");
321                                 options                 = node->getIntValue("options");
322                                 maxValue                = node->getFloatValue("maxValue");
323                                 minValue                = node->getFloatValue("minValue");
324                                 scaling                 = node->getFloatValue("disp_scaling");
325                                 major_divs              = node->getIntValue("major_divs");
326                                 minor_divs              = node->getIntValue("minor_divs");
327                                 modulator               = node->getIntValue("modulator");
328                                 span_units              = node->getFloatValue("value_span");
329                                 type                    = node->getStringValue("type");
330                                 tick_bottom         = node->getBoolValue("tick_bottom",false);
331                                 tick_top                = node->getBoolValue("tick_top",false);
332                                 tick_right              = node->getBoolValue("tick_right",false);
333                                 tick_left               = node->getBoolValue("tick_left",false);
334                                 cap_bottom              = node->getBoolValue("cap_bottom",false);
335                                 cap_top                 = node->getBoolValue("cap_top",false);
336                                 cap_right               = node->getBoolValue("cap_right",false);
337                                 cap_left                = node->getBoolValue("cap_left",false);
338                                 marker_off              = node->getFloatValue("marker_offset",0.0);
339                                 enable_pointer  = node->getBoolValue("enable_pointer",true);
340                                 type_pointer    = node->getStringValue("pointer_type");
341                                 working                 = node->getBoolValue("working");
342
343
344                                 FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
345
346
347                                 if(type=="guage")
348                                         span_units = maxValue - minValue;
349
350                                 if(loadfn=="anzg")
351                                         load_fn = get_anzg;
352                                 else                            
353                                 if(loadfn=="heading")
354                                         load_fn = get_heading;
355                                 else
356                                 if(loadfn=="aoa")
357                                         load_fn = get_aoa;
358                                 else
359                                 if(loadfn=="climb")
360                                         load_fn = get_climb_rate;
361                                 else
362                                 if(loadfn=="altitude")
363                                         load_fn = get_altitude;
364                                 else
365                                 if(loadfn=="agl")
366                                         load_fn = get_agl;
367                                 else
368                                 if(loadfn=="speed")
369                                         load_fn = get_speed;
370                                 else
371                                 if(loadfn=="view_direction")
372                                         load_fn = get_view_direction;
373                                 else
374                                 if(loadfn=="aileronval")
375                                         load_fn = get_aileronval;
376                                 else
377                                 if(loadfn=="elevatorval")
378                                         load_fn = get_elevatorval;
379                                 else
380                                 if(loadfn=="rudderval")
381                                         load_fn = get_rudderval;
382                                 else
383                                 if(loadfn=="throttleval")
384                                         load_fn = get_throttleval;
385
386
387                                 p = (instr_item *) new hud_card(        x,
388                                                                                                                 y,  
389                                                                                                                 width,
390                                                                                                                 height,
391                                                                             load_fn,
392                                                                                                                 options,
393                                                                                                                 maxValue, minValue,
394                                                                                                                 scaling,
395                                                                                                                 major_divs, minor_divs,
396                                                                                                                 modulator,
397                                                                                                                 dp_showing,
398                                                                                                                 span_units,
399                                                                                                                 type,
400                                                                                                                 tick_bottom,
401                                                                                                                 tick_top,
402                                                                                                                 tick_right,
403                                                                                                                 tick_left,
404                                                                                                                 cap_bottom,
405                                                                                                                 cap_top,
406                                                                                                                 cap_right,
407                                                                                                                 cap_left,
408                                                                                                                 marker_off,
409                                                                                                                 enable_pointer,
410                                                                                                                 type_pointer,
411                                                                                                                 working);
412                                         return p;
413 }// end readCard
414
415 static instr_item *
416 readLabel(const SGPropertyNode * node)
417 {
418         instr_item *p;
419
420         int font_size = (globals->get_options()->get_xsize() > 1000) ? LARGE : SMALL;
421
422                                 name                            = node->getStringValue("name");
423                                 x                   = node->getIntValue("x");
424                                 y                   = node->getIntValue("y");
425                                 width               = node->getIntValue("width");
426                                 height                          = node->getIntValue("height");
427                                 loadfn                          = node->getStringValue("data_source");
428                                 label_format            = node->getStringValue("label_format");
429                                 prelabel                        = node->getStringValue("pre_label_string");
430                                 postlabel                       = node->getStringValue("post_label_string");
431                                 scaling                         = node->getFloatValue("scale_data");
432                                 options                         = node->getIntValue("options");
433                                 justi                           = node->getIntValue("justification");
434                                 blinking            = node->getIntValue("blinking");
435                                 latitude                        = node->getBoolValue("latitude",false);
436                                 longitude                       = node->getBoolValue("longitude",false);
437                                 working             = node->getBoolValue("working");
438
439
440                                 FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
441
442
443                                 if(justi==0)
444                                         justification = LEFT_JUST;
445                                 else
446                                 if(justi==1)
447                                         justification = CENTER_JUST;
448                                 else
449                                 if(justi==2)
450                                         justification = RIGHT_JUST;
451
452
453                                 if(prelabel=="NULL")
454                                         pre_label_string = NULL;
455                                 else
456                                 if(prelabel=="blank")
457                                         pre_label_string = " ";
458                                 else
459                                         pre_label_string = prelabel.c_str();
460
461
462                                 if(postlabel=="blank")
463                                         post_label_string = " ";
464                                 else
465                                 if(postlabel=="NULL")
466                                         post_label_string = NULL;
467                                 else
468                                 if(postlabel=="units")
469                                         post_label_string = units;
470                                 else
471                                         post_label_string = postlabel.c_str();
472  
473
474                                 if(loadfn=="aux16")
475                                         load_fn = get_aux16;
476                                 else
477                                 if(loadfn=="aux17")
478                                         load_fn = get_aux17;
479                                 else
480                                 if(loadfn=="aux9")
481                                         load_fn = get_aux9;
482                                 else
483                                 if(loadfn=="aux11")
484                                         load_fn = get_aux11;
485                                 else
486                                 if(loadfn=="aux12")
487                                         load_fn = get_aux12;
488                                 else
489                                 if(loadfn=="aux10")
490                                         load_fn = get_aux10;
491                                 else
492                                 if(loadfn=="aux13")
493                                         load_fn = get_aux13;
494                                 else
495                                 if(loadfn=="aux14")
496                                         load_fn = get_aux14;
497                                 else
498                                 if(loadfn=="aux15")
499                                         load_fn = get_aux15;
500                                 else
501                                 if(loadfn=="aux8")
502                                         load_fn = get_aux8;
503                                 else
504                                 if(loadfn=="ax")
505                                         load_fn = get_Ax;
506                                 else
507                                 if(loadfn=="speed")
508                                         load_fn = get_speed;
509                                 else
510                                 if(loadfn=="mach")
511                                         load_fn = get_mach;
512                                 else
513                                 if(loadfn=="altitude")
514                                         load_fn = get_altitude;
515                                 else
516                                 if(loadfn=="agl")
517                                         load_fn = get_agl;
518                                 else
519                                 if(loadfn=="framerate")
520                                         load_fn = get_frame_rate;
521                                 else
522                                 if(loadfn=="heading")
523                                         load_fn = get_heading;
524                                 else
525                                 if(loadfn=="fov")
526                                         load_fn = get_fov;
527                                 else
528                                 if(loadfn=="vfc_tris_culled")
529                                         load_fn = get_vfc_tris_culled;
530                                 else
531                                 if(loadfn=="vfc_tris_drawn")
532                                         load_fn = get_vfc_tris_drawn;
533                                 else
534                                 if(loadfn=="aoa")
535                                         load_fn = get_aoa;
536                                 else
537                                 if(loadfn=="latitude")
538                                         load_fn  = get_latitude;
539                                 else
540                                 if(loadfn=="longitude")
541                                         load_fn   = get_longitude;
542
543
544                                 p = (instr_item *) new instr_label ( x,
545                                                  y,
546                                                  width,
547                                                  height,
548                                                  load_fn,
549                                                                                              label_format.c_str(),
550                                                  pre_label_string,
551                                                                                                  post_label_string,
552                                                  scaling,
553                                                  options,
554                                                  justification,
555                                                                                                  font_size,
556                                                  blinking,
557                                                                                                  latitude,
558                                                  longitude,
559                                                                                                  working);
560
561                                 return p;
562
563 } // end readLabel
564
565 static instr_item * 
566 readTBI(const SGPropertyNode * node)
567 {
568
569         instr_item *p;
570
571                                 name           = node->getStringValue("name");
572                                 x              = node->getIntValue("x");
573                                 y              = node->getIntValue("y");
574                                 width          = node->getIntValue("width");
575                                 height         = node->getIntValue("height");
576                                 maxBankAngle   = node->getFloatValue("maxBankAngle");
577                                 maxSlipAngle   = node->getFloatValue("maxSlipAngle");
578                                 gap_width      = node->getIntValue("gap_width");
579                                 working        = node->getBoolValue("working");
580
581                                 FG_LOG(FG_INPUT, FG_INFO, "Done reading instrument " << name);
582
583
584                                 p = (instr_item *) new fgTBI_instr(     x,
585                                                                                                                 y,  
586                                                                                                                 width,
587                                                                                                                 height,
588                                                                                                                 get_roll,
589                                                                                                                 get_sideslip,
590                                                                                                                 maxBankAngle, 
591                                                                                                                 maxSlipAngle,
592                                                                                                                 gap_width,
593                                                                                                                 working);
594
595                                 return p;
596 } //end readTBI
597
598
599 int readInstrument(const SGPropertyNode * node)
600 {
601
602         instr_item *HIptr;
603     
604     if ( globals->get_options()->get_units() == FGOptions::FG_UNITS_FEET ) {
605     strcpy(units, " ft");
606     } else {
607     strcpy(units, " m");
608     }
609
610                         const SGPropertyNode * ladder_group = node->getNode("ladders");
611
612                         if (ladder_group != 0) {
613                                 int nLadders = ladder_group->nChildren();
614                                 for (int j = 0; j < nLadders; j++) {
615
616                                         HIptr = readLadder(ladder_group->getChild(j));
617                                         HUD_deque.insert( HUD_deque.begin(), HIptr);
618                                         
619                                 }// for - ladders
620                         }
621
622                         const SGPropertyNode * card_group = node->getNode("cards");
623                         if (card_group != 0) {
624                                 int nCards = card_group->nChildren();
625                                 for (int j = 0; j < nCards; j++) {
626
627                                         HIptr = readCard(card_group->getChild(j));
628                                         HUD_deque.insert( HUD_deque.begin(), HIptr);
629
630                                 }//for - cards
631                         }
632
633                         const SGPropertyNode * label_group = node->getNode("labels");
634                         if (label_group != 0) {
635                                 int nLabels = label_group->nChildren();
636                                 for (int j = 0; j < nLabels; j++) {
637
638                                         HIptr = readLabel(label_group->getChild(j));
639                                         HUD_deque.insert( HUD_deque.begin(), HIptr);
640
641                                 }//for - labels
642                         }
643
644                         const SGPropertyNode * tbi_group = node->getNode("tbis");
645                         if (tbi_group != 0) {
646                                 int nTbis = tbi_group->nChildren();
647                                 for (int j = 0; j < nTbis; j++) {
648
649                                         HIptr = readTBI(tbi_group->getChild(j));
650                                         HUD_deque.insert( HUD_deque.begin(), HIptr);
651
652                                 }//for - tbis
653                         }
654  return 0;
655 }//end readinstrument
656
657 int readHud( istream &input ) 
658 {
659
660         SGPropertyNode root;
661
662
663         if (!readProperties(input, &root)) {
664                 FG_LOG(FG_INPUT, FG_ALERT, "Malformed property list for hud.");
665                 return 0;
666         }
667   
668         
669         FG_LOG(FG_INPUT, FG_INFO, "Read properties for  " <<
670                 root.getStringValue("name"));
671
672
673         HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());  // empty the HUD deque
674
675
676         FG_LOG(FG_INPUT, FG_INFO, "Reading Hud instruments");
677
678         const SGPropertyNode * instrument_group = root.getChild("instruments");
679         int nInstruments = instrument_group->nChildren();
680
681         for (int i = 0; i < nInstruments; i++) {
682                 
683                 const SGPropertyNode * node = instrument_group->getChild(i);
684
685                 FGPath path( globals->get_options()->get_fg_root() );
686                 path.append(node->getStringValue("path"));
687
688                 FG_LOG(FG_INPUT, FG_INFO, "Reading Instrument "
689                 << node->getName()
690                 << " from "
691                 << path.str());
692
693
694                 SGPropertyNode root2;
695                 if (readProperties(path.str(), &root2)) {
696
697                         readInstrument(&root2);
698
699                 }//if
700         }//for loop(i)
701  return 0;
702 }
703
704
705 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
706 {
707
708
709         HUD_style = 1;
710
711         FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
712
713     string hud_path =
714         globals->get_props()->getStringValue("/sim/hud/path",
715                                           "Huds/Default/default.xml");
716         FGPath path(globals->get_options()->get_fg_root());
717         path.append(hud_path);
718         
719         ifstream input(path.c_str());
720         if (!input.good()) 
721                 {
722                         FG_LOG(FG_INPUT, FG_ALERT,
723                         "Cannot read Hud configuration from " << path.str());
724                 } 
725         else 
726                 {
727                         readHud(input);
728                         input.close();
729                 }
730
731         fgHUDalphaInit();
732         fgHUDReshape();
733
734   return 0;  // For now. Later we may use this for an error code.
735
736 }
737
738 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
739 {
740
741     HUD_style = 2;
742
743     FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
744
745         FGPath path(globals->get_options()->get_fg_root());
746         path.append("Huds/Minimal/default.xml");
747
748
749         ifstream input(path.c_str());
750         if (!input.good()) {
751                 FG_LOG(FG_INPUT, FG_ALERT,
752                         "Cannot read Hud configuration from " << path.str());
753         } 
754         else {
755                 readHud(input);
756                 input.close();
757         }
758
759     return 0;  // For now. Later we may use this for an error code.
760
761 }
762 //$$$ End - added, Neetha, 28 Nov 2k  
763
764 int global_day_night_switch = DAY;
765
766 void HUD_masterswitch( bool incr )
767 {
768     if ( globals->get_options()->get_hud_status() ) {
769         if ( global_day_night_switch == DAY ) {
770             global_day_night_switch = NIGHT;
771         } else {
772             globals->get_options()->set_hud_status( false );
773         }
774     } else {
775         globals->get_options()->set_hud_status( true );
776         global_day_night_switch = DAY;
777     }   
778 }
779
780 void HUD_brightkey( bool incr_bright )
781 {
782     instr_item *pHUDInstr = HUD_deque[0];
783     int brightness        = pHUDInstr->get_brightness();
784
785     if( globals->get_options()->get_hud_status() ) {
786         if( incr_bright ) {
787             switch (brightness)
788                 {
789                 case BRT_LIGHT:
790                     brightness = BRT_BLACK;
791                     break;
792
793                 case BRT_MEDIUM:
794                     brightness = BRT_LIGHT;
795                     break;
796
797                 case BRT_DARK:
798                     brightness = BRT_MEDIUM;
799                     break;
800
801                 case BRT_BLACK:
802                     brightness = BRT_DARK;
803                     break;
804
805                 default:
806                     brightness = BRT_BLACK;
807                 }
808         } else {
809             switch (brightness)
810                 {
811                 case BRT_LIGHT:
812                     brightness = BRT_MEDIUM;
813                     break;
814
815                 case BRT_MEDIUM:
816                     brightness = BRT_DARK;
817                     break;
818
819                 case BRT_DARK:
820                     brightness = BRT_BLACK;
821                     break;
822
823                 case BRT_BLACK:
824                     brightness = BRT_LIGHT;
825                     break;
826
827                 default:
828                     globals->get_options()->set_hud_status(0);
829                 }
830         }
831     } else {
832         globals->get_options()->set_hud_status(true);
833     }
834
835     pHUDInstr->SetBrightness( brightness );
836 }
837
838
839 #define fgAP_CLAMP(val,min,max) ( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) )
840
841 static puDialogBox *HUDalphaDialog;
842 static puText      *HUDalphaText;
843 static puSlider    *HUDalphaHS0;
844 //static puText      *HUDtextText;
845 //static puSlider    *HUDalphaHS1;
846 static char         SliderText[2][ 8 ];
847
848 static void alpha_adj( puObject *hs ) {
849         float val ;
850
851         hs-> getValue ( &val ) ;
852         fgAP_CLAMP ( val, 0.1, 1.0 ) ;
853         //    printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ;
854         hud_trans_alpha = val;
855         sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
856         HUDalphaText -> setLabel ( SliderText[ 0 ] ) ;
857 }
858
859 void fgHUDalphaAdjust( puObject * ) {
860         globals->get_options()->set_anti_alias_hud(1);
861         FG_PUSH_PUI_DIALOG( HUDalphaDialog );
862 }
863
864 static void goAwayHUDalphaAdjust (puObject *)
865 {
866         FG_POP_PUI_DIALOG( HUDalphaDialog );
867 }
868
869 static void cancelHUDalphaAdjust (puObject *)
870 {
871         globals->get_options()->set_anti_alias_hud(0);
872         FG_POP_PUI_DIALOG( HUDalphaDialog );
873 }
874
875 // Done once at system initialization
876 void fgHUDalphaInit( void ) {
877
878         //      printf("fgHUDalphaInit\n");
879 #define HORIZONTAL  FALSE
880
881         int DialogX = 40;
882         int DialogY = 100;
883         int DialogWidth = 240;
884
885         char Label[] =  "HUD Adjuster";
886         char *s;
887
888         int labelX = (DialogWidth / 2) -
889                                  (puGetStringWidth( puGetDefaultLabelFont(), Label ) / 2);
890         
891         int nSliders = 1;
892         int slider_x = 10;
893         int slider_y = 55;
894         int slider_width = 220;
895         int slider_title_x = 15;
896         int slider_value_x = 160;
897         float slider_delta = 0.05f;
898
899         puFont HUDalphaLegendFont;
900         puFont HUDalphaLabelFont;
901         puGetDefaultFonts ( &HUDalphaLegendFont, &HUDalphaLabelFont );
902         
903         HUDalphaDialog = new puDialogBox ( DialogX, DialogY ); {
904                 int horiz_slider_height = puGetStringHeight (HUDalphaLabelFont) +
905                                                                   puGetStringDescender (HUDalphaLabelFont) +
906                                                                   PUSTR_TGAP + PUSTR_BGAP + 5;
907
908                 puFrame *
909                 HUDalphaFrame = new puFrame ( 0, 0,
910                                                                           DialogWidth,
911                                                                           85 + nSliders * horiz_slider_height );
912                 
913                 puText *
914                 HUDalphaDialogMessage = new puText ( labelX,
915                                                                                          52 + nSliders
916                                                                                          * horiz_slider_height );
917                 HUDalphaDialogMessage -> setDefaultValue ( Label );
918                 HUDalphaDialogMessage -> getDefaultValue ( &s );
919                 HUDalphaDialogMessage -> setLabel        ( s );
920
921                 HUDalphaHS0 = new puSlider ( slider_x, slider_y,
922                                                                          slider_width, HORIZONTAL ) ;
923                 HUDalphaHS0->     setDelta ( slider_delta ) ;
924                 HUDalphaHS0->     setValue ( hud_trans_alpha ) ;
925                 HUDalphaHS0->    setCBMode ( PUSLIDER_DELTA ) ;
926                 HUDalphaHS0->  setCallback ( alpha_adj ) ;
927
928                 puText *
929                 HUDalphaTitle =      new puText ( slider_title_x, slider_y ) ;
930                 HUDalphaTitle-> setDefaultValue ( "Alpha" ) ;
931                 HUDalphaTitle-> getDefaultValue ( &s ) ;
932                 HUDalphaTitle->        setLabel ( s ) ;
933                 
934                 HUDalphaText = new puText ( slider_value_x, slider_y ) ;
935                 sprintf( SliderText[ 0 ], "%05.2f", hud_trans_alpha );
936                 HUDalphaText-> setLabel ( SliderText[ 0 ] ) ;
937
938
939                 puOneShot *
940                 HUDalphaOkButton =     new puOneShot ( 10, 10, 60, 45 );
941                 HUDalphaOkButton->         setLegend ( gui_msg_OK );
942                 HUDalphaOkButton-> makeReturnDefault ( TRUE );
943                 HUDalphaOkButton->       setCallback ( goAwayHUDalphaAdjust );
944                 
945                 puOneShot *
946                 HUDalphaNoButton = new puOneShot ( 160, 10, 230, 45 );
947                 HUDalphaNoButton->     setLegend ( gui_msg_CANCEL );
948                 HUDalphaNoButton->   setCallback ( cancelHUDalphaAdjust );
949         }
950         FG_FINALIZE_PUI_DIALOG( HUDalphaDialog );
951
952 #undef HORIZONTAL
953 }
954
955 void fgHUDReshape(void) {
956         if ( HUDtext )
957                 delete HUDtext;
958
959         HUD_TextSize = globals->get_options()->get_xsize() / 60;
960         HUD_TextSize = 10;
961         HUDtext = new fntRenderer();
962         HUDtext -> setFont      ( guiFntHandle ) ;
963         HUDtext -> setPointSize ( HUD_TextSize ) ;
964         HUD_TextList.setFont( HUDtext );
965 }
966
967
968 static void set_hud_color(float r, float g, float b) {
969         globals->get_options()->get_anti_alias_hud() ?
970                         glColor4f(r,g,b,hud_trans_alpha) :
971                         glColor3f(r,g,b);
972 }
973
974 // fgUpdateHUD
975 //
976 // Performs a once around the list of calls to instruments installed in
977 // the HUD object with requests for redraw. Kinda. It will when this is
978 // all C++.
979 //
980 void fgUpdateHUD( void ) {
981   int brightness;
982 //  int day_night_sw = current_aircraft.controls->day_night_switch;
983   int day_night_sw = global_day_night_switch;
984   int hud_displays = HUD_deque.size();
985   instr_item *pHUDInstr;
986   float line_width;
987
988   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
989     return;
990     }
991
992   HUD_TextList.erase();
993   HUD_LineList.erase();
994 //  HUD_StippleLineList.erase();
995   
996   pHUDInstr = HUD_deque[0];
997   brightness = pHUDInstr->get_brightness();
998 //  brightness = HUD_deque.at(0)->get_brightness();
999
1000   glMatrixMode(GL_PROJECTION);
1001   glPushMatrix();
1002
1003   glLoadIdentity();
1004   gluOrtho2D(0, 640, 0, 480);
1005   glMatrixMode(GL_MODELVIEW);
1006   glPushMatrix();
1007   glLoadIdentity();
1008
1009   glDisable(GL_DEPTH_TEST);
1010   glDisable(GL_LIGHTING);
1011
1012   if( globals->get_options()->get_anti_alias_hud() ) {
1013           glEnable(GL_LINE_SMOOTH);
1014 //        glEnable(GL_BLEND);
1015           glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1016           glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
1017           glLineWidth(1.5);
1018   } else {
1019           glLineWidth(1.0);
1020   }
1021
1022   if( day_night_sw == DAY) {
1023       switch (brightness)
1024           {
1025           case BRT_LIGHT:
1026               set_hud_color (0.1f, 0.9f, 0.1f);
1027               break;
1028
1029           case BRT_MEDIUM:
1030               set_hud_color (0.1f, 0.7f, 0.0f);
1031               break;
1032
1033           case BRT_DARK:
1034               set_hud_color (0.0f, 0.6f, 0.0f);
1035               break;
1036
1037           case BRT_BLACK:
1038               set_hud_color( 0.0f, 0.0f, 0.0f);
1039               break;
1040
1041           default:
1042               set_hud_color (0.1f, 0.9f, 0.1f);
1043           }
1044   } else {
1045       if( day_night_sw == NIGHT) {
1046           switch (brightness)
1047               {
1048               case BRT_LIGHT:
1049                   set_hud_color (0.9f, 0.1f, 0.1f);
1050                   break;
1051
1052               case BRT_MEDIUM:
1053                   set_hud_color (0.7f, 0.0f, 0.1f);
1054                   break;
1055
1056               case BRT_DARK:
1057                   set_hud_color (0.6f, 0.0f, 0.0f);
1058                   break;
1059
1060               case BRT_BLACK:
1061                   set_hud_color( 0.0f, 0.0f, 0.0f);
1062                   break;
1063
1064               default:
1065                   set_hud_color (0.6f, 0.0f, 0.0f);
1066               }
1067       } else {     // Just in case default
1068           set_hud_color (0.1f, 0.9f, 0.1f);
1069       }
1070   }
1071
1072   deque < instr_item * > :: iterator current = HUD_deque.begin();
1073   deque < instr_item * > :: iterator last = HUD_deque.end();
1074
1075   for ( ; current != last; ++current ) {
1076           pHUDInstr = *current;
1077
1078           if( pHUDInstr->enabled()) {
1079                   //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1080                   //            hud->code, hud->status );
1081                   pHUDInstr->draw();
1082                   
1083           }
1084   }
1085
1086   char *gmt_str = get_formated_gmt_time();
1087   HUD_TextList.add( fgText(40, 10, gmt_str) );
1088
1089 #ifdef FG_NETWORK_OLK
1090   if ( net_hud_display ) {
1091       net_hud_update();
1092   }
1093 #endif
1094
1095
1096   // temporary
1097   // extern bool fgAPAltitudeEnabled( void );
1098   // extern bool fgAPHeadingEnabled( void );
1099   // extern bool fgAPWayPointEnabled( void );
1100   // extern char *fgAPget_TargetDistanceStr( void );
1101   // extern char *fgAPget_TargetHeadingStr( void );
1102   // extern char *fgAPget_TargetAltitudeStr( void );
1103   // extern char *fgAPget_TargetLatLonStr( void );
1104
1105   int apY = 480 - 80;
1106 //  char scratch[128];
1107 //  HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
1108 //  apY -= 15;
1109   if( current_autopilot->get_HeadingEnabled() ) {
1110       HUD_TextList.add( fgText( 40, apY, 
1111                                 current_autopilot->get_TargetHeadingStr()) );
1112       apY -= 15;
1113   }
1114   if( current_autopilot->get_AltitudeEnabled() ) {
1115       HUD_TextList.add( fgText( 40, apY, 
1116                                 current_autopilot->get_TargetAltitudeStr()) );
1117       apY -= 15;
1118   }
1119   if( current_autopilot->get_HeadingMode() == 
1120       FGAutopilot::FG_HEADING_WAYPOINT )
1121   {
1122       char *wpstr;
1123       wpstr = current_autopilot->get_TargetWP1Str();
1124       if ( strlen( wpstr ) ) {
1125           HUD_TextList.add( fgText( 40, apY, wpstr ) );
1126           apY -= 15;
1127       }
1128       wpstr = current_autopilot->get_TargetWP2Str();
1129       if ( strlen( wpstr ) ) {
1130           HUD_TextList.add( fgText( 40, apY, wpstr ) );
1131           apY -= 15;
1132       }
1133       wpstr = current_autopilot->get_TargetWP3Str();
1134       if ( strlen( wpstr ) ) {
1135           HUD_TextList.add( fgText( 40, apY, wpstr ) );
1136           apY -= 15;
1137       }
1138   }
1139   
1140   HUD_TextList.draw();
1141
1142   HUD_LineList.draw();
1143
1144 //  glEnable(GL_LINE_STIPPLE);
1145 //  glLineStipple( 1, 0x00FF );
1146 //  HUD_StippleLineList.draw();
1147 //  glDisable(GL_LINE_STIPPLE);
1148
1149   if( globals->get_options()->get_anti_alias_hud() ) {
1150 //        glDisable(GL_BLEND);
1151           glDisable(GL_LINE_SMOOTH);
1152           glLineWidth(1.0);
1153   }
1154
1155   glEnable(GL_DEPTH_TEST);
1156   glEnable(GL_LIGHTING);
1157   glMatrixMode(GL_PROJECTION);
1158   glPopMatrix();
1159   glMatrixMode(GL_MODELVIEW);
1160   glPopMatrix();
1161 }
1162