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