1 /**************************************************************************
2 * hud.cxx -- hud defines and prototypes
4 * Written by Michele America, started September 1997.
6 * Copyright (C) 1997 Michele F. America - micheleamerica@geocities.com
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.
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.
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.
23 * (Log is kept at end of this file)
24 **************************************************************************/
40 # include <values.h> // for MAXINT
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>
54 #if defined ( __sun__ ) || defined ( __sgi )
56 extern void *memmove(void *, const void *, size_t);
64 // The following routines obtain information concerntin the aircraft's
65 // current state and return it to calling instrument display routines.
66 // They should eventually be member functions of the aircraft.
69 deque< instr_item * > HUD_deque;
75 locRECT( UINT left, UINT top, UINT right, UINT bottom);
76 RECT get_rect(void) { return rect;}
79 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
89 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
97 void drawOneLine( RECT &rect)
100 glVertex2f(rect.left, rect.top);
101 glVertex2f(rect.right, rect.bottom);
106 // The following code deals with painting the "instrument" on the display
108 /* textString - Bitmap font string */
110 void textString( int x, int y, char *msg, void *font ){
113 glutBitmapCharacter(font, *msg);
118 /* strokeString - Stroke font string */
120 void strokeString(int x, int y, char *msg, void *font, float theta)
126 glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
127 xx = (int)(x * cos(theta) + y * sin( theta ));
128 yy = (int)(y * cos(theta) - x * sin( theta ));
129 glTranslatef( xx, yy, 0);
130 glScalef(.1, .1, 0.0);
132 glutStrokeCharacter(font, *msg);
138 //========================= End of Class Implementations===================
141 // Constructs a HUD object and then adds in instruments. At the present
142 // the instruments are hard coded into the routine. Ultimately these need
143 // to be defined by the aircraft's instrumentation records so that the
144 // display for a Piper Cub doesn't show the speed range of a North American
145 // mustange and the engine readouts of a B36!
150 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
155 fgPrintf( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD\n" );
157 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
162 // For now lets just hardcode the hud here.
163 // In the future, hud information has to come from the same place
164 // aircraft information came from.
166 // fgHUDSetTimeMode( hud, NIGHT );
167 // fgHUDSetBrightness( hud, BRT_LIGHT );
174 HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
177 case 1: // Artificial Horizon
178 HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
182 HIptr = (instr_item *) new hud_card( 130,
187 HUDS_LEFT | HUDS_VERT,
198 case 3: // Radio Altimeter
199 HIptr = (instr_item *) new hud_card( 420,
204 HUDS_LEFT | HUDS_VERT,
214 case 4: // GYRO COMPASS
215 HIptr = (instr_item *) new hud_card( 200,
231 HIptr = (instr_item *) new hud_card( 460,
236 HUDS_RIGHT | HUDS_VERT,
247 HIptr = (instr_item *) new guage_instr( 250, // x
251 get_aileronval, // data source
252 HUDS_BOTTOM | HUDS_NOTEXT,
259 HIptr = (instr_item *) new guage_instr( 170, // x
263 get_elevatorval, // data source
264 HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
265 -100.0, // Scale data
271 HIptr = (instr_item *) new guage_instr( 250, // x
275 get_rudderval, // data source
276 HUDS_TOP | HUDS_NOTEXT,
283 HIptr = (instr_item *) new guage_instr( 100, // x
287 get_throttleval, // data source
288 HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
294 case 10: // Digital KIAS
295 HIptr = (instr_item *) new instr_label ( 110,
311 case 11: // Digital Rate of Climb
312 HIptr = (instr_item *) new instr_label ( 110,
328 case 12: // Roll indication diagnostic
329 HIptr = (instr_item *) new instr_label ( 110,
345 case 13: // Angle of attack diagnostic
346 HIptr = (instr_item *) new instr_label ( 440,
363 HIptr = (instr_item *) new instr_label ( 440,
380 HIptr = (instr_item *) new instr_label ( 440,
397 HIptr = (instr_item *) new instr_label( 440,
414 HIptr = (instr_item *) new instr_label( 440,
431 HIptr = (instr_item *) new instr_label( 440,
449 HIptr = (instr_item *) new instr_label( 10,
466 switch( current_options.get_tris_or_culled() ) {
468 HIptr = (instr_item *) new instr_label( 10,
484 HIptr = (instr_item *) new instr_label( 10,
503 HIptr = (instr_item *) new instr_label( 10,
522 if( HIptr ) { // Anything to install?
523 HUD_deque.insert( HUD_deque.begin(), HIptr);
529 return 0; // For now. Later we may use this for an error code.
532 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
537 fgPrintf( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD\n" );
539 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
544 // For now lets just hardcode the hud here.
545 // In the future, hud information has to come from the same place
546 // aircraft information came from.
548 // fgHUDSetTimeMode( hud, NIGHT );
549 // fgHUDSetBrightness( hud, BRT_LIGHT );
557 HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
560 case 1: // Artificial Horizon
561 HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
565 HIptr = (instr_item *) new hud_card( 130,
570 HUDS_LEFT | HUDS_VERT,
581 case 3: // Radio Altimeter
582 HIptr = (instr_item *) new hud_card( 420,
587 HUDS_LEFT | HUDS_VERT,
597 case 4: // GYRO COMPASS
598 HIptr = (instr_item *) new hud_card( 200,
614 HIptr = (instr_item *) new hud_card( 460,
619 HUDS_RIGHT | HUDS_VERT,
630 HIptr = (instr_item *) new guage_instr( 250, // x
634 get_aileronval, // data source
635 HUDS_BOTTOM | HUDS_NOTEXT,
642 HIptr = (instr_item *) new guage_instr( 170, // x
646 get_elevatorval, // data source
647 HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
648 -100.0, // Scale data
654 HIptr = (instr_item *) new guage_instr( 250, // x
658 get_rudderval, // data source
659 HUDS_TOP | HUDS_NOTEXT,
666 HIptr = (instr_item *) new guage_instr( 100, // x
670 get_throttleval, // data source
671 HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
677 case 10: // Digital KIAS
678 HIptr = (instr_item *) new instr_label ( 110,
694 case 11: // Digital Rate of Climb
695 HIptr = (instr_item *) new instr_label ( 110,
711 case 12: // Roll indication diagnostic
712 HIptr = (instr_item *) new instr_label ( 110,
728 case 13: // Angle of attack diagnostic
729 HIptr = (instr_item *) new instr_label ( 440,
746 HIptr = (instr_item *) new instr_label ( 440,
763 HIptr = (instr_item *) new instr_label ( 440,
780 HIptr = (instr_item *) new instr_label( 440,
797 HIptr = (instr_item *) new instr_label( 440,
814 HIptr = (instr_item *) new instr_label( 440,
832 HIptr = (instr_item *) new instr_label( 10,
849 switch( current_options.get_tris_or_culled() ) {
851 HIptr = (instr_item *) new instr_label( 10,
867 HIptr = (instr_item *) new instr_label( 10,
886 HIptr = (instr_item *) new instr_label( 10,
905 if( HIptr ) { // Anything to install?
906 HUD_deque.insert( HUD_deque.begin(), HIptr);
912 return 0; // For now. Later we may use this for an error code.
915 int global_day_night_switch = DAY;
917 void HUD_brightkey( bool incr_bright )
919 instr_item *pHUDInstr = HUD_deque[0];
920 int brightness = pHUDInstr->get_brightness();
922 if( current_options.get_hud_status() ) {
924 switch (brightness) {
926 current_options.set_hud_status(0);
930 brightness = BRT_LIGHT;
934 brightness = BRT_MEDIUM;
938 brightness = BRT_DARK;
942 brightness = BRT_BLACK;
946 switch (brightness) {
948 brightness = BRT_MEDIUM;
952 brightness = BRT_DARK;
956 brightness = BRT_BLACK;
961 current_options.set_hud_status(0);
966 current_options.set_hud_status(1);
968 if( DAY == global_day_night_switch ) {
969 brightness = BRT_BLACK;
972 brightness = BRT_DARK;
973 global_day_night_switch = DAY;
977 if( NIGHT == global_day_night_switch ) {
978 brightness = BRT_DARK;
981 brightness = BRT_MEDIUM;
982 global_day_night_switch = NIGHT;
986 pHUDInstr->SetBrightness( brightness );
991 // Performs a once around the list of calls to instruments installed in
992 // the HUD object with requests for redraw. Kinda. It will when this is
995 void fgUpdateHUD( void ) {
998 // int day_night_sw = current_aircraft.controls->day_night_switch;
999 int day_night_sw = global_day_night_switch;
1000 int hud_displays = HUD_deque.size();
1001 instr_item *pHUDInstr;
1003 if( !hud_displays ) { // Trust everyone, but ALWAYS cut the cards!
1007 pHUDInstr = HUD_deque[0];
1008 brightness = pHUDInstr->get_brightness();
1009 // brightness = HUD_deque.at(0)->get_brightness();
1011 glMatrixMode(GL_PROJECTION);
1015 gluOrtho2D(0, 640, 0, 480);
1016 glMatrixMode(GL_MODELVIEW);
1020 glColor3f(1.0, 1.0, 1.0);
1023 glDisable(GL_DEPTH_TEST);
1024 glDisable(GL_LIGHTING);
1028 deque < instr_item * > :: iterator current;
1029 deque < instr_item * > :: iterator last;
1031 current = HUD_deque.begin();
1032 last = HUD_deque.end();
1033 while ( current != last ) {
1034 pHUDInstr = *current;
1037 // for( i = hud_displays; i; --i) { // Draw everything
1038 // if( HUD_deque.at(i)->enabled()) {
1039 // pHUDInstr = HUD_deque[i - 1];
1040 if( pHUDInstr->enabled()) {
1041 // We should to respond to a dial instead
1042 // or as well to the of time of day. Of
1043 // course, we have no dial!
1044 if( day_night_sw == DAY) {
1045 switch (brightness) {
1047 glColor3f (0.1, 0.9, 0.1);
1051 glColor3f (0.1, 0.7, 0.0);
1055 glColor3f (0.0, 0.5, 0.0);
1059 glColor3f( 0.0, 0.0, 0.0);
1066 if( day_night_sw == NIGHT) {
1067 switch (brightness) {
1069 glColor3f (0.9, 0.1, 0.1);
1073 glColor3f (0.7, 0.0, 0.1);
1078 glColor3f (0.5, 0.0, 0.0);
1081 else { // Just in case default
1082 glColor3f (0.1, 0.9, 0.1);
1085 // fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d Status %d\n",
1086 // hud->code, hud->status );
1088 // HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
1089 // No broken displays honored just now.
1093 glEnable(GL_DEPTH_TEST);
1094 glEnable(GL_LIGHTING);
1095 glMatrixMode(GL_PROJECTION);
1097 glMatrixMode(GL_MODELVIEW);
1102 /* Revision 1.21 1998/09/29 02:01:07 curt
1103 /* Added a "rate of climb" indicator.
1105 * Revision 1.20 1998/08/24 20:05:16 curt
1106 * Added a second minimalistic HUD.
1107 * Added code to display the number of triangles rendered.
1109 * Revision 1.19 1998/07/30 23:44:05 curt
1110 * Tweaks for sgi building.
1112 * Revision 1.18 1998/07/20 12:47:55 curt
1113 * Replace the hud rendering for loop (which linearly searches the the hud
1114 * list to find the entry with the proper position) with a simple linear
1115 * traversal using an "iterator."
1117 * Revision 1.17 1998/07/13 21:28:02 curt
1118 * Converted the aoa scale to a radio altimeter.
1120 * Revision 1.16 1998/07/13 21:00:47 curt
1121 * Integrated Charlies latest HUD updates.
1122 * Wrote access functions for current fgOPTIONS.
1124 * Revision 1.15 1998/07/08 14:41:08 curt
1125 * Renamed polar3d.h to polar3d.hxx
1127 * Revision 1.14 1998/07/06 21:31:20 curt
1128 * Removed an extraneous ^M.
1130 * Revision 1.13 1998/07/03 13:16:28 curt
1131 * Added Charlie Hotchkiss's HUD updates and improvementes.
1133 * Revision 1.11 1998/06/05 18:17:10 curt
1134 * Added the declaration of memmove needed by the stl which apparently
1135 * solaris only defines for cc compilations and not for c++ (__STDC__)
1137 * Revision 1.10 1998/05/17 16:58:12 curt
1138 * Added a View Frustum Culling ratio display to the hud.
1140 * Revision 1.9 1998/05/16 13:04:14 curt
1141 * New updates from Charlie Hotchkiss.
1143 * Revision 1.8 1998/05/13 18:27:54 curt
1144 * Added an fov to hud display.
1146 * Revision 1.7 1998/05/11 18:13:11 curt
1147 * Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
1149 * Revision 1.22 1998/04/18 04:14:02 curt
1150 * Moved fg_debug.c to it's own library.
1152 * Revision 1.21 1998/04/03 21:55:28 curt
1153 * Converting to Gnu autoconf system.
1156 * Revision 1.20 1998/03/09 22:48:40 curt
1157 * Minor "formatting" tweaks.
1159 * Revision 1.19 1998/02/23 20:18:28 curt
1160 * Incorporated Michele America's hud changes.
1162 * Revision 1.18 1998/02/21 14:53:10 curt
1163 * Added Charlie's HUD changes.
1165 * Revision 1.17 1998/02/20 00:16:21 curt
1166 * Thursday's tweaks.
1168 * Revision 1.16 1998/02/19 13:05:49 curt
1169 * Incorporated some HUD tweaks from Michelle America.
1170 * Tweaked the sky's sunset/rise colors.
1171 * Other misc. tweaks.
1173 * Revision 1.15 1998/02/16 13:38:39 curt
1174 * Integrated changes from Charlie Hotchkiss.
1176 * Revision 1.14 1998/02/12 21:59:41 curt
1177 * Incorporated code changes contributed by Charlie Hotchkiss
1178 * <chotchkiss@namg.us.anritsu.com>
1180 * Revision 1.12 1998/02/09 15:07:48 curt
1183 * Revision 1.11 1998/02/07 15:29:34 curt
1184 * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
1185 * <chotchkiss@namg.us.anritsu.com>
1187 * Revision 1.10 1998/02/03 23:20:14 curt
1188 * Lots of little tweaks to fix various consistency problems discovered by
1189 * Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
1190 * passed arguments along to the real printf(). Also incorporated HUD changes
1191 * by Michele America.
1193 * Revision 1.9 1998/01/31 00:43:04 curt
1194 * Added MetroWorks patches from Carmen Volpe.
1196 * Revision 1.8 1998/01/27 00:47:51 curt
1197 * Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
1198 * system and commandline/config file processing code.
1200 * Revision 1.7 1998/01/19 18:40:20 curt
1201 * Tons of little changes to clean up the code and to remove fatal errors
1202 * when building with the c++ compiler.
1204 * Revision 1.6 1997/12/15 23:54:34 curt
1205 * Add xgl wrappers for debugging.
1206 * Generate terrain normals on the fly.
1208 * Revision 1.5 1997/12/10 22:37:39 curt
1209 * Prepended "fg" on the name of all global structures that didn't have it yet.
1210 * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
1212 * Revision 1.4 1997/09/23 00:29:32 curt
1213 * Tweaks to get things to compile with gcc-win32.
1215 * Revision 1.3 1997/09/05 14:17:26 curt
1216 * More tweaking with stars.
1218 * Revision 1.2 1997/09/04 02:17:30 curt
1221 * Revision 1.1 1997/08/29 18:03:22 curt