]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/cockpit.cxx
Here is the 'boostified' event manager plus relevant changes to
[flightgear.git] / src / Cockpit / cockpit.cxx
1 // cockpit.cxx -- routines to draw a cockpit (initial draft)
2 //
3 // Written by Michele America, started September 1997.
4 //
5 // Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
6 //
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.
11 //
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.
16 //
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.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #ifdef HAVE_WINDOWS_H          
29 #  include <windows.h>
30 #endif
31
32 #include <GL/glut.h>
33
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #include <simgear/constants.h>
39 #include <simgear/debug/logstream.hxx>
40 #include <simgear/math/polar3d.hxx>
41 #include <simgear/misc/props.hxx>
42 #include <simgear/timing/sg_time.hxx>
43
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>
52 #include <GUI/gui.h>
53
54 #include "cockpit.hxx"
55
56
57 // This is a structure that contains all data related to
58 // cockpit/panel/hud system
59
60 static pCockpit ac_cockpit;
61 // The following routines obtain information concerntin the aircraft's
62 // current state and return it to calling instrument display routines.
63 // They should eventually be member functions of the aircraft.
64 //
65
66 float get_latitude( void )
67 {
68     return current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
69 }
70
71 float get_lat_min( void )
72 {
73     double a, d;
74
75     a = current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;    
76     if (a < 0.0) {
77         a = -a;
78     }
79     d = (double) ( (int) a);
80     float lat_min = (a - d) * 60.0;
81
82     return lat_min;
83 }
84
85
86 float get_longitude( void )
87 {
88     return current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
89 }
90
91
92 char*
93 get_formated_gmt_time( void )
94 {
95     static char buf[32];
96     const struct tm *p = globals->get_time_params()->getGmt();
97     sprintf( buf, "%d/%d/%4d %d:%02d:%02d", 
98          p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
99          p->tm_hour, p->tm_min, p->tm_sec);
100
101     return buf;
102 }
103
104
105 float get_long_min( void )
106 {
107     double  a, d;
108     a = current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;   
109     if (a < 0.0) {
110         a = -a;
111     }
112     d = (double) ( (int) a);
113     float lon_min = (a - d) * 60.0; 
114
115     return lon_min;
116 }
117
118 float get_throttleval( void )
119 {
120     // Hack limiting to one engine
121     return globals->get_controls()->get_throttle( 0 );
122 }
123
124 float get_aileronval( void )
125 {
126     return globals->get_controls()->get_aileron();
127 }
128
129 float get_elevatorval( void )
130 {
131     return globals->get_controls()->get_elevator();
132 }
133
134 float get_elev_trimval( void )
135 {
136     return globals->get_controls()->get_elevator_trim();
137 }
138
139 float get_rudderval( void )
140 {
141     return globals->get_controls()->get_rudder();
142 }
143
144 float get_speed( void )
145 {
146     static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
147
148     float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
149         * speedup_node->getIntValue();
150
151     return speed;
152 }
153
154 float get_mach(void)
155 {
156     return current_aircraft.fdm_state->get_Mach_number();
157 }       
158
159 float get_aoa( void )
160 {
161     return current_aircraft.fdm_state->get_Alpha() * SGD_RADIANS_TO_DEGREES;
162 }
163
164 float get_roll( void )
165 {
166     return current_aircraft.fdm_state->get_Phi();
167 }
168
169 float get_pitch( void )
170 {
171     return current_aircraft.fdm_state->get_Theta();
172 }
173
174 float get_heading( void )
175 {
176     return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES;
177 }
178
179 float get_altitude( void )
180 {
181     static const SGPropertyNode *startup_units_node
182         = fgGetNode("/sim/startup/units");
183
184     float altitude;
185
186     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
187         altitude = current_aircraft.fdm_state->get_Altitude();
188     } else {
189         altitude = (current_aircraft.fdm_state->get_Altitude()
190                     * SG_FEET_TO_METER);
191     }
192
193     return altitude;
194 }
195
196 float get_agl( void )
197 {
198     static const SGPropertyNode *startup_units_node
199         = fgGetNode("/sim/startup/units");
200
201     float agl;
202
203     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
204         agl = (current_aircraft.fdm_state->get_Altitude()
205                - scenery.get_cur_elev() * SG_METER_TO_FEET);
206     } else {
207         agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
208                - scenery.get_cur_elev());
209     }
210
211     return agl;
212 }
213
214 float get_sideslip( void )
215 {
216     return current_aircraft.fdm_state->get_Beta();
217 }
218
219 float get_frame_rate( void )
220 {
221     return general.get_frame_rate();
222 }
223
224 float get_fov( void )
225 {
226     return globals->get_current_view()->get_fov(); 
227 }
228
229 float get_vfc_ratio( void )
230 {
231     // float vfc = current_view.get_vfc_ratio();
232     // return (vfc);
233     return 0.0;
234 }
235
236 float get_vfc_tris_drawn   ( void )
237 {
238     // float rendered = current_view.get_tris_rendered();
239     // return (rendered);
240     return 0.0;
241 }
242
243 float get_vfc_tris_culled   ( void )
244 {
245     // float culled = current_view.get_tris_culled();
246     // return (culled);
247     return 0.0;
248 }
249
250 float get_climb_rate( void )
251 {
252     static const SGPropertyNode *startup_units_node
253         = fgGetNode("/sim/startup/units");
254
255     float climb_rate;
256     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
257         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
258     } else {
259         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
260     }
261
262     return climb_rate;
263 }
264
265
266 float get_view_direction( void )
267 {
268     double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
269     double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
270         * SGD_RADIANS_TO_DEGREES;
271     
272     if(view > 360.)
273         view -= 360.;
274     else if(view<0.)
275         view += 360.;
276     
277     return view;
278 }
279
280 // $$$ begin - added, VS Renganathan 13 Oct 2K
281 // #ifdef FIGHTER_HUD
282 float get_Vx   ( void )
283 {
284     // Curt dont comment this and return zero. - Ranga
285     // Please remove comments from get_V_..() function in flight.hxx
286     float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
287     return Vxx;
288 }
289
290 float get_Vy   ( void )
291 {
292     // Curt dont comment this and return zero. - Ranga
293     // Please remove comments from get_V_..() function in flight.hxx
294     float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
295     return Vyy;
296 }
297
298 float get_Vz   ( void )
299 {
300     // Curt dont comment this and return zero. - Ranga
301     // Please remove comments from get_V_..() function in flight.hxx
302     float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
303     return Vzz;
304 }
305
306 float get_Ax   ( void )
307 {
308     float Ax = current_aircraft.fdm_state->get_V_dot_north();
309     return Ax;
310 }
311
312 float get_Ay   ( void )
313 {
314     float Ay = current_aircraft.fdm_state->get_V_dot_east();
315     return Ay;
316 }
317
318 float get_Az   ( void )
319 {
320     float Az = current_aircraft.fdm_state->get_V_dot_down();
321     return Az;
322 }
323
324 float get_anzg   ( void )
325 {
326     float anzg = current_aircraft.fdm_state->get_N_Z_cg();
327     return anzg;
328 }
329
330 int get_iaux1 (void)
331 {
332     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
333     return fdm->get_iaux(1);
334 }
335
336 int get_iaux2 (void)
337 {
338     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
339     return fdm->get_iaux(2);
340 }
341
342 int get_iaux3 (void)
343 {
344     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
345     return fdm->get_iaux(3);
346 }
347
348 int get_iaux4 (void)
349 {
350     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
351     return fdm->get_iaux(4);
352 }
353
354 int get_iaux5 (void)
355 {
356     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
357     return fdm->get_iaux(5);
358 }
359
360 int get_iaux6 (void)
361 {
362     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
363     return fdm->get_iaux(6);
364 }
365
366 int get_iaux7 (void)
367 {
368     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
369     return fdm->get_iaux(7);
370 }
371
372 int get_iaux8 (void)
373 {
374     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
375     return fdm->get_iaux(8);
376 }
377
378 int get_iaux9 (void)
379 {
380     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
381     return fdm->get_iaux(9);
382 }
383
384 int get_iaux10 (void)
385 {
386     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
387     return fdm->get_iaux(10);
388 }
389
390 int get_iaux11 (void)
391 {
392     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
393     return fdm->get_iaux(11);
394 }
395
396 int get_iaux12 (void)
397 {
398      FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
399      return fdm->get_iaux(12);
400 }
401
402 float get_aux1 (void)
403 {
404     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
405     return fdm->get_daux(1);
406 }
407
408 float get_aux2 (void)
409 {
410     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
411     return fdm->get_daux(2);
412 }
413
414 float get_aux3 (void)
415 {
416     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
417     return fdm->get_daux(3);
418 }
419
420 float get_aux4 (void)
421 {
422     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
423     return fdm->get_daux(4);
424 }
425
426 float get_aux5 (void)
427 {
428     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
429     return fdm->get_daux(5);
430 }
431
432 float get_aux6 (void)
433 {
434     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
435     return fdm->get_daux(6);
436 }
437
438 float get_aux7 (void)
439 {
440     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
441     return fdm->get_daux(7);
442 }
443
444 float get_aux8 (void)
445 {
446     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
447     return fdm->get_daux(8);
448 }
449
450 float get_aux9 (void)
451 {
452     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
453     return fdm->get_faux(1);
454 }
455
456 float get_aux10 (void)
457 {
458     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
459     return fdm->get_faux(2);
460 }
461
462 float get_aux11 (void)
463 {
464     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
465     return fdm->get_faux(3);
466 }
467
468 float get_aux12 (void)
469 {
470     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
471     return fdm->get_faux(4);
472 }
473
474 float get_aux13 (void)
475 {
476     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
477     return fdm->get_faux(5);
478 }
479
480 float get_aux14 (void)
481 {
482     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
483     return fdm->get_faux(6);
484 }
485
486 float get_aux15 (void)
487 {
488     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
489     return fdm->get_faux(7);
490 }
491
492 float get_aux16 (void)
493 {
494     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
495     return fdm->get_faux(8);
496 }
497
498 float get_aux17 (void)
499 {
500     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
501     return fdm->get_faux(9);
502 }
503
504 float get_aux18 (void)
505 {
506     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
507     return fdm->get_faux(10);
508 }
509 // #endif
510 // $$$ end - added, VS Renganathan 13 Oct 2K
511
512
513 #ifdef NOT_USED
514 /****************************************************************************/
515 /* Convert degrees to dd mm'ss.s" (DMS-Format)                              */
516 /****************************************************************************/
517 char *dmshh_format(double degrees)
518 {
519     static char buf[16];    
520     int deg_part;
521     int min_part;
522     double sec_part;
523     
524     if (degrees < 0)
525       degrees = -degrees;
526
527     deg_part = degrees;
528     min_part = 60.0 * (degrees - deg_part);
529     sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
530
531     /* Round off hundredths */
532     if (sec_part + 0.005 >= 60.0)
533       sec_part -= 60.0, min_part += 1;
534     if (min_part >= 60)
535       min_part -= 60, deg_part += 1;
536
537     sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
538
539     return buf;
540 }
541 #endif // 0
542
543
544 /************************************************************************
545  Convert degrees to dd mm.mmm' (DMM-Format)
546  Description: Converts using a round-off factor tailored to the required
547  precision of the minutes field (three decimal places).  Round-off
548  prevents function from returning a minutes value of 60.
549
550  Input arguments: Coordinate value in decimal degrees
551
552 ************************************************************************/
553 static char *toDM(float dd)
554 {
555     static char  dm[16];
556     double tempdd;
557     double mn;
558     double sign = 1;
559     int deg;
560
561     if (dd < 0) {
562         sign = -1;
563     }
564     /* round for minutes expressed to three decimal places */
565     tempdd = fabs(dd) + (5.0E-4 / 60.0);
566     deg = (int)tempdd;
567     mn = fabs( (tempdd - (double)(deg)) * 60.0 - 4.999E-4 );
568     deg *= (int)sign;
569     sprintf(dm, "%d*%06.3f", deg, mn);
570     return dm;
571 }
572
573
574 /************************************************************************
575  Convert degrees to dd mm'ss.s'' (DMS-Format)
576  Description: Converts using a round-off factor tailored to the required
577  precision of the seconds field (one decimal place).  Round-off
578  prevents function from returning a seconds value of 60.
579
580  Input arguments: Coordinate value in decimal degrees
581
582 ************************************************************************/
583 static char *toDMS(float dd)
584 {
585     static char  dms[16];
586     double tempdd, tempmin;
587     int deg;
588     int mn;
589     double sec;
590     double sign = 1;
591
592     if(dd < 0) {
593         sign = -1;
594     }
595     /* round up for seconds expressed to one decimal place */
596     tempdd = fabs(dd) + (0.05 / 3600.0);
597     deg = (int)tempdd;
598     tempmin =  (tempdd - (double)(deg)) * 60.0;
599     mn = (int)tempmin;
600     sec = fabs( (tempmin - (double)(mn)) * 60.0 - 0.049 );
601     deg *= (int)sign;
602     sprintf(dms, "%d*%02d %04.1f", deg, mn, sec);
603     return dms;
604 }
605
606
607 // Have to set the LatLon display type
608 //static char *(*fgLatLonFormat)(float) = toDM;
609 static char *(*fgLatLonFormat)(float);
610
611 char *coord_format_lat(float latitude)
612 {
613     static char buf[16];
614
615     sprintf(buf,"%s%c",
616 //      dmshh_format(latitude),
617 //      toDMS(latitude),
618 //      toDM(latitude),
619         fgLatLonFormat(latitude),           
620         latitude > 0 ? 'N' : 'S');
621     return buf;
622 }
623
624 char *coord_format_lon(float longitude)
625 {
626     static char buf[80];
627
628     sprintf(buf,"%s%c",
629 //      dmshh_format(longitude),
630 //      toDMS(longitude),
631 //      toDM(longitude),
632         fgLatLonFormat(longitude),
633         longitude > 0 ? 'E' : 'W');
634     return buf;
635 }
636
637 void fgLatLonFormatToggle( puObject *)
638 {
639     static int toggle = 0;
640
641     if ( toggle ) 
642         fgLatLonFormat = toDM;
643     else
644         fgLatLonFormat = toDMS;
645     
646     toggle = ~toggle;
647 }
648
649 #ifdef NOT_USED
650 char *coord_format_latlon(double latitude, double longitude)
651 {
652     static char buf[1024];
653
654     sprintf(buf,"%s%c %s%c",
655         dmshh_format(latitude),
656         latitude > 0 ? 'N' : 'S',
657         dmshh_format(longitude),
658         longitude > 0 ? 'E' : 'W');
659     return buf;
660 }
661 #endif
662
663
664 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
665 {
666     SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
667
668     //  cockpit->code = 1;  /* It will be aircraft dependent */
669     //  cockpit->status = 0;
670
671     // If aircraft has HUD specified we will get the specs from its def
672     // file. For now we will depend upon hard coding in hud?
673     
674     // We must insure that the existing instrument link is purged.
675     // This is done by deleting the links in the list.
676     
677     // HI_Head is now a null pointer so we can generate a new list from the
678     // current aircraft.
679
680     fgHUDInit( cur_aircraft );
681     ac_cockpit = new fg_Cockpit();
682     
683     // Have to set the LatLon display type
684     fgLatLonFormat = toDM;
685     
686     SG_LOG( SG_COCKPIT, SG_INFO,
687         "  Code " << ac_cockpit->code() << " Status " 
688         << ac_cockpit->status() );
689
690         return true;
691 }
692
693 void fgCockpitUpdate( void ) {
694
695     SG_LOG( SG_COCKPIT, SG_DEBUG,
696             "Cockpit: code " << ac_cockpit->code() << " status " 
697             << ac_cockpit->status() );
698
699     static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
700     static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
701     static const SGPropertyNode * hud_visibility_node
702         = fgGetNode("/sim/hud/visibility");
703
704     int iwidth   = xsize_node->getIntValue();
705     int iheight  = ysize_node->getIntValue();
706     float width  = iwidth;
707     // float height = iheight;
708
709                                 // FIXME: inefficient
710     if ( hud_visibility_node->getBoolValue() ) {
711         // This will check the global hud linked list pointer.
712         // If these is anything to draw it will.
713         fgUpdateHUD();
714     }
715
716 #define DISPLAY_COUNTER
717 #ifdef DISPLAY_COUNTER
718     else
719     {
720         char buf[64];
721         float fps    =       get_frame_rate();
722 //      float tris   = fps * get_vfc_tris_drawn();
723 //      float culled = fps * get_vfc_tris_culled();
724 //      sprintf(buf,"%-4.1f  %7.0f  %7.0f", fps, tris, culled);
725         sprintf(buf,"%-5.1f", fps);
726
727         glMatrixMode( GL_PROJECTION );
728         glPushMatrix();
729         glLoadIdentity();
730         gluOrtho2D( 0, iwidth, 0, iheight );
731         glMatrixMode( GL_MODELVIEW );
732         glPushMatrix();
733         glLoadIdentity();
734
735         glDisable( GL_DEPTH_TEST );
736         glDisable( GL_LIGHTING );
737         
738         glColor3f( 0.9, 0.4, 0.2 );
739
740         guiFnt.drawString( buf,
741                            int(width - guiFnt.getStringWidth(buf) - 10),
742                            10 );
743         glEnable( GL_DEPTH_TEST );
744         glEnable( GL_LIGHTING );
745         glMatrixMode( GL_PROJECTION );
746         glPopMatrix();
747         glMatrixMode( GL_MODELVIEW );
748         glPopMatrix();
749     }
750 #endif // #ifdef DISPLAY_COUNTER
751     
752     glViewport( 0, 0, iwidth, iheight );
753 }
754