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