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