]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud.cxx
Allow aircraft model file to be specified from the command line.
[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     p = new HudLadder( cen_x-ladr_w2, cen_y-ladr_h2, 2*ladr_w2, 2*ladr_h2, 1 );
685     HUD_deque.push_front( p );
686
687 //      case 4:    // GYRO COMPASS
688     p =new hud_card( cen_x-(compass_w/2),
689                      max_y,
690                      compass_w,
691                      28,
692                      get_view_direction,
693                      HUDS_TOP,
694                      360, 0,
695                      1.0,
696                      5,   1,
697                      360,
698                      0,
699                      25,
700                      true);
701     HUD_deque.push_front( p );
702
703     p = new lat_label( (cen_x - compass_w/2)/2,
704                        max_y,
705                        0, text_h,
706                        get_latitude,
707                        "%s%", //"%.0f",
708                        "", //"Lat ",
709                        "",
710                        1.0,
711                        HUDS_TOP,
712                        CENTER_JUST,
713                        font_size,
714                        0,
715                        TRUE );
716     HUD_deque.push_front( p );
717     
718 //    p = new instr_label( 140, 450, 60, 10,
719 //           get_lat_min,
720 //           "%05.2f",
721 //           "",
722 //           NULL,
723 //           1.0,
724 //           HUDS_TOP,
725 //           CENTER_JUST,
726 //           font_size,
727 //           0,
728 //           TRUE );
729 //    HUD_deque.push_front( p );
730     
731     p = new lon_label(((cen_x+compass_w/2)+(2*cen_x))/2,
732                        max_y,
733                        1, text_h,
734                        get_longitude,
735                        "%s%",//"%.0f",
736                        "", //"Lon ",
737                        "",
738                        1.0,
739                        HUDS_TOP,
740                        CENTER_JUST,
741                        font_size,
742                        0,
743                        TRUE );
744     HUD_deque.push_front( p );
745     
746     int x_pos = 40;
747     
748     p = new instr_label( x_pos, 25, 60, 10,
749                          get_frame_rate,
750                          "%7.1f",
751                          "Frame rate =",
752                          NULL,
753                          1.0,
754                          HUDS_TOP,
755                          LEFT_JUST,
756                          font_size,
757                          0, 
758                          TRUE );
759     HUD_deque.push_front( p );
760 #if 0
761     p = new instr_label( x_pos, 40, 120, 10,
762                          get_vfc_tris_culled,
763                          "%7.0f",
764                          "Culled       =",
765                          NULL,
766                          1.0,
767                          HUDS_TOP,
768                          LEFT_JUST,
769                          font_size,
770                          0,
771                          TRUE );
772     HUD_deque.push_front( p );
773
774     p = new instr_label( x_pos, 55, 120, 10,
775                          get_vfc_tris_drawn,
776                          "%7.0f",
777                          "Rendered   =",
778                          NULL,
779                          1.0,
780                          HUDS_TOP,
781                          LEFT_JUST,
782                          font_size,
783                          0,
784                          TRUE );
785     HUD_deque.push_front( p );
786 #endif // 0
787         
788 //    p = new instr_label( x_pos, 70, 90, 10,
789     p = new instr_label( x_pos, 40, 90, 10,
790                          get_fov,
791                          "%7.1f",
792                          "FOV          = ",
793                          NULL,
794                          1.0,
795                          HUDS_TOP,
796                          LEFT_JUST,
797                          font_size,
798                          0,
799                          TRUE );
800     HUD_deque.push_front( p );
801
802     x_pos = 480;
803     
804     p = new instr_label ( x_pos,
805                           70,
806                           60,
807                           10,
808                           get_aoa,
809                           "%7.2f",
810                           "AOA      ",
811                           " Deg",
812                           1.0,
813                           HUDS_TOP,
814                           LEFT_JUST,
815                           font_size,
816                           0,
817                           TRUE );
818     HUD_deque.push_front( p );
819
820     p = new instr_label( x_pos, 55, 40, 30,
821                          get_speed,
822                          "%5.0f",
823                          "Airspeed ",
824                          " Kts",
825                          1.0,
826                          HUDS_TOP,
827                          LEFT_JUST,
828                          font_size,
829                          0,
830                          TRUE );
831     HUD_deque.push_front( p );
832
833     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
834     strcpy(units, " ft");
835     } else {
836     strcpy(units, " m");
837     }
838     p = new instr_label( x_pos, 40, 40, 10,
839              get_altitude,
840              "%5.0f",
841              "Altitude ",
842              units,
843              1.0,
844              HUDS_TOP,
845              LEFT_JUST,
846              font_size,
847              0,
848              TRUE );
849     HUD_deque.push_front( p );
850
851     p = new instr_label( x_pos, 25, 40, 10,
852              get_agl,
853              "%5.0f",
854              "Elvation ",
855              units,
856              1.0,
857              HUDS_TOP,
858              LEFT_JUST,
859              font_size,
860              0,
861              TRUE );
862     HUD_deque.push_front( p );
863
864     p = new instr_label( x_pos, 10, 60, 10,
865              get_heading,
866              "%5.1f",
867              "Heading  ",
868              " Deg",
869              1.0,
870              HUDS_TOP,
871              LEFT_JUST,
872              font_size,
873              0,
874              TRUE );
875     HUD_deque.push_front( p );
876
877     p = new fgTBI_instr( 290, 55, 60, 10 ); // 270
878     HUD_deque.push_front( p );
879     
880     p = new  guage_instr( 270, //250,            // x
881                           390, //360, //400, //45, //420,            // y
882                           100,            // width
883                           20,            // height
884                           get_aileronval, // data source
885                           HUDS_BOTTOM | HUDS_NOTEXT,
886                           100.0,
887                           +1.0,
888                           -1.0);
889     HUD_deque.push_front( p );
890
891     p = new  guage_instr( 20,             // x
892                           240-50,             // y
893                           20,             // width
894                           100,             // height
895                           get_elevatorval, // data source
896                           HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
897                           -100.0,           // Scale data
898                           +1.0,           // Data Range
899                           -1.0);
900     HUD_deque.push_front( p );
901
902     p = new  guage_instr( 270, //250,             // x
903                           10+15,             // y
904                           100,             // width
905                           20,             // height
906                           get_rudderval,   // data source
907                           HUDS_TOP | HUDS_NOTEXT,
908                           100.0,
909                           +1.0,
910                           -1.0);
911     HUD_deque.push_front( p );
912
913     p = new  guage_instr( 600,             // x
914                           240-80,
915                           20,
916                           160,             // height
917                           get_throttleval, // data source
918                           HUDS_VERT | HUDS_LEFT | HUDS_NOTEXT,
919                           100.0,
920                           1.0,
921                           0.0);
922     HUD_deque.push_front( p );
923     
924     return 0;  // For now. Later we may use this for an error code.
925 }
926
927 int global_day_night_switch = DAY;
928
929 void HUD_brightkey( bool incr_bright )
930 {
931 instr_item *pHUDInstr = HUD_deque[0];
932 int brightness        = pHUDInstr->get_brightness();
933
934   if( current_options.get_hud_status() ) {
935     if( incr_bright ) {
936       switch (brightness) {
937         case BRT_LIGHT:
938           current_options.set_hud_status(0);
939           break;
940
941         case BRT_MEDIUM:
942           brightness = BRT_LIGHT;
943           break;
944
945         case BRT_DARK:
946           brightness = BRT_MEDIUM;
947           break;
948
949         case BRT_BLACK:
950           brightness = BRT_DARK;
951           break;
952
953         default:
954           brightness = BRT_BLACK;
955         }
956       }
957     else {
958       switch (brightness) {
959         case BRT_LIGHT:
960           brightness = BRT_MEDIUM;
961           break;
962
963         case BRT_MEDIUM:
964           brightness = BRT_DARK;
965           break;
966
967         case BRT_DARK:
968           brightness = BRT_BLACK;
969           break;
970
971         case BRT_BLACK:
972         default:
973           current_options.set_hud_status(0);
974         }
975       }
976     }
977   else {
978     current_options.set_hud_status(1);
979     if( incr_bright ) {
980       if( DAY == global_day_night_switch ) {
981         brightness = BRT_BLACK;
982         }
983       else {
984         brightness = BRT_DARK;
985         global_day_night_switch = DAY;
986         }
987       }
988     else {
989       if( NIGHT == global_day_night_switch ) {
990         brightness = BRT_DARK;
991         }
992       else {
993         brightness = BRT_MEDIUM;
994         global_day_night_switch = NIGHT;
995         }
996       }
997     }
998   pHUDInstr->SetBrightness( brightness );
999 }
1000
1001 #if 0
1002 // fgUpdateHUD
1003 //
1004 // Performs a once around the list of calls to instruments installed in
1005 // the HUD object with requests for redraw. Kinda. It will when this is
1006 // all C++.
1007 //
1008 void fgUpdateHUD( void ) {
1009   int brightness;
1010 //  int day_night_sw = current_aircraft.controls->day_night_switch;
1011   int day_night_sw = global_day_night_switch;
1012   int hud_displays = HUD_deque.size();
1013   instr_item *pHUDInstr;
1014   float line_width;
1015
1016   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
1017     return;
1018     }
1019
1020   HUD_TextList.erase();
1021   HUD_LineList.erase();
1022 //  HUD_StippleLineList.erase();
1023   
1024   pHUDInstr = HUD_deque[0];
1025   brightness = pHUDInstr->get_brightness();
1026 //  brightness = HUD_deque.at(0)->get_brightness();
1027
1028   glMatrixMode(GL_PROJECTION);
1029   glPushMatrix();
1030
1031   glLoadIdentity();
1032   gluOrtho2D(0, 640, 0, 480);
1033   glMatrixMode(GL_MODELVIEW);
1034   glPushMatrix();
1035   glLoadIdentity();
1036
1037   glColor3f(1.0, 1.0, 1.0);
1038   glIndexi(7);
1039
1040   glDisable(GL_DEPTH_TEST);
1041   glDisable(GL_LIGHTING);
1042
1043   // We can do translucency, so why not. :-)
1044 //  glEnable    ( GL_BLEND ) ;
1045 //  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1046   
1047   if( day_night_sw == DAY) {
1048       switch (brightness) {
1049           case BRT_LIGHT:
1050 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1051             glColor3f (0.1, 0.9, 0.1);
1052             break;
1053
1054           case BRT_MEDIUM:
1055 //            glColor4f (0.1, 0.7, 0.0, 0.75);
1056             glColor3f (0.1, 0.7, 0.0);
1057             break;
1058
1059           case BRT_DARK:
1060 //            glColor4f (0.0, 0.6, 0.0, 0.75);
1061             glColor3f(0.0, 0.6, 0.0);
1062             break;
1063
1064           case BRT_BLACK:
1065 //            glColor4f( 0.0, 0.0, 0.0, 0.75);
1066             glColor3f( 0.0, 0.0, 0.0);
1067             break;
1068
1069           default:;
1070       }
1071   }
1072   else {
1073       if( day_night_sw == NIGHT) {
1074           switch (brightness) {
1075               case BRT_LIGHT:
1076 //                glColor4f (0.9, 0.1, 0.1, 0.75);
1077                 glColor3f (0.9, 0.1, 0.1);
1078                 break;
1079
1080               case BRT_MEDIUM:
1081 //                glColor4f (0.7, 0.0, 0.1, 0.75);
1082                 glColor3f (0.7, 0.0, 0.1);
1083                 break;
1084
1085               case BRT_DARK:
1086               default:
1087 //                glColor4f (0.6, 0.0, 0.0, 0.75);
1088                   glColor3f (0.6, 0.0, 0.0);
1089           }
1090       }
1091           else {     // Just in case default
1092 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1093               glColor3f (0.1, 0.9, 0.1);
1094           }
1095   }
1096
1097   deque < instr_item * > :: iterator current = HUD_deque.begin();
1098   deque < instr_item * > :: iterator last = HUD_deque.end();
1099
1100   for ( ; current != last; ++current ) {
1101       pHUDInstr = *current;
1102
1103       if( pHUDInstr->enabled()) {
1104           //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1105           //            hud->code, hud->status );
1106           pHUDInstr->draw();
1107 //        HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1108                               // No broken displays honored just now.
1109       }
1110   }
1111
1112   char *gmt_str = get_formated_gmt_time();
1113   HUD_TextList.add( fgText( 40, 10, gmt_str) );
1114
1115 #ifdef FG_NETWORK_OLK
1116   if ( net_hud_display ) {
1117       net_hud_update();
1118   }
1119 #endif
1120
1121   HUD_TextList.draw();
1122
1123   line_width = (current_options.get_xsize() > 1000) ? 1.0 : 0.5;
1124   glLineWidth(line_width);
1125   HUD_LineList.draw();
1126
1127 //  glEnable(GL_LINE_STIPPLE);
1128 //  glLineStipple( 1, 0x00FF );
1129 //  HUD_StippleLineList.draw();
1130 //  glDisable(GL_LINE_STIPPLE);
1131
1132 //  glDisable( GL_BLEND );
1133   
1134   glEnable(GL_DEPTH_TEST);
1135   glEnable(GL_LIGHTING);
1136   glMatrixMode(GL_PROJECTION);
1137   glPopMatrix();
1138   glMatrixMode(GL_MODELVIEW);
1139   glPopMatrix();
1140 }
1141 #endif
1142
1143
1144 // fgUpdateHUD
1145 //
1146 // Performs a once around the list of calls to instruments installed in
1147 // the HUD object with requests for redraw. Kinda. It will when this is
1148 // all C++.
1149 //
1150 void fgUpdateHUD( void ) {
1151   int brightness;
1152 //  int day_night_sw = current_aircraft.controls->day_night_switch;
1153   int day_night_sw = global_day_night_switch;
1154   int hud_displays = HUD_deque.size();
1155   instr_item *pHUDInstr;
1156   float line_width;
1157
1158   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
1159     return;
1160     }
1161
1162   HUD_TextList.erase();
1163   HUD_LineList.erase();
1164 //  HUD_StippleLineList.erase();
1165   
1166   pHUDInstr = HUD_deque[0];
1167   brightness = pHUDInstr->get_brightness();
1168 //  brightness = HUD_deque.at(0)->get_brightness();
1169
1170   glMatrixMode(GL_PROJECTION);
1171   glPushMatrix();
1172
1173   glLoadIdentity();
1174   gluOrtho2D(0, 640, 0, 480);
1175   glMatrixMode(GL_MODELVIEW);
1176   glPushMatrix();
1177   glLoadIdentity();
1178
1179   glColor3f(1.0, 1.0, 1.0);
1180   glIndexi(7);
1181
1182   glDisable(GL_DEPTH_TEST);
1183   glDisable(GL_LIGHTING);
1184
1185   // We can do translucency, so why not. :-)
1186 //  glEnable    ( GL_BLEND ) ;
1187 //  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1188   
1189   if( day_night_sw == DAY) {
1190           switch (brightness) {
1191                   case BRT_LIGHT:
1192 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1193             glColor3f (0.1, 0.9, 0.1);
1194             break;
1195
1196           case BRT_MEDIUM:
1197 //            glColor4f (0.1, 0.7, 0.0, 0.75);
1198             glColor3f (0.1, 0.7, 0.0);
1199             break;
1200
1201           case BRT_DARK:
1202 //            glColor4f (0.0, 0.6, 0.0, 0.75);
1203             glColor3f(0.0, 0.6, 0.0);
1204             break;
1205
1206           case BRT_BLACK:
1207 //            glColor4f( 0.0, 0.0, 0.0, 0.75);
1208             glColor3f( 0.0, 0.0, 0.0);
1209             break;
1210
1211           default:;
1212           }
1213   }
1214   else {
1215           if( day_night_sw == NIGHT) {
1216                   switch (brightness) {
1217                           case BRT_LIGHT:
1218 //                glColor4f (0.9, 0.1, 0.1, 0.75);
1219                 glColor3f (0.9, 0.1, 0.1);
1220                 break;
1221
1222               case BRT_MEDIUM:
1223 //                glColor4f (0.7, 0.0, 0.1, 0.75);
1224                 glColor3f (0.7, 0.0, 0.1);
1225                 break;
1226
1227                           case BRT_DARK:
1228                           default:
1229 //                                glColor4f (0.6, 0.0, 0.0, 0.75);
1230                                   glColor3f (0.6, 0.0, 0.0);
1231                   }
1232           }
1233           else {     // Just in case default
1234 //                        glColor4f (0.1, 0.9, 0.1, 0.75);
1235                           glColor3f (0.1, 0.9, 0.1);
1236                   }
1237   }
1238
1239   deque < instr_item * > :: iterator current = HUD_deque.begin();
1240   deque < instr_item * > :: iterator last = HUD_deque.end();
1241
1242   for ( ; current != last; ++current ) {
1243           pHUDInstr = *current;
1244
1245           if( pHUDInstr->enabled()) {
1246                   //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1247                   //            hud->code, hud->status );
1248                   pHUDInstr->draw();
1249 //            HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1250                               // No broken displays honored just now.
1251           }
1252   }
1253
1254   char *gmt_str = get_formated_gmt_time();
1255   HUD_TextList.add( fgText(40, 10, gmt_str) );
1256
1257   // temporary
1258   extern bool fgAPAltitudeEnabled( void );
1259   extern bool fgAPHeadingEnabled( void );
1260   extern bool fgAPWayPointEnabled( void );
1261   extern char *fgAPget_TargetDistanceStr( void );
1262   extern char *fgAPget_TargetHeadingStr( void );
1263   extern char *fgAPget_TargetAltitudeStr( void );
1264   extern char *fgAPget_TargetLatLonStr( void );
1265
1266   int apY = 480 - 80;
1267 //  char scratch[128];
1268 //  HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
1269 //  apY -= 15;
1270   if( fgAPHeadingEnabled() ) {
1271           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetHeadingStr()) );       
1272           apY -= 15;
1273   }
1274   if( fgAPAltitudeEnabled() ) {
1275           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetAltitudeStr()) );      
1276           apY -= 15;
1277   }
1278   if( fgAPWayPointEnabled() ) {
1279           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetLatLonStr()) );
1280           apY -= 15;
1281           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetDistanceStr() ) );     
1282           apY -= 15;
1283   }
1284   
1285   HUD_TextList.draw();
1286
1287   line_width = (current_options.get_xsize() > 1000) ? 1.0 : 0.5;
1288   glLineWidth(line_width);
1289   HUD_LineList.draw();
1290
1291 //  glEnable(GL_LINE_STIPPLE);
1292 //  glLineStipple( 1, 0x00FF );
1293 //  HUD_StippleLineList.draw();
1294 //  glDisable(GL_LINE_STIPPLE);
1295
1296 //  glDisable( GL_BLEND );
1297   
1298   glEnable(GL_DEPTH_TEST);
1299   glEnable(GL_LIGHTING);
1300   glMatrixMode(GL_PROJECTION);
1301   glPopMatrix();
1302   glMatrixMode(GL_MODELVIEW);
1303   glPopMatrix();
1304 }
1305