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