Use one standard define for enableing of the Special Purpose FDM code.
[fg:hoorays-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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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 <simgear/compiler.h>
33
34 #include SG_GLU_H
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39
40 #include <simgear/constants.h>
41 #include <simgear/debug/logstream.hxx>
42 #include <simgear/math/polar3d.hxx>
43 #include <simgear/props/props.hxx>
44 #include <simgear/timing/sg_time.hxx>
45
46 #include <Aircraft/aircraft.hxx>
47 #include <Include/general.hxx>
48 #ifdef ENABLE_SP_FDM
49 #include <FDM/SP/ADA.hxx>
50 #endif
51 #include <Main/globals.hxx>
52 #include <Main/fg_props.hxx>
53 #include <Main/viewmgr.hxx>
54 #include <Scenery/scenery.hxx>
55 #include <Time/fg_timer.hxx>
56 #include <GUI/gui.h>
57
58 #include "cockpit.hxx"
59 #include "hud.hxx"
60
61
62 // This is a structure that contains all data related to
63 // cockpit/panel/hud system
64
65 static pCockpit ac_cockpit;
66 // The following routines obtain information concerntin the aircraft's
67 // current state and return it to calling instrument display routines.
68 // They should eventually be member functions of the aircraft.
69 //
70
71 float get_latitude( void )
72 {
73     return current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
74 }
75
76 float get_lat_min( void )
77 {
78     double a, d;
79
80     a = current_aircraft.fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES;
81     if (a < 0.0) {
82         a = -a;
83     }
84     d = (double) ( (int) a);
85     float lat_min = (a - d) * 60.0;
86
87     return lat_min;
88 }
89
90
91 float get_longitude( void )
92 {
93     return current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
94 }
95
96
97 char*
98 get_formated_gmt_time( void )
99 {
100     static char buf[32];
101     const struct tm *p = globals->get_time_params()->getGmt();
102     sprintf( buf, "%d/%d/%4d %d:%02d:%02d",
103          p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
104          p->tm_hour, p->tm_min, p->tm_sec);
105
106     return buf;
107 }
108
109
110 float get_long_min( void )
111 {
112     double  a, d;
113     a = current_aircraft.fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES;
114     if (a < 0.0) {
115         a = -a;
116     }
117     d = (double) ( (int) a);
118     float lon_min = (a - d) * 60.0;
119
120     return lon_min;
121 }
122
123 float get_throttleval( void )
124 {
125     // Hack limiting to one engine
126     return globals->get_controls()->get_throttle( 0 );
127 }
128
129 float get_aileronval( void )
130 {
131     return globals->get_controls()->get_aileron();
132 }
133
134 float get_elevatorval( void )
135 {
136     return globals->get_controls()->get_elevator();
137 }
138
139 float get_elev_trimval( void )
140 {
141     return globals->get_controls()->get_elevator_trim();
142 }
143
144 float get_rudderval( void )
145 {
146     return globals->get_controls()->get_rudder();
147 }
148
149 float get_speed( void )
150 {
151     static const SGPropertyNode * speedup_node = fgGetNode("/sim/speed-up");
152
153     float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
154         * speedup_node->getIntValue();
155
156     return speed;
157 }
158
159 float get_mach(void)
160 {
161     return current_aircraft.fdm_state->get_Mach_number();
162 }
163
164 float get_aoa( void )
165 {
166     return current_aircraft.fdm_state->get_Alpha() * SGD_RADIANS_TO_DEGREES;
167 }
168
169 float get_roll( void )
170 {
171     return current_aircraft.fdm_state->get_Phi();
172 }
173
174 float get_pitch( void )
175 {
176     return current_aircraft.fdm_state->get_Theta();
177 }
178
179 float get_heading( void )
180 {
181     return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES;
182 }
183
184 float get_altitude( void )
185 {
186     static const SGPropertyNode *startup_units_node
187         = fgGetNode("/sim/startup/units");
188
189     float altitude;
190
191     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
192         altitude = current_aircraft.fdm_state->get_Altitude();
193     } else {
194         altitude = (current_aircraft.fdm_state->get_Altitude()
195                     * SG_FEET_TO_METER);
196     }
197
198     return altitude;
199 }
200
201 float get_agl( void )
202 {
203     static const SGPropertyNode *startup_units_node
204         = fgGetNode("/sim/startup/units");
205
206     float agl;
207
208     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
209         agl = (current_aircraft.fdm_state->get_Altitude()
210                - current_aircraft.fdm_state->get_Runway_altitude());
211     } else {
212         agl = (current_aircraft.fdm_state->get_Altitude()
213                - current_aircraft.fdm_state->get_Runway_altitude()) * SG_FEET_TO_METER;
214     }
215
216     return agl;
217 }
218
219 float get_sideslip( void )
220 {
221     return current_aircraft.fdm_state->get_Beta();
222 }
223
224 float get_frame_rate( void )
225 {
226     return general.get_frame_rate();
227 }
228
229 float get_fov( void )
230 {
231     return globals->get_current_view()->get_fov();
232 }
233
234 float get_vfc_ratio( void )
235 {
236     // float vfc = current_view.get_vfc_ratio();
237     // return (vfc);
238     return 0.0;
239 }
240
241 float get_vfc_tris_drawn   ( void )
242 {
243     // float rendered = current_view.get_tris_rendered();
244     // return (rendered);
245     return 0.0;
246 }
247
248 float get_vfc_tris_culled   ( void )
249 {
250     // float culled = current_view.get_tris_culled();
251     // return (culled);
252     return 0.0;
253 }
254
255 float get_climb_rate( void )
256 {
257     static const SGPropertyNode *startup_units_node
258         = fgGetNode("/sim/startup/units");
259
260     float climb_rate;
261     if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
262         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
263     } else {
264         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * SG_FEET_TO_METER * 60.0;
265     }
266
267     return climb_rate;
268 }
269
270
271 float get_view_direction( void )
272 {
273     double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
274     double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
275         * SGD_RADIANS_TO_DEGREES;
276
277     if (view > 360.)
278         view -= 360.;
279     else if (view<0.)
280         view += 360.;
281
282     return view;
283 }
284
285 // Added by Markus Hof on 5. Jan 2004
286 float get_dme( void )
287 {
288     static const SGPropertyNode * dme_node =
289         fgGetNode("/instrumentation/dme/indicated-distance-nm");
290
291     return dme_node->getFloatValue();
292 }
293
294 // $$$ begin - added, VS Renganathan 13 Oct 2K
295 // #ifdef FIGHTER_HUD
296 float get_Vx   ( void )
297 {
298     // Curt dont comment this and return zero. - Ranga
299     // Please remove comments from get_V_..() function in flight.hxx
300     float Vxx = current_aircraft.fdm_state->get_V_north_rel_ground();
301     return Vxx;
302 }
303
304 float get_Vy   ( void )
305 {
306     // Curt dont comment this and return zero. - Ranga
307     // Please remove comments from get_V_..() function in flight.hxx
308     float Vyy = current_aircraft.fdm_state->get_V_east_rel_ground();
309     return Vyy;
310 }
311
312 float get_Vz   ( void )
313 {
314     // Curt dont comment this and return zero. - Ranga
315     // Please remove comments from get_V_..() function in flight.hxx
316     float Vzz = current_aircraft.fdm_state->get_V_down_rel_ground();
317     return Vzz;
318 }
319
320 float get_Ax   ( void )
321 {
322     float Ax = current_aircraft.fdm_state->get_V_dot_north();
323     return Ax;
324 }
325
326 float get_Ay   ( void )
327 {
328     float Ay = current_aircraft.fdm_state->get_V_dot_east();
329     return Ay;
330 }
331
332 float get_Az   ( void )
333 {
334     float Az = current_aircraft.fdm_state->get_V_dot_down();
335     return Az;
336 }
337
338 float get_anzg   ( void )
339 {
340     float anzg = current_aircraft.fdm_state->get_N_Z_cg();
341     return anzg;
342 }
343
344 #ifdef ENABLE_SP_FDM
345 int get_iaux1 (void)
346 {
347     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
348     return fdm->get_iaux(1);
349 }
350
351 int get_iaux2 (void)
352 {
353     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
354     return fdm->get_iaux(2);
355 }
356
357 int get_iaux3 (void)
358 {
359     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
360     return fdm->get_iaux(3);
361 }
362
363 int get_iaux4 (void)
364 {
365     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
366     return fdm->get_iaux(4);
367 }
368
369 int get_iaux5 (void)
370 {
371     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
372     return fdm->get_iaux(5);
373 }
374
375 int get_iaux6 (void)
376 {
377     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
378     return fdm->get_iaux(6);
379 }
380
381 int get_iaux7 (void)
382 {
383     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
384     return fdm->get_iaux(7);
385 }
386
387 int get_iaux8 (void)
388 {
389     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
390     return fdm->get_iaux(8);
391 }
392
393 int get_iaux9 (void)
394 {
395     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
396     return fdm->get_iaux(9);
397 }
398
399 int get_iaux10 (void)
400 {
401     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
402     return fdm->get_iaux(10);
403 }
404
405 int get_iaux11 (void)
406 {
407     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
408     return fdm->get_iaux(11);
409 }
410
411 int get_iaux12 (void)
412 {
413      FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
414      return fdm->get_iaux(12);
415 }
416
417 float get_aux1 (void)
418 {
419     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
420     return fdm->get_daux(1);
421 }
422
423 float get_aux2 (void)
424 {
425     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
426     return fdm->get_daux(2);
427 }
428
429 float get_aux3 (void)
430 {
431     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
432     return fdm->get_daux(3);
433 }
434
435 float get_aux4 (void)
436 {
437     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
438     return fdm->get_daux(4);
439 }
440
441 float get_aux5 (void)
442 {
443     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
444     return fdm->get_daux(5);
445 }
446
447 float get_aux6 (void)
448 {
449     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
450     return fdm->get_daux(6);
451 }
452
453 float get_aux7 (void)
454 {
455     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
456     return fdm->get_daux(7);
457 }
458
459 float get_aux8 (void)
460 {
461     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
462     return fdm->get_daux(8);
463 }
464
465 float get_aux9 (void)
466 {
467     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
468     return fdm->get_faux(1);
469 }
470
471 float get_aux10 (void)
472 {
473     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
474     return fdm->get_faux(2);
475 }
476
477 float get_aux11 (void)
478 {
479     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
480     return fdm->get_faux(3);
481 }
482
483 float get_aux12 (void)
484 {
485     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
486     return fdm->get_faux(4);
487 }
488
489 float get_aux13 (void)
490 {
491     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
492     return fdm->get_faux(5);
493 }
494
495 float get_aux14 (void)
496 {
497     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
498     return fdm->get_faux(6);
499 }
500
501 float get_aux15 (void)
502 {
503     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
504     return fdm->get_faux(7);
505 }
506
507 float get_aux16 (void)
508 {
509     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
510     return fdm->get_faux(8);
511 }
512
513 float get_aux17 (void)
514 {
515     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
516     return fdm->get_faux(9);
517 }
518
519 float get_aux18 (void)
520 {
521     FGADA *fdm = (FGADA *)current_aircraft.fdm_state;
522     return fdm->get_faux(10);
523 }
524 #endif
525
526
527 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
528 {
529     SG_LOG( SG_COCKPIT, SG_INFO, "Initializing cockpit subsystem" );
530
531     //  cockpit->code = 1;  /* It will be aircraft dependent */
532     //  cockpit->status = 0;
533
534     // If aircraft has HUD specified we will get the specs from its def
535     // file. For now we will depend upon hard coding in hud?
536
537     // We must insure that the existing instrument link is purged.
538     // This is done by deleting the links in the list.
539
540     // HI_Head is now a null pointer so we can generate a new list from the
541     // current aircraft.
542
543     fgHUDInit( cur_aircraft );
544     ac_cockpit = new fg_Cockpit();
545
546     SG_LOG( SG_COCKPIT, SG_INFO,
547         "  Code " << ac_cockpit->code() << " Status "
548         << ac_cockpit->status() );
549
550     return true;
551 }
552
553 void fgCockpitUpdate( void ) {
554
555     SG_LOG( SG_COCKPIT, SG_DEBUG,
556             "Cockpit: code " << ac_cockpit->code() << " status "
557             << ac_cockpit->status() );
558
559     static const SGPropertyNode * xsize_node = fgGetNode("/sim/startup/xsize");
560     static const SGPropertyNode * ysize_node = fgGetNode("/sim/startup/ysize");
561     static const SGPropertyNode * hud_visibility_node
562         = fgGetNode("/sim/hud/visibility");
563
564     int iwidth   = xsize_node->getIntValue();
565     int iheight  = ysize_node->getIntValue();
566
567                                 // FIXME: inefficient
568     if ( hud_visibility_node->getBoolValue() ) {
569         // This will check the global hud linked list pointer.
570         // If there is anything to draw it will.
571         fgUpdateHUD();
572     }
573
574     glViewport( 0, 0, iwidth, iheight );
575 }
576
577
578
579
580
581 struct FuncTable {
582     char *name;
583     FLTFNPTR func;
584 } fn_table[] = {
585     { "agl", get_agl },
586     { "aileronval", get_aileronval },
587     { "altitude", get_altitude },
588     { "anzg", get_anzg },
589     { "aoa", get_aoa },
590     { "ax", get_Ax },
591     { "climb", get_climb_rate },
592     { "elevatortrimval", get_elev_trimval },
593     { "elevatorval", get_elevatorval },
594     { "fov", get_fov },
595     { "framerate", get_frame_rate },
596     { "heading", get_heading },
597     { "latitude", get_latitude },
598     { "longitude", get_longitude },
599     { "mach", get_mach },
600     { "rudderval", get_rudderval },
601     { "speed", get_speed },
602     { "throttleval", get_throttleval },
603     { "view_direction", get_view_direction },
604     { "vfc_tris_culled", get_vfc_tris_culled },
605     { "vfc_tris_drawn", get_vfc_tris_drawn },
606 #ifdef ENABLE_SP_FDM
607     { "aux1", get_aux1 },
608     { "aux2", get_aux2 },
609     { "aux3", get_aux3 },
610     { "aux4", get_aux4 },
611     { "aux5", get_aux5 },
612     { "aux6", get_aux6 },
613     { "aux7", get_aux7 },
614     { "aux8", get_aux8 },
615     { "aux9", get_aux9 },
616     { "aux10", get_aux10 },
617     { "aux11", get_aux11 },
618     { "aux12", get_aux12 },
619     { "aux13", get_aux13 },
620     { "aux14", get_aux14 },
621     { "aux15", get_aux15 },
622     { "aux16", get_aux16 },
623     { "aux17", get_aux17 },
624     { "aux18", get_aux18 },
625 #endif
626     { 0, 0 },
627 };
628
629
630 FLTFNPTR get_func(const char *name)
631 {
632     for (int i = 0; fn_table[i].name; i++)
633         if (!strcmp(fn_table[i].name, name))
634             return fn_table[i].func;
635
636     return 0;
637 }
638
639