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/misc/props.hxx>
43 #include <Aircraft/aircraft.hxx>
44 #include <Include/general.hxx>
45 #include <FDM/ADA.hxx>
46 #include <Main/globals.hxx>
47 #include <Main/fg_props.hxx>
48 #include <Main/viewmgr.hxx>
49 #include <Scenery/scenery.hxx>
50 #include <Time/fg_timer.hxx>
53 #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 ( 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 )
199 if ( fgGetString("/sim/startup/units") == "feet" ) {
200 agl = (current_aircraft.fdm_state->get_Altitude()
201 - scenery.cur_elev * SG_METER_TO_FEET);
203 agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
210 float get_sideslip( void )
212 return current_aircraft.fdm_state->get_Beta();
215 float get_frame_rate( void )
217 return general.get_frame_rate();
220 float get_fov( void )
222 return globals->get_current_view()->get_fov();
225 float get_vfc_ratio( void )
227 // float vfc = current_view.get_vfc_ratio();
232 float get_vfc_tris_drawn ( void )
234 // float rendered = current_view.get_tris_rendered();
235 // return (rendered);
239 float get_vfc_tris_culled ( void )
241 // float culled = current_view.get_tris_culled();
246 float get_climb_rate( void )
249 if ( fgGetString("/sim/startup/units") == "feet" ) {
250 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
252 climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
259 float get_view_direction( void )
261 double view_off = SGD_2PI - globals->get_current_view()->get_view_offset();
262 double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
263 * SGD_RADIANS_TO_DEGREES;
273 // $$$ begin - added, VS Renganathan 13 Oct 2K
274 // #ifdef FIGHTER_HUD
275 float get_Vx ( void )
277 // Curt dont comment this and return zero. - Ranga
278 // Please remove comments from get_V_..() function in flight.hxx
279 float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
283 float get_Vy ( void )
285 // Curt dont comment this and return zero. - Ranga
286 // Please remove comments from get_V_..() function in flight.hxx
287 float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
291 float get_Vz ( void )
293 // Curt dont comment this and return zero. - Ranga
294 // Please remove comments from get_V_..() function in flight.hxx
295 float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
299 float get_Ax ( void )
301 float Ax = current_aircraft.fdm_state->get_V_dot_north();
305 float get_Ay ( void )
307 float Ay = current_aircraft.fdm_state->get_V_dot_east();
311 float get_Az ( void )
313 float Az = current_aircraft.fdm_state->get_V_dot_down();
317 float get_anzg ( void )
319 float anzg = current_aircraft.fdm_state->get_N_Z_cg();
325 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
326 return fdm->get_iaux(1);
331 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
332 return fdm->get_iaux(2);
337 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
338 return fdm->get_iaux(3);
343 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
344 return fdm->get_iaux(4);
349 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
350 return fdm->get_iaux(5);
355 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
356 return fdm->get_iaux(6);
361 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
362 return fdm->get_iaux(7);
367 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
368 return fdm->get_iaux(8);
373 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
374 return fdm->get_iaux(9);
377 int get_iaux10 (void)
379 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
380 return fdm->get_iaux(10);
383 int get_iaux11 (void)
385 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
386 return fdm->get_iaux(11);
389 int get_iaux12 (void)
391 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
392 return fdm->get_iaux(12);
395 float get_aux1 (void)
397 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
398 return fdm->get_daux(1);
401 float get_aux2 (void)
403 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
404 return fdm->get_daux(2);
407 float get_aux3 (void)
409 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
410 return fdm->get_daux(3);
413 float get_aux4 (void)
415 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
416 return fdm->get_daux(4);
419 float get_aux5 (void)
421 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
422 return fdm->get_daux(5);
425 float get_aux6 (void)
427 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
428 return fdm->get_daux(6);
431 float get_aux7 (void)
433 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
434 return fdm->get_daux(7);
437 float get_aux8 (void)
439 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
440 return fdm->get_daux(8);
443 float get_aux9 (void)
445 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
446 return fdm->get_faux(1);
449 float get_aux10 (void)
451 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
452 return fdm->get_faux(2);
455 float get_aux11 (void)
457 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
458 return fdm->get_faux(3);
461 float get_aux12 (void)
463 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
464 return fdm->get_faux(4);
467 float get_aux13 (void)
469 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
470 return fdm->get_faux(5);
473 float get_aux14 (void)
475 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
476 return fdm->get_faux(6);
479 float get_aux15 (void)
481 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
482 return fdm->get_faux(7);
485 float get_aux16 (void)
487 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
488 return fdm->get_faux(8);
491 float get_aux17 (void)
493 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
494 return fdm->get_faux(9);
497 float get_aux18 (void)
499 FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
500 return fdm->get_faux(10);
503 // $$$ end - added, VS Renganathan 13 Oct 2K
507 /****************************************************************************/
508 /* Convert degrees to dd mm'ss.s" (DMS-Format) */
509 /****************************************************************************/
510 char *dmshh_format(double degrees)
521 min_part = 60.0 * (degrees - deg_part);
522 sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
524 /* Round off hundredths */
525 if (sec_part + 0.005 >= 60.0)
526 sec_part -= 60.0, min_part += 1;
528 min_part -= 60, deg_part += 1;
530 sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
537 /************************************************************************
538 Convert degrees to dd mm.mmm' (DMM-Format)
539 Description: Converts using a round-off factor tailored to the required
540 precision of the minutes field (three decimal places). Round-off
541 prevents function from returning a minutes value of 60.
543 Input arguments: Coordinate value in decimal degrees
545 ************************************************************************/
546 static char *toDM(float dd)
557 /* round for minutes expressed to three decimal places */
558 tempdd = fabs(dd) + (5.0E-4 / 60.0);
560 mn = fabs( (tempdd - (double)(deg)) * 60.0 - 4.999E-4 );
562 sprintf(dm, "%d*%06.3f", deg, mn);
567 /************************************************************************
568 Convert degrees to dd mm'ss.s'' (DMS-Format)
569 Description: Converts using a round-off factor tailored to the required
570 precision of the seconds field (one decimal place). Round-off
571 prevents function from returning a seconds value of 60.
573 Input arguments: Coordinate value in decimal degrees
575 ************************************************************************/
576 static char *toDMS(float dd)
579 double tempdd, tempmin;
588 /* round up for seconds expressed to one decimal place */
589 tempdd = fabs(dd) + (0.05 / 3600.0);
591 tempmin = (tempdd - (double)(deg)) * 60.0;
593 sec = fabs( (tempmin - (double)(mn)) * 60.0 - 0.049 );
595 sprintf(dms, "%d*%02d %04.1f", deg, mn, sec);
600 // Have to set the LatLon display type
601 //static char *(*fgLatLonFormat)(float) = toDM;
602 static char *(*fgLatLonFormat)(float);
604 char *coord_format_lat(float latitude)
609 // dmshh_format(latitude),
612 fgLatLonFormat(latitude),
613 latitude > 0 ? 'N' : 'S');
617 char *coord_format_lon(float longitude)
622 // dmshh_format(longitude),
625 fgLatLonFormat(longitude),
626 longitude > 0 ? 'E' : 'W');
630 void fgLatLonFormatToggle( puObject *)
632 static int toggle = 0;
635 fgLatLonFormat = toDM;
637 fgLatLonFormat = toDMS;
643 char *coord_format_latlon(double latitude, double longitude)
645 static char buf[1024];
647 sprintf(buf,"%s%c %s%c",
648 dmshh_format(latitude),
649 latitude > 0 ? 'N' : 'S',
650 dmshh_format(longitude),
651 longitude > 0 ? 'E' : 'W');
657 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
659 SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
661 // cockpit->code = 1; /* It will be aircraft dependent */
662 // cockpit->status = 0;
664 // If aircraft has HUD specified we will get the specs from its def
665 // file. For now we will depend upon hard coding in hud?
667 // We must insure that the existing instrument link is purged.
668 // This is done by deleting the links in the list.
670 // HI_Head is now a null pointer so we can generate a new list from the
673 fgHUDInit( cur_aircraft );
674 ac_cockpit = new fg_Cockpit();
676 // Have to set the LatLon display type
677 fgLatLonFormat = toDM;
679 SG_LOG( SG_COCKPIT, SG_INFO,
680 " Code " << ac_cockpit->code() << " Status "
681 << ac_cockpit->status() );
686 void fgCockpitUpdate( void ) {
688 SG_LOG( SG_COCKPIT, SG_DEBUG,
689 "Cockpit: code " << ac_cockpit->code() << " status "
690 << ac_cockpit->status() );
692 static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
693 static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
694 static const SGPropertyNode * hud_visibility_node
695 = fgGetNode("/sim/hud/visibility");
697 int iwidth = xsize_node->getIntValue();
698 int iheight = ysize_node->getIntValue();
699 float width = iwidth;
700 // float height = iheight;
702 // FIXME: inefficient
703 if ( hud_visibility_node->getBoolValue() ) {
704 // This will check the global hud linked list pointer.
705 // If these is anything to draw it will.
709 #define DISPLAY_COUNTER
710 #ifdef DISPLAY_COUNTER
714 float fps = get_frame_rate();
715 // float tris = fps * get_vfc_tris_drawn();
716 // float culled = fps * get_vfc_tris_culled();
717 // sprintf(buf,"%-4.1f %7.0f %7.0f", fps, tris, culled);
718 sprintf(buf,"%-5.1f", fps);
720 glMatrixMode( GL_PROJECTION );
723 gluOrtho2D( 0, iwidth, 0, iheight );
724 glMatrixMode( GL_MODELVIEW );
728 glDisable( GL_DEPTH_TEST );
729 glDisable( GL_LIGHTING );
731 glColor3f( 0.9, 0.4, 0.2 );
733 guiFnt.drawString( buf,
734 int(width - guiFnt.getStringWidth(buf) - 10),
736 glEnable( GL_DEPTH_TEST );
737 glEnable( GL_LIGHTING );
738 glMatrixMode( GL_PROJECTION );
740 glMatrixMode( GL_MODELVIEW );
743 #endif // #ifdef DISPLAY_COUNTER
745 glViewport( 0, 0, iwidth, iheight );