]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud.cxx
d4f753855fae1238df5d9c1a1738445d5c652f31
[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 <NetworkOLK/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   
337  
338   HUD_deque.insert( HUD_deque.begin(), HIptr);
339     
340
341 //      case 10:    // Digital Mach number
342         HIptr = (instr_item *) new instr_label ( min_x , //same as speed tape
343                                                  cen_y-(compass_w/2) -10, //below speed tape
344                                                   40,
345                                                   30,
346                                                  get_mach,
347                                                  "%4.2f",
348                                                  "",
349                                                  NULL,
350                                                  1.0,
351                                                  HUDS_TOP,
352                                                  RIGHT_JUST,
353                                                  font_size,
354                                                  0,
355                                                  TRUE );
356   HUD_deque.insert( HUD_deque.begin(), HIptr);
357
358 //      case 9:
359   HIptr = (instr_item *) new  guage_instr( min_x-10,           // x
360                                            cen_y -75,       // y 
361                                            20,              // width
362                                            150,             // height
363                                            get_throttleval, // data source
364 //                                         HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
365                                            HUDS_VERT | HUDS_LEFT | HUDS_NOTEXT,                                        100.0,
366                                            1.0,
367                                            0.0
368                                           );
369   HUD_deque.insert( HUD_deque.begin(), HIptr);
370 // Remove this when below uncommented       
371 //      case 10:
372   HIptr = (instr_item *) new instr_label( 10,
373                                           25,
374                                           60,
375                                           10,
376                                           get_frame_rate,
377                                           "%5.1f",
378                                           "",
379                                           NULL,
380                                           1.0,
381                                           HUDS_TOP,
382                                           RIGHT_JUST,
383                                           font_size,
384                                           0,
385                                           TRUE );
386   HUD_deque.insert( HUD_deque.begin(), HIptr);
387   
388   HIptr = (instr_item *) new lat_label(  (cen_x - (compass_w/2))/2,
389                                           max_y,    
390                                           1,
391                                           text_h,
392                                           get_latitude,
393                                           "%s%", //"%.0f",
394                                           "", //"Lat ",
395                                           "",
396                                           1.0,
397                                           HUDS_TOP,
398                                           CENTER_JUST,
399                                           font_size,
400                                           0,
401                                           TRUE );
402   HUD_deque.insert( HUD_deque.begin(), HIptr);
403     
404     HIptr = (instr_item *) new lon_label(((cen_x+compass_w/2)+(2*cen_x))/2,
405                                           max_y,
406                                           1, text_h,
407                                           get_longitude,
408                                           "%s%",//"%.0f",
409                                           "", //"Lon ", 
410                                           "",
411                                           1.0,
412                                           HUDS_TOP,
413                                           CENTER_JUST,
414                                           font_size,
415                                           0,
416                                           TRUE );
417   HUD_deque.insert( HUD_deque.begin(), HIptr);
418     
419 /*
420 //      case 10:    // Digital KIAS
421         HIptr = (instr_item *) new instr_label ( 110,
422                                                  150,
423                                                   40,
424                                                   30,
425                                                  get_speed,
426                                                  "%5.0f",
427                                                  NULL,
428                                                  " Kts",
429                                                  1.0,
430                                                  HUDS_TOP,
431                                                  RIGHT_JUST,
432                                                  font_size,
433                                                  0,
434                                                  TRUE );
435   HUD_deque.insert( HUD_deque.begin(), HIptr);
436
437 //      case 11:    // Digital Rate of Climb
438         HIptr = (instr_item *) new instr_label ( 110,
439                                                  135,
440                                                   40,
441                                                   10,
442                                                  get_climb_rate,
443                                                  "%5.0f",
444                                                  " Climb",
445                                                  NULL,
446                                                  1.0,
447                                                  HUDS_TOP,
448                                                  RIGHT_JUST,
449                                                  font_size,
450                                                  0,
451                                                  TRUE );
452   HUD_deque.insert( HUD_deque.begin(), HIptr);
453
454 //      case 12:    // Roll indication diagnostic
455         HIptr = (instr_item *) new instr_label ( 110,
456                                                  120,
457                                                   40,
458                                                   10,
459                                                  get_roll,
460                                                  "%5.2f",
461                                                  " Roll",
462                                                  " Deg",
463                                                  1.0,
464                                                  HUDS_TOP,
465                                                  RIGHT_JUST,
466                                                  font_size,
467                                                  0,
468                                                  TRUE );
469   HUD_deque.insert( HUD_deque.begin(), HIptr);
470
471 //      case 13:    // Angle of attack diagnostic
472         HIptr = (instr_item *) new instr_label ( 440,
473                                                  150,
474                                                   60,
475                                                   10,
476                                                  get_aoa,
477                                                  "      %5.2f",
478                                                  "AOA",
479                                                  " Deg",
480                                                  1.0,
481                                                  HUDS_TOP,
482                                                  RIGHT_JUST,
483                                                  font_size,
484                                                  0,
485                                                  TRUE );
486   HUD_deque.insert( HUD_deque.begin(), HIptr);
487
488 //      case 14:
489         HIptr = (instr_item *) new instr_label ( 440,
490                                                  135,
491                                                   60,
492                                                   10,
493                                                  get_heading,
494                                                  " %5.1f",
495                                                  "Heading ",
496                                                  " Deg",
497                                                  1.0,
498                                                  HUDS_TOP,
499                                                  RIGHT_JUST,
500                                                  font_size,
501                                                  0,
502                                                  TRUE );
503   HUD_deque.insert( HUD_deque.begin(), HIptr);
504
505 //      case 15:
506         HIptr = (instr_item *) new instr_label ( 440,
507                                                  120,
508                                                   60,
509                                                   10,
510                                                  get_sideslip,
511                                                  "%5.2f",
512                                                  "Sideslip ",
513                                                  NULL,
514                                                  1.0,
515                                                  HUDS_TOP,
516                                                  RIGHT_JUST,
517                                                  font_size,
518                                                  0,
519                                                  TRUE );
520   HUD_deque.insert( HUD_deque.begin(), HIptr);
521
522 //      case 16:
523         HIptr = (instr_item *) new instr_label( 440,
524                                                 100,
525                                                  60,
526                                                  10,
527                                                 get_throttleval,
528                                                 "%5.2f",
529                                                 "Throttle ",
530                                                 NULL,
531                                                  1.0,
532                                                 HUDS_TOP,
533                                                 RIGHT_JUST,
534                                                 font_size,
535                                                 0,
536                                                 TRUE );
537   HUD_deque.insert( HUD_deque.begin(), HIptr);
538
539 //      case 17:
540         HIptr = (instr_item *) new instr_label( 440,
541                                                  85,
542                                                  60,
543                                                  10,
544                                                 get_elevatorval,
545                                                 "%5.2f",
546                                                 "Elevator ",
547                                                 NULL,
548                                                  1.0,
549                                                 HUDS_TOP,
550                                                 RIGHT_JUST,
551                                                 font_size,
552                                                 0,
553                                                 TRUE );
554   HUD_deque.insert( HUD_deque.begin(), HIptr);
555
556 //      case 18:
557         HIptr = (instr_item *) new instr_label( 440,
558                                                  60,
559                                                  60,
560                                                  10,
561                                                 get_aileronval,
562                                                 "%5.2f",
563                                                 "Aileron  ",
564                                                 NULL,
565                                                  1.0,
566                                                 HUDS_TOP,
567                                                 RIGHT_JUST,
568                                                 font_size,
569                                                 0,
570                                                 TRUE );
571   HUD_deque.insert( HUD_deque.begin(), HIptr);
572
573 //      case 19:
574         HIptr = (instr_item *) new instr_label( 10,
575                                                 10,
576                                                 60,
577                                                 10,
578                                                  get_frame_rate,
579                                                 "%.1f",
580                                                 "Frame rate = ",
581                                                 NULL,
582                                                  1.0,
583                                                 HUDS_TOP,
584                                                 RIGHT_JUST,
585                                                 font_size,
586                                                 0,
587                                                 TRUE );
588   HUD_deque.insert( HUD_deque.begin(), HIptr);
589
590 //      case 20:
591       switch( current_options.get_tris_or_culled() ) {
592       case 0:
593           HIptr = (instr_item *) new instr_label( 10,
594                               25,
595                               120,
596                               10,
597                               get_vfc_tris_drawn,
598                               "%.0f",
599                               "Tris Rendered = ",
600                               NULL,
601                               1.0,
602                               HUDS_TOP,
603                               RIGHT_JUST,
604                               font_size,
605                               0,
606                               TRUE );
607           break;
608       case 1:
609           HIptr = (instr_item *) new instr_label( 10,
610                               25,
611                               90,
612                               10,
613                               get_vfc_ratio,
614                               "%.2f",
615                               "VFC Ratio = ",
616                               NULL,
617                               1.0,
618                               HUDS_TOP,
619                               RIGHT_JUST,
620                               font_size,
621                               0,
622                               TRUE );
623           break;
624       }
625       break;
626
627 //      case 21:
628         HIptr = (instr_item *) new instr_label( 10,
629                                                 40,
630                                                 90,
631                                                 10,
632                                                 get_fov,
633                                                 "%.1f",
634                                                 "FOV = ",
635                                                 NULL,
636                         1.0,
637                                                 HUDS_TOP,
638                                                 RIGHT_JUST,
639                                                 font_size,
640                                                 0,
641                                                 TRUE );
642   HUD_deque.insert( HUD_deque.begin(), HIptr);
643 */
644 //      default:
645 //        HIptr = 0;;
646 //      }
647 //    if( HIptr ) {                   // Anything to install?
648 //      HUD_deque.insert( HUD_deque.begin(), HIptr);
649 //      }
650 //    index++;
651 //    }
652 //  while( HIptr );
653
654   return 0;  // For now. Later we may use this for an error code.
655
656 }
657
658 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
659 {
660 //    instr_item *HIptr;
661 //    int index;
662     int font_size;
663
664     int off = 50;
665 //  int min_x = off;
666 //  int max_x = 640-off;
667 //  int min_y = off;
668     int max_y = 480-off;
669     int cen_x = 640 / 2;
670     int cen_y = 480 / 2;
671     int text_h = 10;
672     int ladr_w2 = 60;
673     int ladr_h2 = 90;
674 //  int ladr_t = 35;
675     int compass_w = 200;
676 //  int gap = 10;
677
678     font_size = (current_options.get_xsize() > 1000) ? LARGE : SMALL;
679
680     HUD_style = 2;
681
682     FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
683
684 //  deque < instr_item * > :: iterator first = HUD_deque.begin();
685 //  deque < instr_item * > :: iterator last = HUD_deque.end();
686 //  HUD_deque.erase( first, last);  // empty the HUD deque  
687     HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
688
689     //  hud->code = 1;
690     //  hud->status = 0;
691
692     // For now lets just hardcode the hud here.
693     // In the future, hud information has to come from the same place
694     // aircraft information came from.
695
696     //  fgHUDSetTimeMode( hud, NIGHT );
697     //  fgHUDSetBrightness( hud, BRT_LIGHT );
698
699     //  index = 0;
700 //    index = 19;  
701
702     instr_item* p;
703
704     p = new HudLadder( cen_x-ladr_w2, cen_y-ladr_h2, 2*ladr_w2, 2*ladr_h2, 1 );
705     HUD_deque.push_front( p );
706
707 //      case 4:    // GYRO COMPASS
708     p =new hud_card( cen_x-(compass_w/2),
709                      max_y,
710                      compass_w,
711                      28,
712                      get_view_direction,
713                      HUDS_TOP,
714                      360, 0,
715                      1.0,
716                      5,   1,
717                      360,
718                      0,
719                      25,
720                      true);
721     HUD_deque.push_front( p );
722
723     p = new lat_label( (cen_x - compass_w/2)/2,
724                        max_y,
725                        0, text_h,
726                        get_latitude,
727                        "%s%", //"%.0f",
728                        "", //"Lat ",
729                        "",
730                        1.0,
731                        HUDS_TOP,
732                        CENTER_JUST,
733                        font_size,
734                        0,
735                        TRUE );
736     HUD_deque.push_front( p );
737     
738 //    p = new instr_label( 140, 450, 60, 10,
739 //           get_lat_min,
740 //           "%05.2f",
741 //           "",
742 //           NULL,
743 //           1.0,
744 //           HUDS_TOP,
745 //           CENTER_JUST,
746 //           font_size,
747 //           0,
748 //           TRUE );
749 //    HUD_deque.push_front( p );
750     
751     p = new lon_label(((cen_x+compass_w/2)+(2*cen_x))/2,
752                        max_y,
753                        1, text_h,
754                        get_longitude,
755                        "%s%",//"%.0f",
756                        "", //"Lon ",
757                        "",
758                        1.0,
759                        HUDS_TOP,
760                        CENTER_JUST,
761                        font_size,
762                        0,
763                        TRUE );
764     HUD_deque.push_front( p );
765     
766     int x_pos = 40;
767     
768     p = new instr_label( x_pos, 25, 60, 10,
769                          get_frame_rate,
770                          "%7.1f",
771                          "Frame rate =",
772                          NULL,
773                          1.0,
774                          HUDS_TOP,
775                          LEFT_JUST,
776                          font_size,
777                          0, 
778                          TRUE );
779     HUD_deque.push_front( p );
780 #if 0
781     p = new instr_label( x_pos, 40, 120, 10,
782                          get_vfc_tris_culled,
783                          "%7.0f",
784                          "Culled       =",
785                          NULL,
786                          1.0,
787                          HUDS_TOP,
788                          LEFT_JUST,
789                          font_size,
790                          0,
791                          TRUE );
792     HUD_deque.push_front( p );
793
794     p = new instr_label( x_pos, 55, 120, 10,
795                          get_vfc_tris_drawn,
796                          "%7.0f",
797                          "Rendered   =",
798                          NULL,
799                          1.0,
800                          HUDS_TOP,
801                          LEFT_JUST,
802                          font_size,
803                          0,
804                          TRUE );
805     HUD_deque.push_front( p );
806 #endif // 0
807         
808 //    p = new instr_label( x_pos, 70, 90, 10,
809     p = new instr_label( x_pos, 40, 90, 10,
810                          get_fov,
811                          "%7.1f",
812                          "FOV          = ",
813                          NULL,
814                          1.0,
815                          HUDS_TOP,
816                          LEFT_JUST,
817                          font_size,
818                          0,
819                          TRUE );
820     HUD_deque.push_front( p );
821
822     x_pos = 480;
823     
824     p = new instr_label ( x_pos,
825                           70,
826                           60,
827                           10,
828                           get_aoa,
829                           "%7.2f",
830                           "AOA      ",
831                           " Deg",
832                           1.0,
833                           HUDS_TOP,
834                           LEFT_JUST,
835                           font_size,
836                           0,
837                           TRUE );
838     HUD_deque.push_front( p );
839
840     p = new instr_label( x_pos, 55, 40, 30,
841                          get_speed,
842                          "%5.0f",
843                          "Airspeed ",
844                          " Kts",
845                          1.0,
846                          HUDS_TOP,
847                          LEFT_JUST,
848                          font_size,
849                          0,
850                          TRUE );
851     HUD_deque.push_front( p );
852
853     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
854     strcpy(units, " ft");
855     } else {
856     strcpy(units, " m");
857     }
858     p = new instr_label( x_pos, 40, 40, 10,
859              get_altitude,
860              "%5.0f",
861              "Altitude ",
862              units,
863              1.0,
864              HUDS_TOP,
865              LEFT_JUST,
866              font_size,
867              0,
868              TRUE );
869     HUD_deque.push_front( p );
870
871     p = new instr_label( x_pos, 25, 40, 10,
872              get_agl,
873              "%5.0f",
874              "Elvation ",
875              units,
876              1.0,
877              HUDS_TOP,
878              LEFT_JUST,
879              font_size,
880              0,
881              TRUE );
882     HUD_deque.push_front( p );
883
884     p = new instr_label( x_pos, 10, 60, 10,
885              get_heading,
886              "%5.1f",
887              "Heading  ",
888              " Deg",
889              1.0,
890              HUDS_TOP,
891              LEFT_JUST,
892              font_size,
893              0,
894              TRUE );
895     HUD_deque.push_front( p );
896
897     p = new fgTBI_instr( 290, 55, 60, 10 ); // 270
898     HUD_deque.push_front( p );
899     
900     p = new  guage_instr( 270, //250,            // x
901                           390, //360, //400, //45, //420,            // y
902                           100,            // width
903                           20,            // height
904                           get_aileronval, // data source
905                           HUDS_BOTTOM | HUDS_NOTEXT,
906                           100.0,
907                           +1.0,
908                           -1.0);
909     HUD_deque.push_front( p );
910
911     p = new  guage_instr( 20,             // x
912                           240-50,             // y
913                           20,             // width
914                           100,             // height
915                           get_elevatorval, // data source
916                           HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
917                           -100.0,           // Scale data
918                           +1.0,           // Data Range
919                           -1.0);
920     HUD_deque.push_front( p );
921
922     p = new  guage_instr( 270, //250,             // x
923                           10+15,             // y
924                           100,             // width
925                           20,             // height
926                           get_rudderval,   // data source
927                           HUDS_TOP | HUDS_NOTEXT,
928                           100.0,
929                           +1.0,
930                           -1.0);
931     HUD_deque.push_front( p );
932
933     p = new  guage_instr( 600,             // x
934                           240-80,
935                           20,
936                           160,             // height
937                           get_throttleval, // data source
938                           HUDS_VERT | HUDS_LEFT | HUDS_NOTEXT,
939                           100.0,
940                           1.0,
941                           0.0);
942     HUD_deque.push_front( p );
943     
944     return 0;  // For now. Later we may use this for an error code.
945 }
946
947 int global_day_night_switch = DAY;
948
949 void HUD_brightkey( bool incr_bright )
950 {
951 instr_item *pHUDInstr = HUD_deque[0];
952 int brightness        = pHUDInstr->get_brightness();
953
954   if( current_options.get_hud_status() ) {
955     if( incr_bright ) {
956       switch (brightness) {
957         case BRT_LIGHT:
958           current_options.set_hud_status(0);
959           break;
960
961         case BRT_MEDIUM:
962           brightness = BRT_LIGHT;
963           break;
964
965         case BRT_DARK:
966           brightness = BRT_MEDIUM;
967           break;
968
969         case BRT_BLACK:
970           brightness = BRT_DARK;
971           break;
972
973         default:
974           brightness = BRT_BLACK;
975         }
976       }
977     else {
978       switch (brightness) {
979         case BRT_LIGHT:
980           brightness = BRT_MEDIUM;
981           break;
982
983         case BRT_MEDIUM:
984           brightness = BRT_DARK;
985           break;
986
987         case BRT_DARK:
988           brightness = BRT_BLACK;
989           break;
990
991         case BRT_BLACK:
992         default:
993           current_options.set_hud_status(0);
994         }
995       }
996     }
997   else {
998     current_options.set_hud_status(1);
999     if( incr_bright ) {
1000       if( DAY == global_day_night_switch ) {
1001         brightness = BRT_BLACK;
1002         }
1003       else {
1004         brightness = BRT_DARK;
1005         global_day_night_switch = DAY;
1006         }
1007       }
1008     else {
1009       if( NIGHT == global_day_night_switch ) {
1010         brightness = BRT_DARK;
1011         }
1012       else {
1013         brightness = BRT_MEDIUM;
1014         global_day_night_switch = NIGHT;
1015         }
1016       }
1017     }
1018   pHUDInstr->SetBrightness( brightness );
1019 }
1020
1021 #if 0
1022 // fgUpdateHUD
1023 //
1024 // Performs a once around the list of calls to instruments installed in
1025 // the HUD object with requests for redraw. Kinda. It will when this is
1026 // all C++.
1027 //
1028 void fgUpdateHUD( void ) {
1029   int brightness;
1030 //  int day_night_sw = current_aircraft.controls->day_night_switch;
1031   int day_night_sw = global_day_night_switch;
1032   int hud_displays = HUD_deque.size();
1033   instr_item *pHUDInstr;
1034   float line_width;
1035
1036   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
1037     return;
1038     }
1039
1040   HUD_TextList.erase();
1041   HUD_LineList.erase();
1042 //  HUD_StippleLineList.erase();
1043   
1044   pHUDInstr = HUD_deque[0];
1045   brightness = pHUDInstr->get_brightness();
1046 //  brightness = HUD_deque.at(0)->get_brightness();
1047
1048   glMatrixMode(GL_PROJECTION);
1049   glPushMatrix();
1050
1051   glLoadIdentity();
1052   gluOrtho2D(0, 640, 0, 480);
1053   glMatrixMode(GL_MODELVIEW);
1054   glPushMatrix();
1055   glLoadIdentity();
1056
1057   glColor3f(1.0, 1.0, 1.0);
1058   glIndexi(7);
1059
1060   glDisable(GL_DEPTH_TEST);
1061   glDisable(GL_LIGHTING);
1062
1063   // We can do translucency, so why not. :-)
1064 //  glEnable    ( GL_BLEND ) ;
1065 //  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1066   
1067   if( day_night_sw == DAY) {
1068       switch (brightness) {
1069           case BRT_LIGHT:
1070 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1071             glColor3f (0.1, 0.9, 0.1);
1072             break;
1073
1074           case BRT_MEDIUM:
1075 //            glColor4f (0.1, 0.7, 0.0, 0.75);
1076             glColor3f (0.1, 0.7, 0.0);
1077             break;
1078
1079           case BRT_DARK:
1080 //            glColor4f (0.0, 0.6, 0.0, 0.75);
1081             glColor3f(0.0, 0.6, 0.0);
1082             break;
1083
1084           case BRT_BLACK:
1085 //            glColor4f( 0.0, 0.0, 0.0, 0.75);
1086             glColor3f( 0.0, 0.0, 0.0);
1087             break;
1088
1089           default:;
1090       }
1091   }
1092   else {
1093       if( day_night_sw == NIGHT) {
1094           switch (brightness) {
1095               case BRT_LIGHT:
1096 //                glColor4f (0.9, 0.1, 0.1, 0.75);
1097                 glColor3f (0.9, 0.1, 0.1);
1098                 break;
1099
1100               case BRT_MEDIUM:
1101 //                glColor4f (0.7, 0.0, 0.1, 0.75);
1102                 glColor3f (0.7, 0.0, 0.1);
1103                 break;
1104
1105               case BRT_DARK:
1106               default:
1107 //                glColor4f (0.6, 0.0, 0.0, 0.75);
1108                   glColor3f (0.6, 0.0, 0.0);
1109           }
1110       }
1111           else {     // Just in case default
1112 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1113               glColor3f (0.1, 0.9, 0.1);
1114           }
1115   }
1116
1117   deque < instr_item * > :: iterator current = HUD_deque.begin();
1118   deque < instr_item * > :: iterator last = HUD_deque.end();
1119
1120   for ( ; current != last; ++current ) {
1121       pHUDInstr = *current;
1122
1123       if( pHUDInstr->enabled()) {
1124           //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1125           //            hud->code, hud->status );
1126           pHUDInstr->draw();
1127 //        HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1128                               // No broken displays honored just now.
1129       }
1130   }
1131
1132   char *gmt_str = get_formated_gmt_time();
1133   HUD_TextList.add( fgText( 40, 10, gmt_str) );
1134
1135 #ifdef FG_NETWORK_OLK
1136   if ( net_hud_display ) {
1137       net_hud_update();
1138   }
1139 #endif
1140
1141   HUD_TextList.draw();
1142
1143   line_width = (current_options.get_xsize() > 1000) ? 1.0 : 0.5;
1144   glLineWidth(line_width);
1145   HUD_LineList.draw();
1146
1147 //  glEnable(GL_LINE_STIPPLE);
1148 //  glLineStipple( 1, 0x00FF );
1149 //  HUD_StippleLineList.draw();
1150 //  glDisable(GL_LINE_STIPPLE);
1151
1152 //  glDisable( GL_BLEND );
1153   
1154   glEnable(GL_DEPTH_TEST);
1155   glEnable(GL_LIGHTING);
1156   glMatrixMode(GL_PROJECTION);
1157   glPopMatrix();
1158   glMatrixMode(GL_MODELVIEW);
1159   glPopMatrix();
1160 }
1161 #endif
1162
1163
1164 // fgUpdateHUD
1165 //
1166 // Performs a once around the list of calls to instruments installed in
1167 // the HUD object with requests for redraw. Kinda. It will when this is
1168 // all C++.
1169 //
1170 void fgUpdateHUD( void ) {
1171   int brightness;
1172 //  int day_night_sw = current_aircraft.controls->day_night_switch;
1173   int day_night_sw = global_day_night_switch;
1174   int hud_displays = HUD_deque.size();
1175   instr_item *pHUDInstr;
1176   float line_width;
1177
1178   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
1179     return;
1180     }
1181
1182   HUD_TextList.erase();
1183   HUD_LineList.erase();
1184 //  HUD_StippleLineList.erase();
1185   
1186   pHUDInstr = HUD_deque[0];
1187   brightness = pHUDInstr->get_brightness();
1188 //  brightness = HUD_deque.at(0)->get_brightness();
1189
1190   glMatrixMode(GL_PROJECTION);
1191   glPushMatrix();
1192
1193   glLoadIdentity();
1194   gluOrtho2D(0, 640, 0, 480);
1195   glMatrixMode(GL_MODELVIEW);
1196   glPushMatrix();
1197   glLoadIdentity();
1198
1199   glColor3f(1.0, 1.0, 1.0);
1200   glIndexi(7);
1201
1202   glDisable(GL_DEPTH_TEST);
1203   glDisable(GL_LIGHTING);
1204
1205   // We can do translucency, so why not. :-)
1206 //  glEnable    ( GL_BLEND ) ;
1207 //  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
1208   
1209   if( day_night_sw == DAY) {
1210           switch (brightness) {
1211                   case BRT_LIGHT:
1212 //            glColor4f (0.1, 0.9, 0.1, 0.75);
1213             glColor3f (0.1, 0.9, 0.1);
1214             break;
1215
1216           case BRT_MEDIUM:
1217 //            glColor4f (0.1, 0.7, 0.0, 0.75);
1218             glColor3f (0.1, 0.7, 0.0);
1219             break;
1220
1221           case BRT_DARK:
1222 //            glColor4f (0.0, 0.6, 0.0, 0.75);
1223             glColor3f(0.0, 0.6, 0.0);
1224             break;
1225
1226           case BRT_BLACK:
1227 //            glColor4f( 0.0, 0.0, 0.0, 0.75);
1228             glColor3f( 0.0, 0.0, 0.0);
1229             break;
1230
1231           default:;
1232           }
1233   }
1234   else {
1235           if( day_night_sw == NIGHT) {
1236                   switch (brightness) {
1237                           case BRT_LIGHT:
1238 //                glColor4f (0.9, 0.1, 0.1, 0.75);
1239                 glColor3f (0.9, 0.1, 0.1);
1240                 break;
1241
1242               case BRT_MEDIUM:
1243 //                glColor4f (0.7, 0.0, 0.1, 0.75);
1244                 glColor3f (0.7, 0.0, 0.1);
1245                 break;
1246
1247                           case BRT_DARK:
1248                           default:
1249 //                                glColor4f (0.6, 0.0, 0.0, 0.75);
1250                                   glColor3f (0.6, 0.0, 0.0);
1251                   }
1252           }
1253           else {     // Just in case default
1254 //                        glColor4f (0.1, 0.9, 0.1, 0.75);
1255                           glColor3f (0.1, 0.9, 0.1);
1256                   }
1257   }
1258
1259   deque < instr_item * > :: iterator current = HUD_deque.begin();
1260   deque < instr_item * > :: iterator last = HUD_deque.end();
1261
1262   for ( ; current != last; ++current ) {
1263           pHUDInstr = *current;
1264
1265           if( pHUDInstr->enabled()) {
1266                   //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
1267                   //            hud->code, hud->status );
1268                   pHUDInstr->draw();
1269 //            HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1270                               // No broken displays honored just now.
1271           }
1272   }
1273
1274   char *gmt_str = get_formated_gmt_time();
1275   HUD_TextList.add( fgText(40, 10, gmt_str) );
1276
1277 #ifdef FG_NETWORK_OLK
1278   if ( net_hud_display ) {
1279       net_hud_update();
1280   }
1281 #endif
1282
1283
1284   // temporary
1285   extern bool fgAPAltitudeEnabled( void );
1286   extern bool fgAPHeadingEnabled( void );
1287   extern bool fgAPWayPointEnabled( void );
1288   extern char *fgAPget_TargetDistanceStr( void );
1289   extern char *fgAPget_TargetHeadingStr( void );
1290   extern char *fgAPget_TargetAltitudeStr( void );
1291   extern char *fgAPget_TargetLatLonStr( void );
1292
1293   int apY = 480 - 80;
1294 //  char scratch[128];
1295 //  HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
1296 //  apY -= 15;
1297   if( fgAPHeadingEnabled() ) {
1298           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetHeadingStr()) );       
1299           apY -= 15;
1300   }
1301   if( fgAPAltitudeEnabled() ) {
1302           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetAltitudeStr()) );      
1303           apY -= 15;
1304   }
1305   if( fgAPWayPointEnabled() ) {
1306           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetLatLonStr()) );
1307           apY -= 15;
1308           HUD_TextList.add( fgText( 40, apY, fgAPget_TargetDistanceStr() ) );     
1309           apY -= 15;
1310   }
1311   
1312   HUD_TextList.draw();
1313
1314   line_width = (current_options.get_xsize() > 1000) ? 1.0 : 0.5;
1315   glLineWidth(line_width);
1316   HUD_LineList.draw();
1317
1318 //  glEnable(GL_LINE_STIPPLE);
1319 //  glLineStipple( 1, 0x00FF );
1320 //  HUD_StippleLineList.draw();
1321 //  glDisable(GL_LINE_STIPPLE);
1322
1323 //  glDisable( GL_BLEND );
1324   
1325   glEnable(GL_DEPTH_TEST);
1326   glEnable(GL_LIGHTING);
1327   glMatrixMode(GL_PROJECTION);
1328   glPopMatrix();
1329   glMatrixMode(GL_MODELVIEW);
1330   glPopMatrix();
1331 }
1332