]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/cockpit.cxx
Updates to vacuum system model from Alex Perry.
[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/fg_random.h>
42 #include <simgear/math/polar3d.hxx>
43
44 #include <Aircraft/aircraft.hxx>
45 #include <Include/general.hxx>
46 #include <Main/options.hxx>
47 #include <Main/views.hxx>
48 #include <Scenery/scenery.hxx>
49 #include <Time/fg_timer.hxx>
50 #include <Time/fg_time.hxx>
51 #include <GUI/gui.h>
52
53 #include "cockpit.hxx"
54
55
56 // This is a structure that contains all data related to
57 // cockpit/panel/hud system
58
59 static pCockpit ac_cockpit;
60 fntRenderer *HUDtext = 0;
61 float  HUD_TextSize = 0;
62 int HUD_style = 0;
63
64 float HUD_matrix[16];
65 // The following routines obtain information concerntin the aircraft's
66 // current state and return it to calling instrument display routines.
67 // They should eventually be member functions of the aircraft.
68 //
69
70 float get_latitude( void )
71 {
72     double lat;
73
74     lat = current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
75
76     float flat = lat;
77     return(flat);
78
79 }
80
81 float get_lat_min( void )
82 {
83     double      a, d;
84
85     a = current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;    
86     if (a < 0.0) {
87         a = -a;
88     }
89     d = (double) ( (int) a);
90     float lat_min = (a - d) * 60.0;
91     return(lat_min );
92 }
93
94
95 float get_longitude( void )
96 {
97     double lon;
98
99     lon = current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
100
101     float flon = lon;
102     return(flon);
103 }
104
105
106 char*
107 get_formated_gmt_time( void )
108 {
109     static char buf[32];
110     FGTime *t = FGTime::cur_time_params;
111     const struct tm *p = t->getGmt();
112     sprintf( buf, "%d/%d/%4d %d:%02d:%02d", 
113          p->tm_mon+1, p->tm_mday, 1900 + p->tm_year,
114          p->tm_hour, p->tm_min, p->tm_sec);
115     return buf;
116 }
117
118
119 float get_long_min( void )
120 {
121     double  a, d;
122     a = current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;   
123     if (a < 0.0) {
124         a = -a;
125     }
126     d = (double) ( (int) a);
127     float lon_min = (a - d) * 60.0; 
128     return(lon_min);
129 }
130
131 float get_throttleval( void )
132 {
133     float throttle = controls.get_throttle( 0 );
134     return (throttle);     // Hack limiting to one engine
135 }
136
137 float get_aileronval( void )
138 {
139     float aileronval = controls.get_aileron();
140     return (aileronval);
141 }
142
143 float get_elevatorval( void )
144 {
145     float elevator_val = (float)controls.get_elevator();
146     return elevator_val;
147 }
148
149 float get_elev_trimval( void )
150 {
151     float elevatorval = controls.get_elevator_trim();
152     return (elevatorval);
153 }
154
155 float get_rudderval( void )
156 {
157     float rudderval = controls.get_rudder();
158     return (rudderval);
159 }
160
161 float get_speed( void )
162 {
163     // Make an explicit function call.
164     float speed = current_aircraft.fdm_state->get_V_calibrated_kts()
165         * current_options.get_speed_up();
166     return( speed );
167 }
168
169 float get_mach(void)
170 {
171         float mach=current_aircraft.fdm_state->get_Mach_number();
172         return mach;
173 }       
174
175 float get_aoa( void )
176 {
177     float aoa = current_aircraft.fdm_state->get_Alpha() * RAD_TO_DEG;
178     return( aoa );
179 }
180
181 float get_roll( void )
182 {
183     float roll = current_aircraft.fdm_state->get_Phi();
184     return( roll );
185 }
186
187 float get_pitch( void )
188 {
189     float pitch = current_aircraft.fdm_state->get_Theta();
190     return( pitch );
191 }
192
193 float get_heading( void )
194 {
195     float heading = (current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG);
196     return( heading );
197 }
198
199 float get_altitude( void )
200 {
201 //  FGState *f;
202     // double rough_elev;
203
204 //  current_aircraft.fdm_state
205     // rough_elev = mesh_altitude(f->get_Longitude() * RAD_TO_ARCSEC,
206     //                         f->get_Latitude()  * RAD_TO_ARCSEC);
207     float altitude;
208
209     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
210         altitude = current_aircraft.fdm_state->get_Altitude();
211     } else {
212         altitude = (current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
213     }
214     return altitude;
215 }
216
217 float get_agl( void )
218 {
219     float agl;
220
221     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
222         agl = (current_aircraft.fdm_state->get_Altitude()
223                - scenery.cur_elev * METER_TO_FEET);
224     } else {
225         agl = (current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
226                - scenery.cur_elev);
227     }
228     return agl;
229 }
230
231 float get_sideslip( void )
232 {
233     float sideslip = current_aircraft.fdm_state->get_Beta();
234     return( sideslip );
235 }
236
237 float get_frame_rate( void )
238 {
239     float frame_rate = general.get_frame_rate();
240     return (frame_rate); 
241 }
242
243 float get_fov( void )
244 {
245     float fov = current_options.get_fov(); 
246     return (fov);
247 }
248
249 float get_vfc_ratio( void )
250 {
251     float vfc = current_view.get_vfc_ratio();
252     return (vfc);
253 }
254
255 float get_vfc_tris_drawn   ( void )
256 {
257     float rendered = current_view.get_tris_rendered();
258     return (rendered);
259 }
260
261 float get_vfc_tris_culled   ( void )
262 {
263     float culled = current_view.get_tris_culled();
264     return (culled);
265 }
266
267 float get_climb_rate( void )
268 {
269     float climb_rate;
270     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
271         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
272     } else {
273         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * FEET_TO_METER * 60.0;
274     }
275     return (climb_rate);
276 }
277
278
279 float get_view_direction( void )
280 {
281     double view;
282  
283     view = FG_2PI - current_view.get_view_offset();
284     view = ( current_aircraft.fdm_state->get_Psi() + view) * RAD_TO_DEG;
285     
286     if(view > 360.)
287         view -= 360.;
288     else if(view<0.)
289         view += 360.;
290     
291     float fview = view;
292     return( fview );
293 }
294
295 #ifdef NOT_USED
296 /****************************************************************************/
297 /* Convert degrees to dd mm'ss.s" (DMS-Format)                              */
298 /****************************************************************************/
299 char *dmshh_format(double degrees)
300 {
301     static char buf[16];    
302     int deg_part;
303     int min_part;
304     double sec_part;
305     
306     if (degrees < 0)
307       degrees = -degrees;
308
309     deg_part = degrees;
310     min_part = 60.0 * (degrees - deg_part);
311     sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
312
313     /* Round off hundredths */
314     if (sec_part + 0.005 >= 60.0)
315       sec_part -= 60.0, min_part += 1;
316     if (min_part >= 60)
317       min_part -= 60, deg_part += 1;
318
319     sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
320
321     return buf;
322 }
323 #endif // 0
324
325 /****************************************************************************/
326 /* Convert degrees to dd mm'ss.s'' (DMS-Format)                              */
327 /****************************************************************************/
328 static char *toDMS(float a)
329 {
330   int        neg = 0;
331   float       d, m, s;
332   static char  dms[16];
333
334   if (a < 0.0f) {
335     a   = -a;
336     neg = 1;
337   }
338   d = (float) ((int) a); 
339   a = (a - d) * 60.0f;
340   m = (float) ((int) a);
341   s = (a - m) * 60.0f;
342   
343   if (s > 59.5f) {
344     s  = 0.0f;
345     m += 1.0f;
346   }
347   if (m > 59.5f) {
348     m  = 0.0f;
349     d += 1.0f;
350   }
351   if (neg)
352     d = -d;
353   
354   sprintf(dms, "%.0f*%02.0f %04.1f", d, m, s);
355   return dms;
356 }
357
358
359 /****************************************************************************/
360 /* Convert degrees to dd mm.mmm' (DMM-Format)                               */
361 /****************************************************************************/
362 static char *toDM(float a)
363 {
364   int        neg = 0;
365   float       d, m;
366   static char  dm[16];
367   
368   if (a < 0.0f) {
369     a = -a;
370     neg = 1;
371   }
372
373   d = (float) ( (int) a);
374   m = (a - d) * 60.0f;
375   
376   if (m > 59.5f) {
377     m  = 0.0f;
378     d += 1.0f;
379   }
380   if (neg) d = -d;
381   
382   sprintf(dm, "%.0f*%06.3f", d, m);
383   return dm;
384 }
385
386 // Have to set the LatLon display type
387 //static char *(*fgLatLonFormat)(float) = toDM;
388 static char *(*fgLatLonFormat)(float);
389
390 char *coord_format_lat(float latitude)
391 {
392     static char buf[16];
393
394     sprintf(buf,"%s%c",
395 //      dmshh_format(latitude),
396 //      toDMS(latitude),
397 //      toDM(latitude),
398         fgLatLonFormat(latitude),           
399         latitude > 0 ? 'N' : 'S');
400     return buf;
401 }
402
403 char *coord_format_lon(float longitude)
404 {
405     static char buf[80];
406
407     sprintf(buf,"%s%c",
408 //      dmshh_format(longitude),
409 //      toDMS(longitude),
410 //      toDM(longitude),
411         fgLatLonFormat(longitude),
412         longitude > 0 ? 'E' : 'W');
413     return buf;
414 }
415
416 void fgLatLonFormatToggle( puObject *)
417 {
418     static int toggle = 0;
419
420     if ( toggle ) 
421         fgLatLonFormat = toDM;
422     else
423         fgLatLonFormat = toDMS;
424     
425     toggle = ~toggle;
426 }
427
428 #ifdef NOT_USED
429 char *coord_format_latlon(double latitude, double longitude)
430 {
431     static char buf[1024];
432
433     sprintf(buf,"%s%c %s%c",
434         dmshh_format(latitude),
435         latitude > 0 ? 'N' : 'S',
436         dmshh_format(longitude),
437         longitude > 0 ? 'E' : 'W');
438     return buf;
439 }
440 #endif
441
442
443 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
444 {
445     FG_LOG( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem" );
446
447     //  cockpit->code = 1;  /* It will be aircraft dependent */
448     //  cockpit->status = 0;
449
450     // If aircraft has HUD specified we will get the specs from its def
451     // file. For now we will depend upon hard coding in hud?
452     
453     // We must insure that the existing instrument link is purged.
454     // This is done by deleting the links in the list.
455     
456     // HI_Head is now a null pointer so we can generate a new list from the
457     // current aircraft.
458
459     fgHUDInit( cur_aircraft );
460     ac_cockpit = new fg_Cockpit();
461     
462     if ( current_options.get_panel_status() ) {
463         new FGPanel;
464     }
465
466     // Have to set the LatLon display type
467     fgLatLonFormat = toDM;
468     
469     FG_LOG( FG_COCKPIT, FG_INFO,
470         "  Code " << ac_cockpit->code() << " Status " 
471         << ac_cockpit->status() );
472
473 //  HUD_TextSize = (current_options.get_xsize() > 1000) ? 10 : 8;
474     HUD_TextSize = 10;
475     HUDtext = new fntRenderer();
476     HUDtext -> setFont      ( guiFntHandle ) ;
477     HUDtext -> setPointSize ( HUD_TextSize ) ;
478     HUD_TextList.setFont( HUDtext );
479
480     return true;
481 }
482
483
484 void fgCockpitUpdate( void ) {
485
486     int iwidth   = current_view.get_winWidth();
487     int iheight  = current_view.get_winHeight();
488     float width  = iwidth;
489     float height = iheight;
490     
491     FG_LOG( FG_COCKPIT, FG_DEBUG,
492         "Cockpit: code " << ac_cockpit->code() << " status " 
493         << ac_cockpit->status() );
494
495     if ( current_options.get_hud_status() ) {
496         // This will check the global hud linked list pointer.
497         // If these is anything to draw it will.
498         fgUpdateHUD();
499     }
500 #define DISPLAY_COUNTER
501 #ifdef DISPLAY_COUNTER
502     else
503     {
504         char buf[64];
505         float fps    =       get_frame_rate();
506 //      float tris   = fps * get_vfc_tris_drawn();
507 //      float culled = fps * get_vfc_tris_culled();
508 //      sprintf(buf,"%-4.1f  %7.0f  %7.0f", fps, tris, culled);
509         sprintf(buf,"%-5.1f", fps);
510
511         glMatrixMode(GL_PROJECTION);
512         glPushMatrix();
513         glLoadIdentity();
514         gluOrtho2D(0, width, 0, height);
515         glMatrixMode(GL_MODELVIEW);
516         glPushMatrix();
517         glLoadIdentity();
518
519         glDisable(GL_DEPTH_TEST);
520         glDisable(GL_LIGHTING);
521         
522         glColor3f (0.9, 0.4, 0.2);
523
524         guiFnt.drawString( buf,
525                            width/2 - guiFnt.getStringWidth(buf)/2,
526                            10 );
527         glEnable(GL_DEPTH_TEST);
528         glEnable(GL_LIGHTING);
529         glMatrixMode(GL_PROJECTION);
530         glPopMatrix();
531         glMatrixMode(GL_MODELVIEW);
532         glPopMatrix();
533     }
534 #endif // #ifdef DISPLAY_COUNTER
535     
536     if( current_options.get_panel_status() && 
537          (fabs( current_view.get_view_offset() ) < 0.2) )
538     {
539         xglViewport( 0, 0, iwidth, iheight );
540
541         FGPanel::OurPanel->Update();
542     }
543 }