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.
36 #include <simgear/constants.h>
37 #include <simgear/debug/logstream.hxx>
38 #include <simgear/math/polar3d.hxx>
39 #include <simgear/props/props.hxx>
40 #include <simgear/timing/sg_time.hxx>
42 #include <Aircraft/aircraft.hxx>
43 #include <Include/general.hxx>
44 #include <FDM/ADA.hxx>
45 #include <Main/globals.hxx>
46 #include <Main/fg_props.hxx>
47 #include <Main/viewmgr.hxx>
48 #include <Scenery/scenery.hxx>
49 #include <Time/fg_timer.hxx>
52 #include "cockpit.hxx"
56 // This is a structure that contains all data related to
57 // cockpit/panel/hud system
59 static pCockpit ac_cockpit;
60 // The following routines obtain information concerntin the aircraft's
61 // current state and return it to calling instrument display routines.
62 // They should eventually be member functions of the aircraft.
65 float get_latitude( void )
67 return current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
70 float get_lat_min( void )
74 a = current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
78 d = (double) ( (int) a);
79 float lat_min = (a - d) * 60.0;
85 float get_longitude( void )
87 return current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
92 get_formated_gmt_time( void )
95 const struct tm *p = globals->get_time_params()->getGmt();
96 sprintf( buf, "%d/%d/%4d %d:%02d:%02d",
97 p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
98 p->tm_hour, p->tm_min, p->tm_sec);
104 float get_long_min( void )
107 a = current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
111 d = (double) ( (int) a);
112 float lon_min = (a - d) * 60.0;
117 float get_throttleval( void )
119 // Hack limiting to one engine
120 return globals->get_controls()->get_throttle( 0 );
123 float get_aileronval( void )
125 return globals->get_controls()->get_aileron();
128 float get_elevatorval( void )
130 return globals->get_controls()->get_elevator();
133 float get_elev_trimval( void )
135 return globals->get_controls()->get_elevator_trim();
138 float get_rudderval( void )
140 return globals->get_controls()->get_rudder();
143 float get_speed( void )
145 static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
147 float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
148 * speedup_node->getIntValue();
155 return current_aircraft.fdm_state->get_Mach_number();
158 float get_aoa( void )
160 return current_aircraft.fdm_state->get_Alpha() * SGD_RADIANS_TO_DEGREES;
163 float get_roll( void )
165 return current_aircraft.fdm_state->get_Phi();
168 float get_pitch( void )
170 return current_aircraft.fdm_state->get_Theta();
173 float get_heading( void )
175 return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES;
178 float get_altitude( void )
180 static const SGPropertyNode *startup_units_node
181 = fgGetNode("/sim/startup/units");
185 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
186 altitude = current_aircraft.fdm_state->get_Altitude();
188 altitude = (current_aircraft.fdm_state->get_Altitude()
195 float get_agl( void )
197 static const SGPropertyNode *startup_units_node
198 = fgGetNode("/sim/startup/units");
202 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
203 agl = (current_aircraft.fdm_state->get_Altitude()
204 - globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET);
206 agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
207 - globals->get_scenery()->get_cur_elev());
213 float get_sideslip( void )
215 return current_aircraft.fdm_state->get_Beta();
218 float get_frame_rate( void )
220 return general.get_frame_rate();
223 float get_fov( void )
225 return globals->get_current_view()->get_fov();
228 float get_vfc_ratio( void )
230 // float vfc = current_view.get_vfc_ratio();
235 float get_vfc_tris_drawn ( void )
237 // float rendered = current_view.get_tris_rendered();
238 // return (rendered);
242 float get_vfc_tris_culled ( void )
244 // float culled = current_view.get_tris_culled();
249 float get_climb_rate( void )
251 static const SGPropertyNode *startup_units_node
252 = fgGetNode("/sim/startup/units");
255 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
256 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
258 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
265 float get_view_direction( void )
267 double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
268 double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
269 * SGD_RADIANS_TO_DEGREES;
279 // $$$ begin - added, VS Renganathan 13 Oct 2K
280 // #ifdef FIGHTER_HUD
281 float get_Vx ( void )
283 // Curt dont comment this and return zero. - Ranga
284 // Please remove comments from get_V_..() function in flight.hxx
285 float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
289 float get_Vy ( void )
291 // Curt dont comment this and return zero. - Ranga
292 // Please remove comments from get_V_..() function in flight.hxx
293 float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
297 float get_Vz ( void )
299 // Curt dont comment this and return zero. - Ranga
300 // Please remove comments from get_V_..() function in flight.hxx
301 float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
305 float get_Ax ( void )
307 float Ax = current_aircraft.fdm_state->get_V_dot_north();
311 float get_Ay ( void )
313 float Ay = current_aircraft.fdm_state->get_V_dot_east();
317 float get_Az ( void )
319 float Az = current_aircraft.fdm_state->get_V_dot_down();
323 float get_anzg ( void )
325 float anzg = current_aircraft.fdm_state->get_N_Z_cg();
331 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
332 return fdm->get_iaux(1);
337 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
338 return fdm->get_iaux(2);
343 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
344 return fdm->get_iaux(3);
349 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
350 return fdm->get_iaux(4);
355 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
356 return fdm->get_iaux(5);
361 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
362 return fdm->get_iaux(6);
367 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
368 return fdm->get_iaux(7);
373 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
374 return fdm->get_iaux(8);
379 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
380 return fdm->get_iaux(9);
383 int get_iaux10 (void)
385 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
386 return fdm->get_iaux(10);
389 int get_iaux11 (void)
391 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
392 return fdm->get_iaux(11);
395 int get_iaux12 (void)
397 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
398 return fdm->get_iaux(12);
401 float get_aux1 (void)
403 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
404 return fdm->get_daux(1);
407 float get_aux2 (void)
409 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
410 return fdm->get_daux(2);
413 float get_aux3 (void)
415 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
416 return fdm->get_daux(3);
419 float get_aux4 (void)
421 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
422 return fdm->get_daux(4);
425 float get_aux5 (void)
427 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
428 return fdm->get_daux(5);
431 float get_aux6 (void)
433 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
434 return fdm->get_daux(6);
437 float get_aux7 (void)
439 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
440 return fdm->get_daux(7);
443 float get_aux8 (void)
445 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
446 return fdm->get_daux(8);
449 float get_aux9 (void)
451 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
452 return fdm->get_faux(1);
455 float get_aux10 (void)
457 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
458 return fdm->get_faux(2);
461 float get_aux11 (void)
463 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
464 return fdm->get_faux(3);
467 float get_aux12 (void)
469 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
470 return fdm->get_faux(4);
473 float get_aux13 (void)
475 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
476 return fdm->get_faux(5);
479 float get_aux14 (void)
481 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
482 return fdm->get_faux(6);
485 float get_aux15 (void)
487 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
488 return fdm->get_faux(7);
491 float get_aux16 (void)
493 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
494 return fdm->get_faux(8);
497 float get_aux17 (void)
499 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
500 return fdm->get_faux(9);
503 float get_aux18 (void)
505 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
506 return fdm->get_faux(10);
509 // $$$ end - added, VS Renganathan 13 Oct 2K
513 /****************************************************************************/
514 /* Convert degrees to dd mm'ss.s" (DMS-Format) */
515 /****************************************************************************/
516 char *dmshh_format(double degrees)
527 min_part = 60.0 * (degrees - deg_part);
528 sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
530 /* Round off hundredths */
531 if (sec_part + 0.005 >= 60.0)
532 sec_part -= 60.0, min_part += 1;
534 min_part -= 60, deg_part += 1;
536 sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
543 /************************************************************************
544 Convert degrees to dd mm.mmm' (DMM-Format)
545 Description: Converts using a round-off factor tailored to the required
546 precision of the minutes field (three decimal places). Round-off
547 prevents function from returning a minutes value of 60.
549 Input arguments: Coordinate value in decimal degrees
551 ************************************************************************/
552 static char *toDM(float dd)
563 /* round for minutes expressed to three decimal places */
564 tempdd = fabs(dd) + (5.0E-4 / 60.0);
566 mn = fabs( (tempdd - (double)(deg)) * 60.0 - 4.999E-4 );
568 sprintf(dm, "%d*%06.3f", deg, mn);
573 /************************************************************************
574 Convert degrees to dd mm'ss.s'' (DMS-Format)
575 Description: Converts using a round-off factor tailored to the required
576 precision of the seconds field (one decimal place). Round-off
577 prevents function from returning a seconds value of 60.
579 Input arguments: Coordinate value in decimal degrees
581 ************************************************************************/
582 static char *toDMS(float dd)
585 double tempdd, tempmin;
594 /* round up for seconds expressed to one decimal place */
595 tempdd = fabs(dd) + (0.05 / 3600.0);
597 tempmin = (tempdd - (double)(deg)) * 60.0;
599 sec = fabs( (tempmin - (double)(mn)) * 60.0 - 0.049 );
601 sprintf(dms, "%d*%02d %04.1f", deg, mn, sec);
606 // Have to set the LatLon display type
607 //static char *(*fgLatLonFormat)(float) = toDM;
608 static char *(*fgLatLonFormat)(float);
610 char *coord_format_lat(float latitude)
615 // dmshh_format(latitude),
618 fgLatLonFormat(latitude),
619 latitude > 0 ? 'N' : 'S');
623 char *coord_format_lon(float longitude)
628 // dmshh_format(longitude),
631 fgLatLonFormat(longitude),
632 longitude > 0 ? 'E' : 'W');
636 void fgLatLonFormatToggle( puObject *)
638 static int toggle = 0;
641 fgLatLonFormat = toDM;
643 fgLatLonFormat = toDMS;
649 char *coord_format_latlon(double latitude, double longitude)
651 static char buf[1024];
653 sprintf(buf,"%s%c %s%c",
654 dmshh_format(latitude),
655 latitude > 0 ? 'N' : 'S',
656 dmshh_format(longitude),
657 longitude > 0 ? 'E' : 'W');
663 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
665 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
667 // cockpit->code = 1; /* It will be aircraft dependent */
668 // cockpit->status = 0;
670 // If aircraft has HUD specified we will get the specs from its def
671 // file. For now we will depend upon hard coding in hud?
673 // We must insure that the existing instrument link is purged.
674 // This is done by deleting the links in the list.
676 // HI_Head is now a null pointer so we can generate a new list from the
679 fgHUDInit( cur_aircraft );
680 ac_cockpit = new fg_Cockpit();
682 // Have to set the LatLon display type
683 fgLatLonFormat = toDM;
685 SG_LOG( SG_COCKPIT, SG_INFO,
686 " Code " << ac_cockpit->code() << " Status "
687 << ac_cockpit->status() );
692 void fgCockpitUpdate( void ) {
694 SG_LOG( SG_COCKPIT, SG_DEBUG,
695 "Cockpit: code " << ac_cockpit->code() << " status "
696 << ac_cockpit->status() );
698 static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
699 static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
700 static const SGPropertyNode * hud_visibility_node
701 = fgGetNode("/sim/hud/visibility");
703 int iwidth = xsize_node->getIntValue();
704 int iheight = ysize_node->getIntValue();
705 float width = iwidth;
706 // float height = iheight;
708 // FIXME: inefficient
709 if ( hud_visibility_node->getBoolValue() ) {
710 // This will check the global hud linked list pointer.
711 // If these is anything to draw it will.
715 #define DISPLAY_COUNTER
716 #ifdef DISPLAY_COUNTER
720 float fps = get_frame_rate();
721 // float tris = fps * get_vfc_tris_drawn();
722 // float culled = fps * get_vfc_tris_culled();
723 // sprintf(buf,"%-4.1f %7.0f %7.0f", fps, tris, culled);
724 sprintf(buf,"%-5.1f", fps);
726 glMatrixMode( GL_PROJECTION );
729 gluOrtho2D( 0, iwidth, 0, iheight );
730 glMatrixMode( GL_MODELVIEW );
734 glDisable( GL_DEPTH_TEST );
735 glDisable( GL_LIGHTING );
737 glColor3f( 0.9, 0.4, 0.2 );
739 guiFnt.drawString( buf,
740 int(width - guiFnt.getStringWidth(buf) - 10),
742 glEnable( GL_DEPTH_TEST );
743 glEnable( GL_LIGHTING );
744 glMatrixMode( GL_PROJECTION );
746 glMatrixMode( GL_MODELVIEW );
749 #endif // #ifdef DISPLAY_COUNTER
751 glViewport( 0, 0, iwidth, iheight );