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