]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud.cxx
6e2341f8e1c7efe1ad2553c004ef52eaf0246cb6
[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
41 #ifdef HAVE_VALUES_H
42 #  include <values.h>  // for MAXINT
43 #endif
44
45 #include <Aircraft/aircraft.hxx>
46 #include <Debug/logstream.hxx>
47 #include <GUI/gui.h>
48 #include <Include/fg_constants.h>
49 #include <Main/options.hxx>
50 #include <Math/fg_random.h>
51 #include <Math/mat3.h>
52 #include <Math/polar3d.hxx>
53 #include <Scenery/scenery.hxx>
54 #include <Time/fg_timer.hxx>
55
56 #if defined ( __sun__ ) || defined ( __sgi )
57 extern "C" {
58   extern void *memmove(void *, const void *, size_t);
59 }
60 #endif
61
62 #include "hud.hxx"
63
64 static char units[5];
65
66 // The following routines obtain information concerning the aircraft's
67 // current state and return it to calling instrument display routines.
68 // They should eventually be member functions of the aircraft.
69 //
70
71 deque< instr_item * > HUD_deque;
72
73 fgTextList         HUD_TextList;
74 fgLineList         HUD_LineList;
75 fgLineList         HUD_StippleLineList;
76
77 class locRECT {
78   public:
79     RECT rect;
80
81     locRECT( UINT left, UINT top, UINT right, UINT bottom);
82     RECT get_rect(void) { return rect;}
83 };
84
85 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
86 {
87   rect.left   =  left;
88   rect.top    =  top;
89   rect.right  =  right;
90   rect.bottom =  bottom;
91
92 }
93 // #define DEBUG
94
95 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
96 {
97   glBegin(GL_LINES);
98   glVertex2f(x1, y1);
99   glVertex2f(x2, y2);
100   glEnd();
101 }
102
103 void drawOneLine( RECT &rect)
104 {
105   glBegin(GL_LINES);
106   glVertex2f(rect.left, rect.top);
107   glVertex2f(rect.right, rect.bottom);
108   glEnd();
109 }
110
111 //
112 // The following code deals with painting the "instrument" on the display
113 //
114    /* textString - Bitmap font string */
115
116 void textString( int x, int y, char *msg, void *font ){
117
118     if(*msg)
119     {
120 //      puDrawString (  NULL, msg, x, y );
121         
122         glRasterPos2f(x, y);
123         while (*msg) {
124             glutBitmapCharacter(font, *msg);
125             msg++;
126         }
127     }
128 }
129
130
131 /* strokeString - Stroke font string */
132 void strokeString(int x, int y, char *msg, void *font, float theta)
133 {
134     int xx;
135     int yy;
136     int c;
137     float sintheta,costheta;
138     
139
140     if(*msg)
141     {
142     glPushMatrix();
143     glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
144     sintheta = sin(theta);
145     costheta = cos(theta);
146     xx = (int)(x * costheta + y * sintheta);
147     yy = (int)(y * costheta - x * sintheta);
148     glTranslatef( xx, yy, 0);
149     glScalef(.1, .1, 0.0);
150     while( (c=*msg++) ) {
151         glutStrokeCharacter(font, c);
152     }
153     glPopMatrix();
154     }
155 }
156
157 int getStringWidth ( char *str )
158 {
159     if ( HUDtext && str )
160     {
161         float r, l ;
162         guiFntHandle->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
163         return FloatToInt( r - l );
164     }
165     return 0 ;
166 }
167
168 //========================= End of Class Implementations===================
169 // fgHUDInit
170 //
171 // Constructs a HUD object and then adds in instruments. At the present
172 // the instruments are hard coded into the routine. Ultimately these need
173 // to be defined by the aircraft's instrumentation records so that the
174 // display for a Piper Cub doesn't show the speed range of a North American
175 // mustange and the engine readouts of a B36!
176 //
177
178 #define INSTRDEFS 21
179
180 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
181 {
182   instr_item *HIptr;
183 //  int index;
184   int font_size;
185
186   int off = 50;
187   int min_x = 25; //off/2;
188   int max_x = 615; //640-(off/2);
189 //  int min_y = off;
190   int max_y = 430; //480-off;
191   int cen_x = 320;
192   int cen_y = 240;
193   unsigned int text_h = 10;
194   unsigned int ladr_w2 = 60;
195   int ladr_h2 = 90;
196   int ladr_t = 35;
197   int compass_w = 200;
198   int gap = 10;
199
200   font_size = (current_options.get_xsize() > 1000) ? LARGE : SMALL;
201   
202   HUD_style = 1;
203
204   FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
205
206 //  deque < instr_item * > :: iterator first = HUD_deque.begin();
207 //  deque < instr_item * > :: iterator last = HUD_deque.end();
208 //  HUD_deque.erase( first, last);  // empty the HUD deque  
209
210   HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());  // empty the HUD deque
211
212 //  hud->code = 1;
213 //  hud->status = 0;
214
215   // For now lets just hardcode the hud here.
216   // In the future, hud information has to come from the same place
217   // aircraft information came from.
218
219 //  fgHUDSetTimeMode( hud, NIGHT );
220 //  fgHUDSetBrightness( hud, BRT_LIGHT );
221
222 //      case 0:     // TBI
223   int x = 290; /*cen_x-30*/
224   int y = 45;  /*off-5*/
225 //  HIptr = (instr_item *) new fgTBI_instr( x, y, ladr_w2, text_h );
226   HIptr = (instr_item *) new fgTBI_instr( 290, 45, 60, 10 );  
227   HUD_deque.insert( HUD_deque.begin(), HIptr);
228
229 //      case 1:     // Artificial Horizon
230   HIptr = (instr_item *) new HudLadder( cen_x-ladr_w2, cen_y-ladr_h2,
231                                         2*ladr_w2, 2*ladr_h2 );
232   HUD_deque.insert( HUD_deque.begin(), HIptr);
233
234 //      case 4:    // GYRO COMPASS
235   HIptr = (instr_item *) new hud_card( cen_x-(compass_w/2),
236                                        max_y,
237                                        compass_w,
238                                        28,
239                                        get_heading,
240                                        HUDS_TOP,
241                                        360, 0,
242                                        1.0,
243                                        5,   1,
244                                        360,
245                                        0,
246                                        25,
247                                        true);
248   HUD_deque.insert( HUD_deque.begin(), HIptr);
249
250 //      case 5:    // AMSL
251   HIptr = (instr_item *) new hud_card( max_x - 35 -15, // 15 to balance speed card
252                                        cen_y-(compass_w/2),
253                                        35,
254                                        compass_w,
255                                        get_altitude,
256 //                                     HUDS_RIGHT | HUDS_VERT,
257                                        HUDS_LEFT | HUDS_VERT,
258                                        5000, -1000,
259                                        1.0,
260                                        100,  25,
261                                        0,
262                                        0,
263                                        250,
264                                        true);
265   HUD_deque.insert( HUD_deque.begin(), HIptr);
266
267 //      case 6:
268   HIptr = (instr_item *) new  guage_instr( cen_x-50,            // x
269                                            cen_y + ladr_h2 -20,  // y
270                                            100,            // width
271                                            20,            // height
272                                            get_aileronval, // data source
273                                            HUDS_BOTTOM | HUDS_NOTEXT,
274                                            100.0,
275                                            +1.0,
276                                            -1.0);
277   HUD_deque.insert( HUD_deque.begin(), HIptr);
278
279 //      case 3:    // Radio Altimeter
280   HIptr = (instr_item *) new hud_card( cen_x + ladr_w2 + gap + 13 + ladr_t,
281                                        cen_y-75,
282                                        25,
283                                        150,
284                                        get_agl,
285                                        HUDS_LEFT | HUDS_VERT,
286                                        1000, 0,
287                                        1.0,
288                                        25, 5,
289                                        0,
290                                        0,
291                                        200.0,
292                                        true);
293   HUD_deque.insert( HUD_deque.begin(), HIptr);
294
295 //      case 7:
296   HIptr = (instr_item *) new  guage_instr( cen_x -ladr_w2 -gap -13 -20 -ladr_t,
297                                            cen_y-50,             // y
298                                            20,             // width
299                                            100,             // height
300                                            get_elevatorval, // data source
301                                            HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
302                                            -100.0,           // Scale data
303                                            +1.0,           // Data Range
304                                            -1.0);
305   HUD_deque.insert( HUD_deque.begin(), HIptr);
306
307 //      case 8:
308   HIptr = (instr_item *) new  guage_instr( cen_x-50,             // x
309                                            cen_y -gap -ladr_w2 -20, //-85   // y
310                                            100,             // width
311                                            20,             // height
312                                            get_rudderval,   // data source
313                                            HUDS_TOP | HUDS_NOTEXT,
314                                            100.0,
315                                            +1.0,
316                                            -1.0);
317   HUD_deque.insert( HUD_deque.begin(), HIptr);
318
319 //      case 2:    // KIAS
320   HIptr = (instr_item *) new hud_card( min_x +10 +5, //min_x +18,
321                                        cen_y-(compass_w/2),
322                                        28,
323                                        compass_w,
324                                        get_speed,
325 //                                     HUDS_LEFT | HUDS_VERT,
326                                        HUDS_RIGHT | HUDS_VERT,                                     
327                                        200.0, 0.0,
328                                        1.0,
329                                        10,  5,
330                                        0,
331                                        0,
332                                        50.0,
333                                        true);
334
335   HUD_deque.insert( HUD_deque.begin(), HIptr);
336
337 //      case 9:
338   HIptr = (instr_item *) new  guage_instr( min_x-10,           // x
339                                            cen_y -75,       // y 
340                                            20,              // width
341                                            150,             // height
342                                            get_throttleval, // data source
343 //                                         HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
344                                            HUDS_VERT | HUDS_LEFT | HUDS_NOTEXT,                                        100.0,
345                                            1.0,
346                                            0.0
347                                           );
348   HUD_deque.insert( HUD_deque.begin(), HIptr);
349 // Remove this when below uncommented       
350 //      case 10:
351   HIptr = (instr_item *) new instr_label( 10,
352                                           25,
353                                           60,
354                                           10,
355                                           get_frame_rate,
356                                           "%5.1f",
357                                           "",
358                                           NULL,
359                                           1.0,
360                                           HUDS_TOP,
361                                           RIGHT_JUST,
362                                           font_size,
363                                           0,
364                                           TRUE );
365   HUD_deque.insert( HUD_deque.begin(), HIptr);
366   
367   HIptr = (instr_item *) new lat_label(  (cen_x - (compass_w/2))/2,
368                                           max_y,    
369                                           1,
370                                           text_h,
371                                           get_latitude,
372                                           "%s%", //"%.0f",
373                                           "", //"Lat ",
374                                           "",
375                                           1.0,
376                                           HUDS_TOP,
377                                           CENTER_JUST,
378                                           font_size,
379                                           0,
380                                           TRUE );
381   HUD_deque.insert( HUD_deque.begin(), HIptr);
382     
383     HIptr = (instr_item *) new lon_label(((cen_x+compass_w/2)+(2*cen_x))/2,
384                                           max_y,
385                                           1, text_h,
386                                           get_longitude,
387                                           "%s%",//"%.0f",
388                                           "", //"Lon ", 
389                                           "",
390                                           1.0,
391                                           HUDS_TOP,
392                                           CENTER_JUST,
393                                           font_size,
394                                           0,
395                                           TRUE );
396   HUD_deque.insert( HUD_deque.begin(), HIptr);
397     
398 /*
399 //      case 10:    // Digital KIAS
400         HIptr = (instr_item *) new instr_label ( 110,
401                                                  150,
402                                                   40,
403                                                   30,
404                                                  get_speed,
405                                                  "%5.0f",
406                                                  NULL,
407                                                  " Kts",
408                                                  1.0,
409                                                  HUDS_TOP,
410                                                  RIGHT_JUST,
411                                                  font_size,
412                                                  0,
413                                                  TRUE );
414   HUD_deque.insert( HUD_deque.begin(), HIptr);
415
416 //      case 11:    // Digital Rate of Climb
417         HIptr = (instr_item *) new instr_label ( 110,
418                                                  135,
419                                                   40,
420                                                   10,
421                                                  get_climb_rate,
422                                                  "%5.0f",
423                                                  " Climb",
424                                                  NULL,
425                                                  1.0,
426                                                  HUDS_TOP,
427                                                  RIGHT_JUST,
428                                                  font_size,
429                                                  0,
430                                                  TRUE );
431   HUD_deque.insert( HUD_deque.begin(), HIptr);
432
433 //      case 12:    // Roll indication diagnostic
434         HIptr = (instr_item *) new instr_label ( 110,
435                                                  120,
436                                                   40,
437                                                   10,
438                                                  get_roll,
439                                                  "%5.2f",
440                                                  " Roll",
441                                                  " Deg",
442                                                  1.0,
443                                                  HUDS_TOP,
444                                                  RIGHT_JUST,
445                                                  font_size,
446                                                  0,
447                                                  TRUE );
448   HUD_deque.insert( HUD_deque.begin(), HIptr);
449
450 //      case 13:    // Angle of attack diagnostic
451         HIptr = (instr_item *) new instr_label ( 440,
452                                                  150,
453                                                   60,
454                                                   10,
455                                                  get_aoa,
456                                                  "      %5.2f",
457                                                  "AOA",
458                                                  " Deg",
459                                                  1.0,
460                                                  HUDS_TOP,
461                                                  RIGHT_JUST,
462                                                  font_size,
463                                                  0,
464                                                  TRUE );
465   HUD_deque.insert( HUD_deque.begin(), HIptr);
466
467 //      case 14:
468         HIptr = (instr_item *) new instr_label ( 440,
469                                                  135,
470                                                   60,
471                                                   10,
472                                                  get_heading,
473                                                  " %5.1f",
474                                                  "Heading ",
475                                                  " Deg",
476                                                  1.0,
477                                                  HUDS_TOP,
478                                                  RIGHT_JUST,
479                                                  font_size,
480                                                  0,
481                                                  TRUE );
482   HUD_deque.insert( HUD_deque.begin(), HIptr);
483
484 //      case 15:
485         HIptr = (instr_item *) new instr_label ( 440,
486                                                  120,
487                                                   60,
488                                                   10,
489                                                  get_sideslip,
490                                                  "%5.2f",
491                                                  "Sideslip ",
492                                                  NULL,
493                                                  1.0,
494                                                  HUDS_TOP,
495                                                  RIGHT_JUST,
496                                                  font_size,
497                                                  0,
498                                                  TRUE );
499   HUD_deque.insert( HUD_deque.begin(), HIptr);
500
501 //      case 16:
502         HIptr = (instr_item *) new instr_label( 440,
503                                                 100,
504                                                  60,
505                                                  10,
506                                                 get_throttleval,
507                                                 "%5.2f",
508                                                 "Throttle ",
509                                                 NULL,
510                                                  1.0,
511                                                 HUDS_TOP,
512                                                 RIGHT_JUST,
513                                                 font_size,
514                                                 0,
515                                                 TRUE );
516   HUD_deque.insert( HUD_deque.begin(), HIptr);
517
518 //      case 17:
519         HIptr = (instr_item *) new instr_label( 440,
520                                                  85,
521                                                  60,
522                                                  10,
523                                                 get_elevatorval,
524                                                 "%5.2f",
525                                                 "Elevator ",
526                                                 NULL,
527                                                  1.0,
528                                                 HUDS_TOP,
529                                                 RIGHT_JUST,
530                                                 font_size,
531                                                 0,
532                                                 TRUE );
533   HUD_deque.insert( HUD_deque.begin(), HIptr);
534
535 //      case 18:
536         HIptr = (instr_item *) new instr_label( 440,
537                                                  60,
538                                                  60,
539                                                  10,
540                                                 get_aileronval,
541                                                 "%5.2f",
542                                                 "Aileron  ",
543                                                 NULL,
544                                                  1.0,
545                                                 HUDS_TOP,
546                                                 RIGHT_JUST,
547                                                 font_size,
548                                                 0,
549                                                 TRUE );
550   HUD_deque.insert( HUD_deque.begin(), HIptr);
551
552 //      case 19:
553         HIptr = (instr_item *) new instr_label( 10,
554                                                 10,
555                                                 60,
556                                                 10,
557                                                  get_frame_rate,
558                                                 "%.1f",
559                                                 "Frame rate = ",
560                                                 NULL,
561                                                  1.0,
562                                                 HUDS_TOP,
563                                                 RIGHT_JUST,
564                                                 font_size,
565                                                 0,
566                                                 TRUE );
567   HUD_deque.insert( HUD_deque.begin(), HIptr);
568
569 //      case 20:
570       switch( current_options.get_tris_or_culled() ) {
571       case 0:
572           HIptr = (instr_item *) new instr_label( 10,
573                               25,
574                               120,
575                               10,
576                               get_vfc_tris_drawn,
577                               "%.0f",
578                               "Tris Rendered = ",
579                               NULL,
580                               1.0,
581                               HUDS_TOP,
582                               RIGHT_JUST,
583                               font_size,
584                               0,
585                               TRUE );
586           break;
587       case 1:
588           HIptr = (instr_item *) new instr_label( 10,
589                               25,
590                               90,
591                               10,
592                               get_vfc_ratio,
593                               "%.2f",
594                               "VFC Ratio = ",
595                               NULL,
596                               1.0,
597                               HUDS_TOP,
598                               RIGHT_JUST,
599                               font_size,
600                               0,
601                               TRUE );
602           break;
603       }
604       break;
605
606 //      case 21:
607         HIptr = (instr_item *) new instr_label( 10,
608                                                 40,
609                                                 90,
610                                                 10,
611                                                 get_fov,
612                                                 "%.1f",
613                                                 "FOV = ",
614                                                 NULL,
615                         1.0,
616                                                 HUDS_TOP,
617                                                 RIGHT_JUST,
618                                                 font_size,
619                                                 0,
620                                                 TRUE );
621   HUD_deque.insert( HUD_deque.begin(), HIptr);
622 */
623 //      default:
624 //        HIptr = 0;;
625 //      }
626 //    if( HIptr ) {                   // Anything to install?
627 //      HUD_deque.insert( HUD_deque.begin(), HIptr);
628 //      }
629 //    index++;
630 //    }
631 //  while( HIptr );
632
633   return 0;  // For now. Later we may use this for an error code.
634
635 }
636
637 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
638 {
639 //    instr_item *HIptr;
640 //    int index;
641     int font_size;
642
643     int off = 50;
644 //  int min_x = off;
645 //  int max_x = 640-off;
646 //  int min_y = off;
647     int max_y = 480-off;
648     int cen_x = 640 / 2;
649 //  int cen_y = 480 / 2;
650     int text_h = 10;
651     int ladr_w2 = 60;
652 //  int ladr_h2 = 90;
653 //  int ladr_t = 35;
654     int compass_w = 200;
655 //  int gap = 10;
656
657     font_size = (current_options.get_xsize() > 1000) ? LARGE : SMALL;
658
659     HUD_style = 2;
660
661     FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
662
663 //  deque < instr_item * > :: iterator first = HUD_deque.begin();
664 //  deque < instr_item * > :: iterator last = HUD_deque.end();
665 //  HUD_deque.erase( first, last);  // empty the HUD deque  
666     HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
667
668     //  hud->code = 1;
669     //  hud->status = 0;
670
671     // For now lets just hardcode the hud here.
672     // In the future, hud information has to come from the same place
673     // aircraft information came from.
674
675     //  fgHUDSetTimeMode( hud, NIGHT );
676     //  fgHUDSetBrightness( hud, BRT_LIGHT );
677
678     //  index = 0;
679 //    index = 19;  
680
681     instr_item* p;
682
683 //      case 4:    // GYRO COMPASS
684     p =new hud_card( cen_x-(compass_w/2),
685                      max_y,
686                      compass_w,
687                      28,
688                      get_view_direction,
689                      HUDS_TOP,
690                      360, 0,
691                      1.0,
692                      5,   1,
693                      360,
694                      0,
695                      25,
696                      true);
697     HUD_deque.push_front( p );
698
699     p = new lat_label( (cen_x - compass_w/2)/2,
700                        max_y,
701                        0, text_h,
702                        get_latitude,
703                        "%s%", //"%.0f",
704                        "", //"Lat ",
705                        "",
706                        1.0,
707                        HUDS_TOP,
708                        CENTER_JUST,
709                        font_size,
710                        0,
711                        TRUE );
712     HUD_deque.push_front( p );
713     
714 //    p = new instr_label( 140, 450, 60, 10,
715 //           get_lat_min,
716 //           "%05.2f",
717 //           "",
718 //           NULL,
719 //           1.0,
720 //           HUDS_TOP,
721 //           CENTER_JUST,
722 //           font_size,
723 //           0,
724 //           TRUE );
725 //    HUD_deque.push_front( p );
726     
727     p = new lon_label(((cen_x+compass_w/2)+(2*cen_x))/2,
728                        max_y,
729                        1, text_h,
730                        get_longitude,
731                        "%s%",//"%.0f",
732                        "", //"Lon ",
733                        "",
734                        1.0,
735                        HUDS_TOP,
736                        CENTER_JUST,
737                        font_size,
738                        0,
739                        TRUE );
740     HUD_deque.push_front( p );
741     
742     int x_pos = 40;
743     
744     p = new instr_label( x_pos, 25, 60, 10,
745                          get_frame_rate,
746                          "%7.1f",
747                          "Frame rate =",
748                          NULL,
749                          1.0,
750                          HUDS_TOP,
751                          LEFT_JUST,
752                          font_size,
753                          0, 
754                          TRUE );
755     HUD_deque.push_front( p );
756
757     p = new instr_label( x_pos, 40, 120, 10,
758                          get_vfc_tris_culled,
759                          "%7.0f",
760                          "Culled       =",
761                          NULL,
762                          1.0,
763                          HUDS_TOP,
764                          LEFT_JUST,
765                          font_size,
766                          0,
767                          TRUE );
768     HUD_deque.push_front( p );
769
770     p = new instr_label( x_pos, 55, 120, 10,
771                          get_vfc_tris_drawn,
772                          "%7.0f",
773                          "Rendered   =",
774                          NULL,
775                          1.0,
776                          HUDS_TOP,
777                          LEFT_JUST,
778                          font_size,
779                          0,
780                          TRUE );
781     HUD_deque.push_front( p );
782     
783     p = new instr_label( x_pos, 70, 90, 10,
784                          get_fov,
785                          "%7.1f",
786                          "FOV          = ",
787                          NULL,
788                          1.0,
789                          HUDS_TOP,
790                          LEFT_JUST,
791                          font_size,
792                          0,
793                          TRUE );
794     HUD_deque.push_front( p );
795
796     x_pos = 480;
797     
798     p = new instr_label ( x_pos,
799                           70,
800                           60,
801                           10,
802                           get_aoa,
803                           "%7.2f",
804                           "AOA      ",
805                           " Deg",
806                           1.0,
807                           HUDS_TOP,
808                           LEFT_JUST,
809                           font_size,
810                           0,
811                           TRUE );
812     HUD_deque.push_front( p );
813
814     p = new instr_label( x_pos, 55, 40, 30,
815                          get_speed,
816                          "%5.0f",
817                          "Airspeed ",
818                          " Kts",
819                          1.0,
820                          HUDS_TOP,
821                          LEFT_JUST,
822                          font_size,
823                          0,
824                          TRUE );
825     HUD_deque.push_front( p );
826
827     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
828     strcpy(units, " ft");
829     } else {
830     strcpy(units, " m");
831     }
832     p = new instr_label( x_pos, 40, 40, 10,
833              get_altitude,
834              "%5.0f",
835              "Altitude ",
836              units,
837              1.0,
838              HUDS_TOP,
839              LEFT_JUST,
840              font_size,
841              0,
842              TRUE );
843     HUD_deque.push_front( p );
844
845     p = new instr_label( x_pos, 25, 40, 10,
846              get_agl,
847              "%5.0f",
848              "Elvation ",
849              units,
850              1.0,
851              HUDS_TOP,
852              LEFT_JUST,
853              font_size,
854              0,
855              TRUE );
856     HUD_deque.push_front( p );
857
858     p = new instr_label( x_pos, 10, 60, 10,
859              get_heading,
860              "%5.1f",
861              "Heading  ",
862              " Deg",
863              1.0,
864              HUDS_TOP,
865              LEFT_JUST,
866              font_size,
867              0,
868              TRUE );
869     HUD_deque.push_front( p );
870
871     p = new fgTBI_instr( 290, 55, 60, 10 ); // 270
872     HUD_deque.push_front( p );
873     
874     p = new  guage_instr( 270, //250,            // x
875                           390, //360, //400, //45, //420,            // y
876                           100,            // width
877                           20,            // height
878                           get_aileronval, // data source
879                           HUDS_BOTTOM | HUDS_NOTEXT,
880                           100.0,
881                           +1.0,
882                           -1.0);
883     HUD_deque.push_front( p );
884
885     p = new  guage_instr( 20,             // x
886                           240-50,             // y
887                           20,             // width
888                           100,             // height
889                           get_elevatorval, // data source
890                           HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
891                           -100.0,           // Scale data
892                           +1.0,           // Data Range
893                           -1.0);
894     HUD_deque.push_front( p );
895
896     p = new  guage_instr( 270, //250,             // x
897                           10+15,             // y
898                           100,             // width
899                           20,             // height
900                           get_rudderval,   // data source
901                           HUDS_TOP | HUDS_NOTEXT,
902                           100.0,
903                           +1.0,
904                           -1.0);
905     HUD_deque.push_front( p );
906
907     p = new  guage_instr( 600,             // x
908                           240-80,
909                           20,
910                           160,             // height
911                           get_throttleval, // data source
912                           HUDS_VERT | HUDS_LEFT | HUDS_NOTEXT,
913                           100.0,
914                           1.0,
915                           0.0);
916     HUD_deque.push_front( p );
917     
918     return 0;  // For now. Later we may use this for an error code.
919 }
920
921 int global_day_night_switch = DAY;
922
923 void HUD_brightkey( bool incr_bright )
924 {
925 instr_item *pHUDInstr = HUD_deque[0];
926 int brightness        = pHUDInstr->get_brightness();
927
928   if( current_options.get_hud_status() ) {
929     if( incr_bright ) {
930       switch (brightness) {
931         case BRT_LIGHT:
932           current_options.set_hud_status(0);
933           break;
934
935         case BRT_MEDIUM:
936           brightness = BRT_LIGHT;
937           break;
938
939         case BRT_DARK:
940           brightness = BRT_MEDIUM;
941           break;
942
943         case BRT_BLACK:
944           brightness = BRT_DARK;
945           break;
946
947         default:
948           brightness = BRT_BLACK;
949         }
950       }
951     else {
952       switch (brightness) {
953         case BRT_LIGHT:
954           brightness = BRT_MEDIUM;
955           break;
956
957         case BRT_MEDIUM:
958           brightness = BRT_DARK;
959           break;
960
961         case BRT_DARK:
962           brightness = BRT_BLACK;
963           break;
964
965         case BRT_BLACK:
966         default:
967           current_options.set_hud_status(0);
968         }
969       }
970     }
971   else {
972     current_options.set_hud_status(1);
973     if( incr_bright ) {
974       if( DAY == global_day_night_switch ) {
975         brightness = BRT_BLACK;
976         }
977       else {
978         brightness = BRT_DARK;
979         global_day_night_switch = DAY;
980         }
981       }
982     else {
983       if( NIGHT == global_day_night_switch ) {
984         brightness = BRT_DARK;
985         }
986       else {
987         brightness = BRT_MEDIUM;
988         global_day_night_switch = NIGHT;
989         }
990       }
991     }
992   pHUDInstr->SetBrightness( brightness );
993 }
994
995 // fgUpdateHUD
996 //
997 // Performs a once around the list of calls to instruments installed in
998 // the HUD object with requests for redraw. Kinda. It will when this is
999 // all C++.
1000 //
1001 void fgUpdateHUD( void ) {
1002   int brightness;
1003 //  int day_night_sw = current_aircraft.controls->day_night_switch;
1004   int day_night_sw = global_day_night_switch;
1005   int hud_displays = HUD_deque.size();
1006   instr_item *pHUDInstr;
1007   float line_width;
1008
1009   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
1010     return;
1011     }
1012
1013   HUD_TextList.erase();
1014   HUD_LineList.erase();
1015 //  HUD_StippleLineList.erase();
1016   
1017   pHUDInstr = HUD_deque[0];
1018   brightness = pHUDInstr->get_brightness();
1019 //  brightness = HUD_deque.at(0)->get_brightness();
1020
1021   glMatrixMode(GL_PROJECTION);
1022   glPushMatrix();
1023
1024   glLoadIdentity();
1025   gluOrtho2D(0, 640, 0, 480);
1026   glMatrixMode(GL_MODELVIEW);
1027   glPushMatrix();
1028   glLoadIdentity();
1029
1030   glColor3f(1.0, 1.0, 1.0);
1031   glIndexi(7);
1032
1033   glDisable(GL_DEPTH_TEST);
1034   glDisable(GL_LIGHTING);
1035
1036   // We can do translucency, so why not. :-)
1037 //  glEnable    ( GL_BLEND ) ;
1038 //  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1039   
1040   if( day_night_sw == DAY) {
1041       switch (brightness) {
1042           case BRT_LIGHT:
1043 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1044             glColor3f (0.1, 0.9, 0.1);
1045             break;
1046
1047           case BRT_MEDIUM:
1048 //            glColor4f (0.1, 0.7, 0.0, 0.75);
1049             glColor3f (0.1, 0.7, 0.0);
1050             break;
1051
1052           case BRT_DARK:
1053 //            glColor4f (0.0, 0.6, 0.0, 0.75);
1054             glColor3f(0.0, 0.6, 0.0);
1055             break;
1056
1057           case BRT_BLACK:
1058 //            glColor4f( 0.0, 0.0, 0.0, 0.75);
1059             glColor3f( 0.0, 0.0, 0.0);
1060             break;
1061
1062           default:;
1063       }
1064   }
1065   else {
1066       if( day_night_sw == NIGHT) {
1067           switch (brightness) {
1068               case BRT_LIGHT:
1069 //                glColor4f (0.9, 0.1, 0.1, 0.75);
1070                 glColor3f (0.9, 0.1, 0.1);
1071                 break;
1072
1073               case BRT_MEDIUM:
1074 //                glColor4f (0.7, 0.0, 0.1, 0.75);
1075                 glColor3f (0.7, 0.0, 0.1);
1076                 break;
1077
1078               case BRT_DARK:
1079               default:
1080 //                glColor4f (0.6, 0.0, 0.0, 0.75);
1081                   glColor3f (0.6, 0.0, 0.0);
1082           }
1083       }
1084           else {     // Just in case default
1085 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1086               glColor3f (0.1, 0.9, 0.1);
1087           }
1088   }
1089
1090   deque < instr_item * > :: iterator current = HUD_deque.begin();
1091   deque < instr_item * > :: iterator last = HUD_deque.end();
1092
1093   for ( ; current != last; ++current ) {
1094       pHUDInstr = *current;
1095
1096       if( pHUDInstr->enabled()) {
1097           //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1098           //            hud->code, hud->status );
1099           pHUDInstr->draw();
1100 //        HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1101                               // No broken displays honored just now.
1102       }
1103   }
1104
1105   char *gmt_str = get_formated_gmt_time();
1106   HUD_TextList.add( fgText( 40, 10, gmt_str ) );
1107   
1108   HUD_TextList.draw();
1109
1110   line_width = (current_options.get_xsize() > 1000) ? 1.0 : 0.5;
1111   glLineWidth(line_width);
1112   HUD_LineList.draw();
1113
1114 //  glEnable(GL_LINE_STIPPLE);
1115 //  glLineStipple( 1, 0x00FF );
1116 //  HUD_StippleLineList.draw();
1117 //  glDisable(GL_LINE_STIPPLE);
1118
1119 //  glDisable( GL_BLEND );
1120   
1121   glEnable(GL_DEPTH_TEST);
1122   glEnable(GL_LIGHTING);
1123   glMatrixMode(GL_PROJECTION);
1124   glPopMatrix();
1125   glMatrixMode(GL_MODELVIEW);
1126   glPopMatrix();
1127 }