1 // cockpit.cxx -- routines to draw a cockpit (initial draft)
3 // Written by Michele America, started September 1997.
5 // Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
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.
38 #include <simgear/constants.h>
39 #include <simgear/debug/logstream.hxx>
40 #include <simgear/math/polar3d.hxx>
41 #include <simgear/props/props.hxx>
42 #include <simgear/timing/sg_time.hxx>
44 #include <Aircraft/aircraft.hxx>
45 #include <Include/general.hxx>
46 #include <FDM/ADA.hxx>
47 #include <Main/globals.hxx>
48 #include <Main/fg_props.hxx>
49 #include <Main/viewmgr.hxx>
50 #include <Scenery/scenery.hxx>
51 #include <Time/fg_timer.hxx>
54 #include "cockpit.hxx"
58 // This is a structure that contains all data related to
59 // cockpit/panel/hud system
61 static pCockpit ac_cockpit;
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 float get_latitude( void )
69 return current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
72 float get_lat_min( void )
76 a = current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
80 d = (double) ( (int) a);
81 float lat_min = (a - d) * 60.0;
87 float get_longitude( void )
89 return current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
94 get_formated_gmt_time( void )
97 const struct tm *p = globals->get_time_params()->getGmt();
98 sprintf( buf, "%d/%d/%4d %d:%02d:%02d",
99 p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
100 p->tm_hour, p->tm_min, p->tm_sec);
106 float get_long_min( void )
109 a = current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
113 d = (double) ( (int) a);
114 float lon_min = (a - d) * 60.0;
119 float get_throttleval( void )
121 // Hack limiting to one engine
122 return globals->get_controls()->get_throttle( 0 );
125 float get_aileronval( void )
127 return globals->get_controls()->get_aileron();
130 float get_elevatorval( void )
132 return globals->get_controls()->get_elevator();
135 float get_elev_trimval( void )
137 return globals->get_controls()->get_elevator_trim();
140 float get_rudderval( void )
142 return globals->get_controls()->get_rudder();
145 float get_speed( void )
147 static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
149 float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
150 * speedup_node->getIntValue();
157 return current_aircraft.fdm_state->get_Mach_number();
160 float get_aoa( void )
162 return current_aircraft.fdm_state->get_Alpha() * SGD_RADIANS_TO_DEGREES;
165 float get_roll( void )
167 return current_aircraft.fdm_state->get_Phi();
170 float get_pitch( void )
172 return current_aircraft.fdm_state->get_Theta();
175 float get_heading( void )
177 return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES;
180 float get_altitude( void )
182 static const SGPropertyNode *startup_units_node
183 = fgGetNode("/sim/startup/units");
187 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
188 altitude = current_aircraft.fdm_state->get_Altitude();
190 altitude = (current_aircraft.fdm_state->get_Altitude()
197 float get_agl( void )
199 static const SGPropertyNode *startup_units_node
200 = fgGetNode("/sim/startup/units");
204 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
205 agl = (current_aircraft.fdm_state->get_Altitude()
206 - globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET);
208 agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
209 - globals->get_scenery()->get_cur_elev());
215 float get_sideslip( void )
217 return current_aircraft.fdm_state->get_Beta();
220 float get_frame_rate( void )
222 return general.get_frame_rate();
225 float get_fov( void )
227 return globals->get_current_view()->get_fov();
230 float get_vfc_ratio( void )
232 // float vfc = current_view.get_vfc_ratio();
237 float get_vfc_tris_drawn ( void )
239 // float rendered = current_view.get_tris_rendered();
240 // return (rendered);
244 float get_vfc_tris_culled ( void )
246 // float culled = current_view.get_tris_culled();
251 float get_climb_rate( void )
253 static const SGPropertyNode *startup_units_node
254 = fgGetNode("/sim/startup/units");
257 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
258 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
260 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
267 float get_view_direction( void )
269 double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
270 double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
271 * SGD_RADIANS_TO_DEGREES;
281 // $$$ begin - added, VS Renganathan 13 Oct 2K
282 // #ifdef FIGHTER_HUD
283 float get_Vx ( void )
285 // Curt dont comment this and return zero. - Ranga
286 // Please remove comments from get_V_..() function in flight.hxx
287 float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
291 float get_Vy ( void )
293 // Curt dont comment this and return zero. - Ranga
294 // Please remove comments from get_V_..() function in flight.hxx
295 float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
299 float get_Vz ( void )
301 // Curt dont comment this and return zero. - Ranga
302 // Please remove comments from get_V_..() function in flight.hxx
303 float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
307 float get_Ax ( void )
309 float Ax = current_aircraft.fdm_state->get_V_dot_north();
313 float get_Ay ( void )
315 float Ay = current_aircraft.fdm_state->get_V_dot_east();
319 float get_Az ( void )
321 float Az = current_aircraft.fdm_state->get_V_dot_down();
325 float get_anzg ( void )
327 float anzg = current_aircraft.fdm_state->get_N_Z_cg();
333 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
334 return fdm->get_iaux(1);
339 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
340 return fdm->get_iaux(2);
345 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
346 return fdm->get_iaux(3);
351 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
352 return fdm->get_iaux(4);
357 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
358 return fdm->get_iaux(5);
363 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
364 return fdm->get_iaux(6);
369 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
370 return fdm->get_iaux(7);
375 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
376 return fdm->get_iaux(8);
381 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
382 return fdm->get_iaux(9);
385 int get_iaux10 (void)
387 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
388 return fdm->get_iaux(10);
391 int get_iaux11 (void)
393 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
394 return fdm->get_iaux(11);
397 int get_iaux12 (void)
399 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
400 return fdm->get_iaux(12);
403 float get_aux1 (void)
405 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
406 return fdm->get_daux(1);
409 float get_aux2 (void)
411 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
412 return fdm->get_daux(2);
415 float get_aux3 (void)
417 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
418 return fdm->get_daux(3);
421 float get_aux4 (void)
423 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
424 return fdm->get_daux(4);
427 float get_aux5 (void)
429 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
430 return fdm->get_daux(5);
433 float get_aux6 (void)
435 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
436 return fdm->get_daux(6);
439 float get_aux7 (void)
441 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
442 return fdm->get_daux(7);
445 float get_aux8 (void)
447 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
448 return fdm->get_daux(8);
451 float get_aux9 (void)
453 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
454 return fdm->get_faux(1);
457 float get_aux10 (void)
459 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
460 return fdm->get_faux(2);
463 float get_aux11 (void)
465 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
466 return fdm->get_faux(3);
469 float get_aux12 (void)
471 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
472 return fdm->get_faux(4);
475 float get_aux13 (void)
477 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
478 return fdm->get_faux(5);
481 float get_aux14 (void)
483 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
484 return fdm->get_faux(6);
487 float get_aux15 (void)
489 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
490 return fdm->get_faux(7);
493 float get_aux16 (void)
495 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
496 return fdm->get_faux(8);
499 float get_aux17 (void)
501 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
502 return fdm->get_faux(9);
505 float get_aux18 (void)
507 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
508 return fdm->get_faux(10);
511 // $$$ end - added, VS Renganathan 13 Oct 2K
515 /****************************************************************************/
516 /* Convert degrees to dd mm'ss.s" (DMS-Format) */
517 /****************************************************************************/
518 char *dmshh_format(double degrees)
529 min_part = 60.0 * (degrees - deg_part);
530 sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
532 /* Round off hundredths */
533 if (sec_part + 0.005 >= 60.0)
534 sec_part -= 60.0, min_part += 1;
536 min_part -= 60, deg_part += 1;
538 sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
545 /************************************************************************
546 Convert degrees to dd mm.mmm' (DMM-Format)
547 Description: Converts using a round-off factor tailored to the required
548 precision of the minutes field (three decimal places). Round-off
549 prevents function from returning a minutes value of 60.
551 Input arguments: Coordinate value in decimal degrees
553 ************************************************************************/
554 static char *toDM(float dd)
565 /* round for minutes expressed to three decimal places */
566 tempdd = fabs(dd) + (5.0E-4 / 60.0);
568 mn = fabs( (tempdd - (double)(deg)) * 60.0 - 4.999E-4 );
570 sprintf(dm, "%d*%06.3f", deg, mn);
575 /************************************************************************
576 Convert degrees to dd mm'ss.s'' (DMS-Format)
577 Description: Converts using a round-off factor tailored to the required
578 precision of the seconds field (one decimal place). Round-off
579 prevents function from returning a seconds value of 60.
581 Input arguments: Coordinate value in decimal degrees
583 ************************************************************************/
584 static char *toDMS(float dd)
587 double tempdd, tempmin;
596 /* round up for seconds expressed to one decimal place */
597 tempdd = fabs(dd) + (0.05 / 3600.0);
599 tempmin = (tempdd - (double)(deg)) * 60.0;
601 sec = fabs( (tempmin - (double)(mn)) * 60.0 - 0.049 );
603 sprintf(dms, "%d*%02d %04.1f", deg, mn, sec);
608 // Have to set the LatLon display type
609 //static char *(*fgLatLonFormat)(float) = toDM;
610 static char *(*fgLatLonFormat)(float);
612 char *coord_format_lat(float latitude)
617 // dmshh_format(latitude),
620 fgLatLonFormat(latitude),
621 latitude > 0 ? 'N' : 'S');
625 char *coord_format_lon(float longitude)
630 // dmshh_format(longitude),
633 fgLatLonFormat(longitude),
634 longitude > 0 ? 'E' : 'W');
638 void fgLatLonFormatToggle( puObject *)
640 static int toggle = 0;
643 fgLatLonFormat = toDM;
645 fgLatLonFormat = toDMS;
651 char *coord_format_latlon(double latitude, double longitude)
653 static char buf[1024];
655 sprintf(buf,"%s%c %s%c",
656 dmshh_format(latitude),
657 latitude > 0 ? 'N' : 'S',
658 dmshh_format(longitude),
659 longitude > 0 ? 'E' : 'W');
665 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
667 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
669 // cockpit->code = 1; /* It will be aircraft dependent */
670 // cockpit->status = 0;
672 // If aircraft has HUD specified we will get the specs from its def
673 // file. For now we will depend upon hard coding in hud?
675 // We must insure that the existing instrument link is purged.
676 // This is done by deleting the links in the list.
678 // HI_Head is now a null pointer so we can generate a new list from the
681 fgHUDInit( cur_aircraft );
682 ac_cockpit = new fg_Cockpit();
684 // Have to set the LatLon display type
685 fgLatLonFormat = toDM;
687 SG_LOG( SG_COCKPIT, SG_INFO,
688 " Code " << ac_cockpit->code() << " Status "
689 << ac_cockpit->status() );
694 void fgCockpitUpdate( void ) {
696 SG_LOG( SG_COCKPIT, SG_DEBUG,
697 "Cockpit: code " << ac_cockpit->code() << " status "
698 << ac_cockpit->status() );
700 static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
701 static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
702 static const SGPropertyNode * hud_visibility_node
703 = fgGetNode("/sim/hud/visibility");
705 int iwidth = xsize_node->getIntValue();
706 int iheight = ysize_node->getIntValue();
707 float width = iwidth;
708 // float height = iheight;
710 // FIXME: inefficient
711 if ( hud_visibility_node->getBoolValue() ) {
712 // This will check the global hud linked list pointer.
713 // If these is anything to draw it will.
717 #define DISPLAY_COUNTER
718 #ifdef DISPLAY_COUNTER
722 float fps = get_frame_rate();
723 // float tris = fps * get_vfc_tris_drawn();
724 // float culled = fps * get_vfc_tris_culled();
725 // sprintf(buf,"%-4.1f %7.0f %7.0f", fps, tris, culled);
726 sprintf(buf,"%-5.1f", fps);
728 glMatrixMode( GL_PROJECTION );
731 gluOrtho2D( 0, iwidth, 0, iheight );
732 glMatrixMode( GL_MODELVIEW );
736 glDisable( GL_DEPTH_TEST );
737 glDisable( GL_LIGHTING );
739 glColor3f( 0.9, 0.4, 0.2 );
741 guiFnt.drawString( buf,
742 int(width - guiFnt.getStringWidth(buf) - 10),
744 glEnable( GL_DEPTH_TEST );
745 glEnable( GL_LIGHTING );
746 glMatrixMode( GL_PROJECTION );
748 glMatrixMode( GL_MODELVIEW );
751 #endif // #ifdef DISPLAY_COUNTER
753 glViewport( 0, 0, iwidth, iheight );