]> git.mxchange.org Git - flightgear.git/blob - Cockpit/hud.cxx
Integrated Charlies latest HUD updates.
[flightgear.git] / Cockpit / hud.cxx
1 /**************************************************************************
2  * hud.cxx -- hud defines and prototypes
3  *
4  * Written by Michele America, started September 1997.
5  *
6  * Copyright (C) 1997  Michele F. America  - micheleamerica@geocities.com
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #ifdef HAVE_WINDOWS_H
32 #  include <windows.h>
33 #endif
34
35 #include <GL/glut.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #ifdef HAVE_VALUES_H
40 #  include <values.h>  // for MAXINT
41 #endif
42
43 #include <Aircraft/aircraft.h>
44 #include <Debug/fg_debug.h>
45 #include <Include/fg_constants.h>
46 #include <Main/options.hxx>
47 #include <Math/fg_random.h>
48 #include <Math/mat3.h>
49 #include <Math/polar3d.hxx>
50 #include <Scenery/scenery.hxx>
51 #include <Time/fg_timer.hxx>
52 #include <Weather/weather.h>
53
54 #include "hud.hxx"
55
56 #ifdef __sun__
57 extern "C" {
58   extern void *memmove(void *, const void *, size_t);
59 }
60 #endif
61
62
63 // The following routines obtain information concerntin the aircraft's
64 // current state and return it to calling instrument display routines.
65 // They should eventually be member functions of the aircraft.
66 //
67
68 deque< instr_item * > HUD_deque;
69
70 class locRECT {
71   public:
72     RECT rect;
73
74     locRECT( UINT left, UINT top, UINT right, UINT bottom);
75     RECT get_rect(void) { return rect;}
76 };
77
78 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
79 {
80   rect.left   =  left;
81   rect.top    =  top;
82   rect.right  =  right;
83   rect.bottom =  bottom;
84
85 }
86 // #define DEBUG
87
88 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
89 {
90   glBegin(GL_LINES);
91   glVertex2f(x1, y1);
92   glVertex2f(x2, y2);
93   glEnd();
94 }
95
96 void drawOneLine( RECT &rect)
97 {
98   glBegin(GL_LINES);
99   glVertex2f(rect.left, rect.top);
100   glVertex2f(rect.right, rect.bottom);
101   glEnd();
102 }
103
104 //
105 // The following code deals with painting the "instrument" on the display
106 //
107    /* textString - Bitmap font string */
108
109 void textString( int x, int y, char *msg, void *font ){
110         glRasterPos2f(x, y);
111         while (*msg) {
112                 glutBitmapCharacter(font, *msg);
113                 msg++;
114     }
115 }
116
117 /* strokeString - Stroke font string */
118
119 void strokeString(int x, int y, char *msg, void *font, float theta)
120 {
121 int xx;
122 int yy;
123
124         glPushMatrix();
125   glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
126   xx = x * cos(theta) + y * sin( theta );
127   yy = y * cos(theta) - x * sin( theta );
128         glTranslatef( xx, yy, 0);
129         glScalef(.1, .1, 0.0);
130         while (*msg) {
131                 glutStrokeCharacter(font, *msg);
132                 msg++;
133         }
134         glPopMatrix();
135 }
136
137 //========================= End of Class Implementations===================
138 // fgHUDInit
139 //
140 // Constructs a HUD object and then adds in instruments. At the present
141 // the instruments are hard coded into the routine. Ultimately these need
142 // to be defined by the aircraft's instrumentation records so that the
143 // display for a Piper Cub doesn't show the speed range of a North American
144 // mustange and the engine readouts of a B36!
145 //
146
147 #define INSTRDEFS 21
148
149 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
150 {
151   instr_item *HIptr;
152   int index;
153
154   fgPrintf( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD\n" );
155
156   HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());  // empty the HUD deque
157
158 //  hud->code = 1;
159 //  hud->status = 0;
160
161   // For now lets just hardcode the hud here.
162   // In the future, hud information has to come from the same place
163   // aircraft information came from.
164
165 //  fgHUDSetTimeMode( hud, NIGHT );
166 //  fgHUDSetBrightness( hud, BRT_LIGHT );
167
168   index = 0;
169
170   do {
171     switch ( index ) {
172       case 0:     // TBI
173         HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
174         break;
175
176       case 1:     // Artificial Horizon
177         HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
178         break;
179
180       case 2:    // KIAS
181         HIptr = (instr_item *) new hud_card( 130,
182                                              170,
183                                               28,
184                                              200,
185                                              get_speed,
186                                              HUDS_LEFT | HUDS_VERT,
187                                              200.0, 0.0,
188                                              1.0,
189                                              10,  5,
190                                              0,
191                                              0,
192                                              50.0,
193                                              true);
194
195         break;
196
197       case 3:    // Angle of Attack
198         HIptr = (instr_item *) new hud_card( 420,
199                                              195,
200                                               25,
201                                              150,
202                                              get_aoa,
203                                              HUDS_LEFT | HUDS_VERT,
204                                              50, -40,
205                                              1.0,
206                                              2,    1,
207                                              0,
208                                              1,
209                                              5.0,
210                                              true);
211         break;
212
213       case 4:    // GYRO COMPASS
214         HIptr = (instr_item *) new hud_card( 200,
215                                              375,
216                                              200,
217                                               28,
218                                              get_heading,
219                                              HUDS_TOP,
220                                              360, 0,
221                                                1.0,
222                                                5,   1,
223                                              360,
224                                                0,
225                                               25,
226                                              true);
227         break;
228
229       case 5:    // AMSL
230         HIptr = (instr_item *) new hud_card( 460,
231                                              170,
232                                               35,
233                                              200,
234                                              get_altitude,
235                                              HUDS_RIGHT | HUDS_VERT,
236                                              15000, 0,
237                                              1.0,
238                                              100,  25,
239                                              0,
240                                              0,
241                                              250,
242                                              true);
243         break;
244
245       case 6:
246         HIptr = (instr_item *) new  guage_instr( 250,            // x
247                                                  350,            // y
248                                                  100,            // width
249                                                   20,            // height
250                                                  get_aileronval, // data source
251                                                  HUDS_BOTTOM | HUDS_NOTEXT,
252                                                  100.0,
253                                                  +1.0,
254                                                  -1.0);
255         break;
256
257       case 7:
258         HIptr = (instr_item *) new  guage_instr( 170,             // x
259                                                  225,             // y
260                                                   20,             // width
261                                                  100,             // height
262                                                  get_elevatorval, // data source
263                                                  HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
264                                                 -100.0,           // Scale data
265                                                   +1.0,           // Data Range
266                                                   -1.0);
267         break;
268
269       case 8:
270         HIptr = (instr_item *) new  guage_instr( 250,             // x
271                                                  200,             // y
272                                                  100,             // width
273                                                   20,             // height
274                                                  get_rudderval,   // data source
275                                                  HUDS_TOP | HUDS_NOTEXT,
276                                                  100.0,
277                                                  +1.0,
278                                                  -1.0);
279         break;
280
281       case 9:
282         HIptr = (instr_item *) new  guage_instr( 100,             // x
283                                                  190,
284                                                   20,
285                                                  160,             // height
286                                                  get_throttleval, // data source
287                                                  HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
288                                                  100.0,
289                                                    1.0,
290                                                    0.0);
291         break;
292
293       case 10:    // Digital KIAS
294         HIptr = (instr_item *) new instr_label ( 110,
295                                                  150,
296                                                   40,
297                                                   30,
298                                                  get_speed,
299                                                  "%5.0f",
300                                                  NULL,
301                                                  " Kts",
302                                                  1.0,
303                                                  HUDS_TOP,
304                                                  RIGHT_JUST,
305                                                  SMALL,
306                                                  0,
307                                                  TRUE );
308         break;
309
310       case 11:    // Digital Altimeter
311         HIptr = (instr_item *) new instr_label ( 110,
312                                                  135,
313                                                   40,
314                                                   10,
315                                                  get_altitude,
316                                                  "MSL  %5.0f",
317                                                  NULL,
318                                                  " m",
319                                                  1.0,
320                                                  HUDS_TOP,
321                                                  LEFT_JUST,
322                                                  SMALL,
323                                                  0,
324                                                  TRUE );
325         break;
326
327       case 12:    // Roll indication diagnostic
328         HIptr = (instr_item *) new instr_label ( 110,
329                                                  120,
330                                                   40,
331                                                   10,
332                                                  get_roll,
333                                                  "%5.2f",
334                                                  " Roll",
335                                                  " Deg",
336                                                  1.0,
337                                                  HUDS_TOP,
338                                                  RIGHT_JUST,
339                                                  SMALL,
340                                                  0,
341                                                  TRUE );
342         break;
343
344       case 13:    // Angle of attack diagnostic
345         HIptr = (instr_item *) new instr_label ( 440,
346                                                  150,
347                                                   60,
348                                                   10,
349                                                  get_aoa,
350                                                  "      %5.2f",
351                                                  "AOA",
352                                                  " Deg",
353                                                  1.0,
354                                                  HUDS_TOP,
355                                                  RIGHT_JUST,
356                                                  SMALL,
357                                                  0,
358                                                  TRUE );
359         break;
360
361       case 14:
362         HIptr = (instr_item *) new instr_label ( 440,
363                                                  135,
364                                                   60,
365                                                   10,
366                                                  get_heading,
367                                                  " %5.1f",
368                                                  "Heading ",
369                                                  " Deg",
370                                                  1.0,
371                                                  HUDS_TOP,
372                                                  RIGHT_JUST,
373                                                  SMALL,
374                                                  0,
375                                                  TRUE );
376         break;
377
378       case 15:
379         HIptr = (instr_item *) new instr_label ( 440,
380                                                  120,
381                                                   60,
382                                                   10,
383                                                  get_sideslip,
384                                                  "%5.2f",
385                                                  "Sideslip ",
386                                                  NULL,
387                                                  1.0,
388                                                  HUDS_TOP,
389                                                  RIGHT_JUST,
390                                                  SMALL,
391                                                  0,
392                                                  TRUE );
393         break;
394
395       case 16:
396         HIptr = (instr_item *) new instr_label( 440,
397                                                 100,
398                                                  60,
399                                                  10,
400                                                 get_throttleval,
401                                                 "%5.2f",
402                                                 "Throttle ",
403                                                 NULL,
404                                                  1.0,
405                                                 HUDS_TOP,
406                                                 RIGHT_JUST,
407                                                 SMALL,
408                                                 0,
409                                                 TRUE );
410         break;
411
412       case 17:
413         HIptr = (instr_item *) new instr_label( 440,
414                                                  85,
415                                                  60,
416                                                  10,
417                                                 get_elevatorval,
418                                                 "%5.2f",
419                                                 "Elevator ",
420                                                 NULL,
421                                                  1.0,
422                                                 HUDS_TOP,
423                                                 RIGHT_JUST,
424                                                 SMALL,
425                                                 0,
426                                                 TRUE );
427         break;
428
429       case 18:
430         HIptr = (instr_item *) new instr_label( 440,
431                                                  60,
432                                                  60,
433                                                  10,
434                                                 get_aileronval,
435                                                 "%5.2f",
436                                                 "Aileron  ",
437                                                 NULL,
438                                                  1.0,
439                                                 HUDS_TOP,
440                                                 RIGHT_JUST,
441                                                 SMALL,
442                                                 0,
443                                                 TRUE );
444         break;
445
446
447       case 19:
448         HIptr = (instr_item *) new instr_label( 10,
449                                                 10,
450                                                 60,
451                                                 10,
452                                                  get_frame_rate,
453                                                 "%.1f",
454                                                 "Frame rate = ",
455                                                 NULL,
456                                                  1.0,
457                                                 HUDS_TOP,
458                                                 RIGHT_JUST,
459                                                 SMALL,
460                                                 0,
461                                                 TRUE );
462         break;
463
464       case 20:
465         HIptr = (instr_item *) new instr_label( 10,
466                                                 25,
467                                                 90,
468                                                 10,
469                                                  get_vfc_ratio,
470                                                 "%.2f",
471                                                 "VFC Ratio = ",
472                                                 NULL,
473                                                  1.0,
474                                                 HUDS_TOP,
475                                                 RIGHT_JUST,
476                                                 SMALL,
477                                                 0,
478                                                 TRUE );
479         break;
480
481       case 21:
482         HIptr = (instr_item *) new instr_label( 10,
483                                                 40,
484                                                 90,
485                                                 10,
486                                                 get_fov,
487                                                 "%.1f",
488                                                 "FOV = ",
489                                                 NULL,
490                                                  1.0,
491                                                 HUDS_TOP,
492                                                 RIGHT_JUST,
493                                                 SMALL,
494                                                 0,
495                                                 TRUE );
496         break;
497
498       default:
499         HIptr = 0;;
500       }
501     if( HIptr ) {                   // Anything to install?
502       HUD_deque.insert( HUD_deque.begin(), HIptr);
503       }
504     index++;
505     }
506   while( HIptr );
507
508   return 0;  // For now. Later we may use this for an error code.
509 }
510
511 int global_day_night_switch = DAY;
512
513 void HUD_brightkey( bool incr_bright )
514 {
515 instr_item *pHUDInstr = HUD_deque[0];
516 int brightness        = pHUDInstr->get_brightness();
517
518   if( current_options.get_hud_status() ) {
519     if( incr_bright ) {
520       switch (brightness) {
521         case BRT_LIGHT:
522               current_options.set_hud_status(0);
523           break;
524
525         case BRT_MEDIUM:
526           brightness = BRT_LIGHT;
527           break;
528
529         case BRT_DARK:
530           brightness = BRT_MEDIUM;
531           break;
532
533         case BRT_BLACK:
534           brightness = BRT_DARK;
535           break;
536
537         default:
538           brightness = BRT_BLACK;
539         }
540       }
541     else {
542       switch (brightness) {
543         case BRT_LIGHT:
544           brightness = BRT_MEDIUM;
545           break;
546
547         case BRT_MEDIUM:
548           brightness = BRT_DARK;
549           break;
550
551         case BRT_DARK:
552           brightness = BRT_BLACK;
553           break;
554
555         case BRT_BLACK:
556         default:
557               current_options.set_hud_status(0);
558         }
559       }
560     }
561   else {
562     current_options.set_hud_status(1);
563     if( incr_bright ) {
564       if( DAY == global_day_night_switch ) {
565         brightness = BRT_BLACK;
566         }
567       else {
568         brightness = BRT_DARK;
569         global_day_night_switch = DAY;
570         }
571       }
572     else {
573       if( NIGHT == global_day_night_switch ) {
574         brightness = BRT_DARK;
575         }
576       else {
577         brightness = BRT_MEDIUM;
578         global_day_night_switch = NIGHT;
579         }
580       }
581     }
582   pHUDInstr->SetBrightness( brightness );
583 }
584
585 // fgUpdateHUD
586 //
587 // Performs a once around the list of calls to instruments installed in
588 // the HUD object with requests for redraw. Kinda. It will when this is
589 // all C++.
590 //
591 void fgUpdateHUD( void ) {
592   int i;
593   int brightness;
594 //  int day_night_sw = current_aircraft.controls->day_night_switch;
595   int day_night_sw = global_day_night_switch;
596   int hud_displays = HUD_deque.size();
597   instr_item *pHUDInstr;
598
599   if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
600     return;
601     }
602
603   pHUDInstr = HUD_deque[0];
604   brightness = pHUDInstr->get_brightness();
605 //  brightness = HUD_deque.at(0)->get_brightness();
606
607   glMatrixMode(GL_PROJECTION);
608   glPushMatrix();
609
610   glLoadIdentity();
611   gluOrtho2D(0, 640, 0, 480);
612   glMatrixMode(GL_MODELVIEW);
613   glPushMatrix();
614   glLoadIdentity();
615
616   glColor3f(1.0, 1.0, 1.0);
617   glIndexi(7);
618
619   glDisable(GL_DEPTH_TEST);
620   glDisable(GL_LIGHTING);
621
622   glLineWidth(1);
623
624   for( i = hud_displays; i; --i) { // Draw everything
625 //    if( HUD_deque.at(i)->enabled()) {
626     pHUDInstr = HUD_deque[i - 1];
627     if( pHUDInstr->enabled()) {
628                                    // We should to respond to a dial instead
629                                    // or as well to the of time of day. Of
630                                    // course, we have no dial!
631       if( day_night_sw == DAY) {
632         switch (brightness) {
633           case BRT_LIGHT:
634             glColor3f (0.1, 0.9, 0.1);
635             break;
636
637           case BRT_MEDIUM:
638             glColor3f (0.1, 0.7, 0.0);
639             break;
640
641           case BRT_DARK:
642             glColor3f (0.0, 0.5, 0.0);
643             break;
644
645           case BRT_BLACK:
646             glColor3f( 0.0, 0.0, 0.0);
647             break;
648
649           default:;
650             }
651           }
652         else {
653           if( day_night_sw == NIGHT) {
654             switch (brightness) {
655               case BRT_LIGHT:
656                 glColor3f (0.9, 0.1, 0.1);
657                 break;
658
659               case BRT_MEDIUM:
660                 glColor3f (0.7, 0.0, 0.1);
661                 break;
662
663               case BRT_DARK:
664               default:
665                 glColor3f (0.5, 0.0, 0.0);
666               }
667             }
668           else {     // Just in case default
669             glColor3f (0.1, 0.9, 0.1);
670             }
671           }
672     //  fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d  Status %d\n",
673     //            hud->code, hud->status );
674       pHUDInstr->draw();
675 //      HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
676                               // No broken displays honored just now.
677       }
678     }
679
680   glEnable(GL_DEPTH_TEST);
681   glEnable(GL_LIGHTING);
682   glMatrixMode(GL_PROJECTION);
683   glPopMatrix();
684   glMatrixMode(GL_MODELVIEW);
685   glPopMatrix();
686 }
687
688 /* $Log$
689 /* Revision 1.16  1998/07/13 21:00:47  curt
690 /* Integrated Charlies latest HUD updates.
691 /* Wrote access functions for current fgOPTIONS.
692 /*
693  * Revision 1.15  1998/07/08 14:41:08  curt
694  * Renamed polar3d.h to polar3d.hxx
695  *
696  * Revision 1.14  1998/07/06 21:31:20  curt
697  * Removed an extraneous ^M.
698  *
699  * Revision 1.13  1998/07/03 13:16:28  curt
700  * Added Charlie Hotchkiss's HUD updates and improvementes.
701  *
702  * Revision 1.11  1998/06/05 18:17:10  curt
703  * Added the declaration of memmove needed by the stl which apparently
704  * solaris only defines for cc compilations and not for c++ (__STDC__)
705  *
706  * Revision 1.10  1998/05/17 16:58:12  curt
707  * Added a View Frustum Culling ratio display to the hud.
708  *
709  * Revision 1.9  1998/05/16 13:04:14  curt
710  * New updates from Charlie Hotchkiss.
711  *
712  * Revision 1.8  1998/05/13 18:27:54  curt
713  * Added an fov to hud display.
714  *
715  * Revision 1.7  1998/05/11 18:13:11  curt
716  * Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
717  *
718  * Revision 1.22  1998/04/18 04:14:02  curt
719  * Moved fg_debug.c to it's own library.
720  *
721  * Revision 1.21  1998/04/03 21:55:28  curt
722  * Converting to Gnu autoconf system.
723  * Tweaks to hud.c
724  *
725  * Revision 1.20  1998/03/09 22:48:40  curt
726  * Minor "formatting" tweaks.
727  *
728  * Revision 1.19  1998/02/23 20:18:28  curt
729  * Incorporated Michele America's hud changes.
730  *
731  * Revision 1.18  1998/02/21 14:53:10  curt
732  * Added Charlie's HUD changes.
733  *
734  * Revision 1.17  1998/02/20 00:16:21  curt
735  * Thursday's tweaks.
736  *
737  * Revision 1.16  1998/02/19 13:05:49  curt
738  * Incorporated some HUD tweaks from Michelle America.
739  * Tweaked the sky's sunset/rise colors.
740  * Other misc. tweaks.
741  *
742  * Revision 1.15  1998/02/16 13:38:39  curt
743  * Integrated changes from Charlie Hotchkiss.
744  *
745  * Revision 1.14  1998/02/12 21:59:41  curt
746  * Incorporated code changes contributed by Charlie Hotchkiss
747  * <chotchkiss@namg.us.anritsu.com>
748  *
749  * Revision 1.12  1998/02/09 15:07:48  curt
750  * Minor tweaks.
751  *
752  * Revision 1.11  1998/02/07 15:29:34  curt
753  * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
754  * <chotchkiss@namg.us.anritsu.com>
755  *
756  * Revision 1.10  1998/02/03 23:20:14  curt
757  * Lots of little tweaks to fix various consistency problems discovered by
758  * Solaris' CC.  Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
759  * passed arguments along to the real printf().  Also incorporated HUD changes
760  * by Michele America.
761  *
762  * Revision 1.9  1998/01/31 00:43:04  curt
763  * Added MetroWorks patches from Carmen Volpe.
764  *
765  * Revision 1.8  1998/01/27 00:47:51  curt
766  * Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
767  * system and commandline/config file processing code.
768  *
769  * Revision 1.7  1998/01/19 18:40:20  curt
770  * Tons of little changes to clean up the code and to remove fatal errors
771  * when building with the c++ compiler.
772  *
773  * Revision 1.6  1997/12/15 23:54:34  curt
774  * Add xgl wrappers for debugging.
775  * Generate terrain normals on the fly.
776  *
777  * Revision 1.5  1997/12/10 22:37:39  curt
778  * Prepended "fg" on the name of all global structures that didn't have it yet.
779  * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
780  *
781  * Revision 1.4  1997/09/23 00:29:32  curt
782  * Tweaks to get things to compile with gcc-win32.
783  *
784  * Revision 1.3  1997/09/05 14:17:26  curt
785  * More tweaking with stars.
786  *
787  * Revision 1.2  1997/09/04 02:17:30  curt
788  * Shufflin' stuff.
789  *
790  * Revision 1.1  1997/08/29 18:03:22  curt
791  * Initial revision.
792  *
793  */