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>
47 #include <FDM/SP/ADA.hxx>
49 #include <Main/globals.hxx>
50 #include <Main/fg_props.hxx>
51 #include <Main/viewmgr.hxx>
52 #include <Scenery/scenery.hxx>
53 #include <Time/fg_timer.hxx>
56 #include "cockpit.hxx"
60 // This is a structure that contains all data related to
61 // cockpit/panel/hud system
63 static pCockpit ac_cockpit;
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 float get_latitude( void )
71 return current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
74 float get_lat_min( void )
78 a = current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
82 d = (double) ( (int) a);
83 float lat_min = (a - d) * 60.0;
89 float get_longitude( void )
91 return current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
96 get_formated_gmt_time( void )
99 const struct tm *p = globals->get_time_params()->getGmt();
100 sprintf( buf, "%d/%d/%4d %d:%02d:%02d",
101 p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
102 p->tm_hour, p->tm_min, p->tm_sec);
108 float get_long_min( void )
111 a = current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
115 d = (double) ( (int) a);
116 float lon_min = (a - d) * 60.0;
121 float get_throttleval( void )
123 // Hack limiting to one engine
124 return globals->get_controls()->get_throttle( 0 );
127 float get_aileronval( void )
129 return globals->get_controls()->get_aileron();
132 float get_elevatorval( void )
134 return globals->get_controls()->get_elevator();
137 float get_elev_trimval( void )
139 return globals->get_controls()->get_elevator_trim();
142 float get_rudderval( void )
144 return globals->get_controls()->get_rudder();
147 float get_speed( void )
149 static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
151 float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
152 * speedup_node->getIntValue();
159 return current_aircraft.fdm_state->get_Mach_number();
162 float get_aoa( void )
164 return current_aircraft.fdm_state->get_Alpha() * SGD_RADIANS_TO_DEGREES;
167 float get_roll( void )
169 return current_aircraft.fdm_state->get_Phi();
172 float get_pitch( void )
174 return current_aircraft.fdm_state->get_Theta();
177 float get_heading( void )
179 return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES;
182 float get_altitude( void )
184 static const SGPropertyNode *startup_units_node
185 = fgGetNode("/sim/startup/units");
189 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
190 altitude = current_aircraft.fdm_state->get_Altitude();
192 altitude = (current_aircraft.fdm_state->get_Altitude()
199 float get_agl( void )
201 static const SGPropertyNode *startup_units_node
202 = fgGetNode("/sim/startup/units");
206 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
207 agl = (current_aircraft.fdm_state->get_Altitude()
208 - globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET);
210 agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
211 - globals->get_scenery()->get_cur_elev());
217 float get_sideslip( void )
219 return current_aircraft.fdm_state->get_Beta();
222 float get_frame_rate( void )
224 return general.get_frame_rate();
227 float get_fov( void )
229 return globals->get_current_view()->get_fov();
232 float get_vfc_ratio( void )
234 // float vfc = current_view.get_vfc_ratio();
239 float get_vfc_tris_drawn ( void )
241 // float rendered = current_view.get_tris_rendered();
242 // return (rendered);
246 float get_vfc_tris_culled ( void )
248 // float culled = current_view.get_tris_culled();
253 float get_climb_rate( void )
255 static const SGPropertyNode *startup_units_node
256 = fgGetNode("/sim/startup/units");
259 if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
260 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
262 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
269 float get_view_direction( void )
271 double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
272 double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
273 * SGD_RADIANS_TO_DEGREES;
283 // Added by Markus Hof on 5. Jan 2004
284 float get_dme( void )
286 static const SGPropertyNode * dme_node =
287 fgGetNode("/radios/dme/distance-nm");
289 return dme_node->getFloatValue();
292 // $$$ begin - added, VS Renganathan 13 Oct 2K
293 // #ifdef FIGHTER_HUD
294 float get_Vx ( void )
296 // Curt dont comment this and return zero. - Ranga
297 // Please remove comments from get_V_..() function in flight.hxx
298 float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
302 float get_Vy ( void )
304 // Curt dont comment this and return zero. - Ranga
305 // Please remove comments from get_V_..() function in flight.hxx
306 float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
310 float get_Vz ( void )
312 // Curt dont comment this and return zero. - Ranga
313 // Please remove comments from get_V_..() function in flight.hxx
314 float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
318 float get_Ax ( void )
320 float Ax = current_aircraft.fdm_state->get_V_dot_north();
324 float get_Ay ( void )
326 float Ay = current_aircraft.fdm_state->get_V_dot_east();
330 float get_Az ( void )
332 float Az = current_aircraft.fdm_state->get_V_dot_down();
336 float get_anzg ( void )
338 float anzg = current_aircraft.fdm_state->get_N_Z_cg();
342 #ifdef ENABLE_SP_FMDS
345 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
346 return fdm->get_iaux(1);
351 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
352 return fdm->get_iaux(2);
357 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
358 return fdm->get_iaux(3);
363 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
364 return fdm->get_iaux(4);
369 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
370 return fdm->get_iaux(5);
375 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
376 return fdm->get_iaux(6);
381 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
382 return fdm->get_iaux(7);
387 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
388 return fdm->get_iaux(8);
393 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
394 return fdm->get_iaux(9);
397 int get_iaux10 (void)
399 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
400 return fdm->get_iaux(10);
403 int get_iaux11 (void)
405 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
406 return fdm->get_iaux(11);
409 int get_iaux12 (void)
411 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
412 return fdm->get_iaux(12);
415 float get_aux1 (void)
417 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
418 return fdm->get_daux(1);
421 float get_aux2 (void)
423 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
424 return fdm->get_daux(2);
427 float get_aux3 (void)
429 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
430 return fdm->get_daux(3);
433 float get_aux4 (void)
435 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
436 return fdm->get_daux(4);
439 float get_aux5 (void)
441 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
442 return fdm->get_daux(5);
445 float get_aux6 (void)
447 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
448 return fdm->get_daux(6);
451 float get_aux7 (void)
453 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
454 return fdm->get_daux(7);
457 float get_aux8 (void)
459 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
460 return fdm->get_daux(8);
463 float get_aux9 (void)
465 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
466 return fdm->get_faux(1);
469 float get_aux10 (void)
471 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
472 return fdm->get_faux(2);
475 float get_aux11 (void)
477 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
478 return fdm->get_faux(3);
481 float get_aux12 (void)
483 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
484 return fdm->get_faux(4);
487 float get_aux13 (void)
489 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
490 return fdm->get_faux(5);
493 float get_aux14 (void)
495 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
496 return fdm->get_faux(6);
499 float get_aux15 (void)
501 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
502 return fdm->get_faux(7);
505 float get_aux16 (void)
507 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
508 return fdm->get_faux(8);
511 float get_aux17 (void)
513 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
514 return fdm->get_faux(9);
517 float get_aux18 (void)
519 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
520 return fdm->get_faux(10);
523 // $$$ end - added, VS Renganathan 13 Oct 2K
527 /****************************************************************************/
528 /* Convert degrees to dd mm'ss.s" (DMS-Format) */
529 /****************************************************************************/
530 char *dmshh_format(double degrees)
541 min_part = 60.0 * (degrees - deg_part);
542 sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
544 /* Round off hundredths */
545 if (sec_part + 0.005 >= 60.0)
546 sec_part -= 60.0, min_part += 1;
548 min_part -= 60, deg_part += 1;
550 sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
557 /************************************************************************
558 Convert degrees to dd mm.mmm' (DMM-Format)
559 Description: Converts using a round-off factor tailored to the required
560 precision of the minutes field (three decimal places). Round-off
561 prevents function from returning a minutes value of 60.
563 Input arguments: Coordinate value in decimal degrees
565 ************************************************************************/
566 static char *toDM(float dd)
577 /* round for minutes expressed to three decimal places */
578 tempdd = fabs(dd) + (5.0E-4 / 60.0);
580 mn = fabs( (tempdd - (double)(deg)) * 60.0 - 4.999E-4 );
582 sprintf(dm, "%d*%06.3f", deg, mn);
587 /************************************************************************
588 Convert degrees to dd mm'ss.s'' (DMS-Format)
589 Description: Converts using a round-off factor tailored to the required
590 precision of the seconds field (one decimal place). Round-off
591 prevents function from returning a seconds value of 60.
593 Input arguments: Coordinate value in decimal degrees
595 ************************************************************************/
596 static char *toDMS(float dd)
599 double tempdd, tempmin;
608 /* round up for seconds expressed to one decimal place */
609 tempdd = fabs(dd) + (0.05 / 3600.0);
611 tempmin = (tempdd - (double)(deg)) * 60.0;
613 sec = fabs( (tempmin - (double)(mn)) * 60.0 - 0.049 );
615 sprintf(dms, "%d*%02d %04.1f", deg, mn, sec);
620 // Have to set the LatLon display type
621 //static char *(*fgLatLonFormat)(float) = toDM;
622 static char *(*fgLatLonFormat)(float);
624 char *coord_format_lat(float latitude)
629 // dmshh_format(latitude),
632 fgLatLonFormat(latitude),
633 latitude > 0 ? 'N' : 'S');
637 char *coord_format_lon(float longitude)
642 // dmshh_format(longitude),
645 fgLatLonFormat(longitude),
646 longitude > 0 ? 'E' : 'W');
650 void fgLatLonFormatToggle( puObject *)
652 static int toggle = 0;
655 fgLatLonFormat = toDM;
657 fgLatLonFormat = toDMS;
663 char *coord_format_latlon(double latitude, double longitude)
665 static char buf[1024];
667 sprintf(buf,"%s%c %s%c",
668 dmshh_format(latitude),
669 latitude > 0 ? 'N' : 'S',
670 dmshh_format(longitude),
671 longitude > 0 ? 'E' : 'W');
677 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
679 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
681 // cockpit->code = 1; /* It will be aircraft dependent */
682 // cockpit->status = 0;
684 // If aircraft has HUD specified we will get the specs from its def
685 // file. For now we will depend upon hard coding in hud?
687 // We must insure that the existing instrument link is purged.
688 // This is done by deleting the links in the list.
690 // HI_Head is now a null pointer so we can generate a new list from the
693 fgHUDInit( cur_aircraft );
694 ac_cockpit = new fg_Cockpit();
696 // Have to set the LatLon display type
697 fgLatLonFormat = toDM;
699 SG_LOG( SG_COCKPIT, SG_INFO,
700 " Code " << ac_cockpit->code() << " Status "
701 << ac_cockpit->status() );
706 void fgCockpitUpdate( void ) {
708 SG_LOG( SG_COCKPIT, SG_DEBUG,
709 "Cockpit: code " << ac_cockpit->code() << " status "
710 << ac_cockpit->status() );
712 static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
713 static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
714 static const SGPropertyNode * hud_visibility_node
715 = fgGetNode("/sim/hud/visibility");
717 int iwidth = xsize_node->getIntValue();
718 int iheight = ysize_node->getIntValue();
719 float width = iwidth;
720 // float height = iheight;
722 // FIXME: inefficient
723 if ( hud_visibility_node->getBoolValue() ) {
724 // This will check the global hud linked list pointer.
725 // If these is anything to draw it will.
729 if ( fgGetBool( "/sim/hud/draw-fps", false ) ) {
731 float fps = get_frame_rate();
732 sprintf(buf,"%-5.1f", fps);
734 glMatrixMode( GL_PROJECTION );
737 gluOrtho2D( 0, iwidth, 0, iheight );
738 glMatrixMode( GL_MODELVIEW );
742 glDisable( GL_DEPTH_TEST );
743 glDisable( GL_LIGHTING );
745 glColor3f( 0.9, 0.4, 0.2 );
747 guiFnt.drawString( buf,
748 int(width - guiFnt.getStringWidth(buf) - 10),
750 glEnable( GL_DEPTH_TEST );
751 glEnable( GL_LIGHTING );
752 glMatrixMode( GL_PROJECTION );
754 glMatrixMode( GL_MODELVIEW );
758 glViewport( 0, 0, iwidth, iheight );