1 // hud.cxx -- hud defines and prototypes
3 // Written by Michele America, started September 1997.
5 // Copyright (C) 1997 Michele F. America - micheleamerica@geocities.com
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.
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.
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.
33 # define exception c_exception
41 #include <Aircraft/aircraft.hxx>
42 #include <Debug/logstream.hxx>
43 #include <Include/fg_constants.h>
44 #include <Main/options.hxx>
45 #include <Math/fg_random.h>
46 #include <Math/mat3.h>
47 #include <Math/polar3d.hxx>
48 #include <Scenery/scenery.hxx>
49 #include <Time/fg_timer.hxx>
51 #if defined ( __sun__ ) || defined ( __sgi )
53 extern void *memmove(void *, const void *, size_t);
62 // The following routines obtain information concerntin the aircraft's
63 // current state and return it to calling instrument display routines.
64 // They should eventually be member functions of the aircraft.
67 HudContainerType HUD_deque;
73 locRECT( UINT left, UINT top, UINT right, UINT bottom);
74 RECT get_rect(void) { return rect;}
77 locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
87 void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
95 void drawOneLine( RECT &rect)
98 glVertex2f(rect.left, rect.top);
99 glVertex2f(rect.right, rect.bottom);
104 // The following code deals with painting the "instrument" on the display
106 /* textString - Bitmap font string */
108 void textString( int x, int y, char *msg, void *font ){
111 glutBitmapCharacter(font, *msg);
116 /* strokeString - Stroke font string */
118 void strokeString(int x, int y, char *msg, void *font, float theta)
124 glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
125 xx = (int)(x * cos(theta) + y * sin( theta ));
126 yy = (int)(y * cos(theta) - x * sin( theta ));
127 glTranslatef( xx, yy, 0);
128 glScalef(.1, .1, 0.0);
130 glutStrokeCharacter(font, *msg);
136 //========================= End of Class Implementations===================
139 // Constructs a HUD object and then adds in instruments. At the present
140 // the instruments are hard coded into the routine. Ultimately these need
141 // to be defined by the aircraft's instrumentation records so that the
142 // display for a Piper Cub doesn't show the speed range of a North American
143 // mustange and the engine readouts of a B36!
148 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
153 FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
155 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
160 // For now lets just hardcode the hud here.
161 // In the future, hud information has to come from the same place
162 // aircraft information came from.
164 // fgHUDSetTimeMode( hud, NIGHT );
165 // fgHUDSetBrightness( hud, BRT_LIGHT );
172 HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
175 case 1: // Artificial Horizon
176 HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
180 HIptr = (instr_item *) new hud_card( 130,
185 HUDS_LEFT | HUDS_VERT,
196 case 3: // Radio Altimeter
197 HIptr = (instr_item *) new hud_card( 420,
202 HUDS_LEFT | HUDS_VERT,
212 case 4: // GYRO COMPASS
213 HIptr = (instr_item *) new hud_card( 200,
229 HIptr = (instr_item *) new hud_card( 460,
234 HUDS_RIGHT | HUDS_VERT,
245 HIptr = (instr_item *) new guage_instr( 250, // x
249 get_aileronval, // data source
250 HUDS_BOTTOM | HUDS_NOTEXT,
257 HIptr = (instr_item *) new guage_instr( 170, // x
261 get_elevatorval, // data source
262 HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
263 -100.0, // Scale data
269 HIptr = (instr_item *) new guage_instr( 250, // x
273 get_rudderval, // data source
274 HUDS_TOP | HUDS_NOTEXT,
281 HIptr = (instr_item *) new guage_instr( 100, // x
285 get_throttleval, // data source
286 HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
292 case 10: // Digital KIAS
293 HIptr = (instr_item *) new instr_label ( 110,
309 case 11: // Digital Rate of Climb
310 HIptr = (instr_item *) new instr_label ( 110,
326 case 12: // Roll indication diagnostic
327 HIptr = (instr_item *) new instr_label ( 110,
343 case 13: // Angle of attack diagnostic
344 HIptr = (instr_item *) new instr_label ( 440,
361 HIptr = (instr_item *) new instr_label ( 440,
378 HIptr = (instr_item *) new instr_label ( 440,
395 HIptr = (instr_item *) new instr_label( 440,
412 HIptr = (instr_item *) new instr_label( 440,
429 HIptr = (instr_item *) new instr_label( 440,
447 HIptr = (instr_item *) new instr_label( 10,
464 switch( current_options.get_tris_or_culled() ) {
466 HIptr = (instr_item *) new instr_label( 10,
482 HIptr = (instr_item *) new instr_label( 10,
501 HIptr = (instr_item *) new instr_label( 10,
520 if( HIptr ) { // Anything to install?
521 HUD_deque.insert( HUD_deque.begin(), HIptr);
527 return 0; // For now. Later we may use this for an error code.
530 int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
534 FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
536 HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
541 // For now lets just hardcode the hud here.
542 // In the future, hud information has to come from the same place
543 // aircraft information came from.
545 // fgHUDSetTimeMode( hud, NIGHT );
546 // fgHUDSetBrightness( hud, BRT_LIGHT );
553 p = new instr_label( 10, 10, 60, 10,
564 HUD_deque.push_front( p );
566 if ( current_options.get_tris_or_culled() == 0 )
567 p = new instr_label( 10, 25, 90, 10,
579 p = new instr_label( 10, 25, 90, 10,
590 HUD_deque.push_front( p );
592 p = new instr_label( 10, 40, 90, 10,
603 HUD_deque.push_front( p );
605 const int x_pos = 480;
606 p = new instr_label( x_pos, 40, 40, 30,
617 HUD_deque.push_front( p );
619 if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
620 strcpy(units, " ft");
624 p = new instr_label( x_pos, 25, 40, 10,
635 HUD_deque.push_front( p );
637 p = new instr_label( x_pos, 10, 60, 10,
648 HUD_deque.push_front( p );
650 return 0; // For now. Later we may use this for an error code.
653 int global_day_night_switch = DAY;
655 void HUD_brightkey( bool incr_bright )
657 instr_item *pHUDInstr = HUD_deque[0];
658 int brightness = pHUDInstr->get_brightness();
660 if( current_options.get_hud_status() ) {
662 switch (brightness) {
664 current_options.set_hud_status(0);
668 brightness = BRT_LIGHT;
672 brightness = BRT_MEDIUM;
676 brightness = BRT_DARK;
680 brightness = BRT_BLACK;
684 switch (brightness) {
686 brightness = BRT_MEDIUM;
690 brightness = BRT_DARK;
694 brightness = BRT_BLACK;
699 current_options.set_hud_status(0);
704 current_options.set_hud_status(1);
706 if( DAY == global_day_night_switch ) {
707 brightness = BRT_BLACK;
710 brightness = BRT_DARK;
711 global_day_night_switch = DAY;
715 if( NIGHT == global_day_night_switch ) {
716 brightness = BRT_DARK;
719 brightness = BRT_MEDIUM;
720 global_day_night_switch = NIGHT;
724 pHUDInstr->SetBrightness( brightness );
729 // Performs a once around the list of calls to instruments installed in
730 // the HUD object with requests for redraw. Kinda. It will when this is
733 void fgUpdateHUD( void ) {
736 // int day_night_sw = current_aircraft.controls->day_night_switch;
737 int day_night_sw = global_day_night_switch;
738 int hud_displays = HUD_deque.size();
739 instr_item *pHUDInstr;
741 if( !hud_displays ) { // Trust everyone, but ALWAYS cut the cards!
745 pHUDInstr = HUD_deque[0];
746 brightness = pHUDInstr->get_brightness();
747 // brightness = HUD_deque.at(0)->get_brightness();
749 glMatrixMode(GL_PROJECTION);
753 gluOrtho2D(0, 640, 0, 480);
754 glMatrixMode(GL_MODELVIEW);
758 glColor3f(1.0, 1.0, 1.0);
761 glDisable(GL_DEPTH_TEST);
762 glDisable(GL_LIGHTING);
766 HudIterator current = HUD_deque.begin();
767 HudIterator last = HUD_deque.end();
769 for ( ; current != last; ++current ) {
770 pHUDInstr = *current;
772 // for( i = hud_displays; i; --i) { // Draw everything
773 // if( HUD_deque.at(i)->enabled()) {
774 // pHUDInstr = HUD_deque[i - 1];
775 if( pHUDInstr->enabled()) {
776 // We should to respond to a dial instead
777 // or as well to the of time of day. Of
778 // course, we have no dial!
779 if( day_night_sw == DAY) {
780 switch (brightness) {
782 glColor3f (0.1, 0.9, 0.1);
786 glColor3f (0.1, 0.7, 0.0);
790 glColor3f (0.0, 0.5, 0.0);
794 glColor3f( 0.0, 0.0, 0.0);
801 if( day_night_sw == NIGHT) {
802 switch (brightness) {
804 glColor3f (0.9, 0.1, 0.1);
808 glColor3f (0.7, 0.0, 0.1);
813 glColor3f (0.5, 0.0, 0.0);
816 else { // Just in case default
817 glColor3f (0.1, 0.9, 0.1);
820 // fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d Status %d\n",
821 // hud->code, hud->status );
823 // HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
824 // No broken displays honored just now.
828 glEnable(GL_DEPTH_TEST);
829 glEnable(GL_LIGHTING);
830 glMatrixMode(GL_PROJECTION);
832 glMatrixMode(GL_MODELVIEW);