]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/cockpit.cxx
Added support for parsing socket options.
[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 <XGL/xgl.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38
39 #include <Aircraft/aircraft.hxx>
40 #include <Debug/logstream.hxx>
41 #include <Include/fg_constants.h>
42 #include <Include/general.hxx>
43 #include <Main/options.hxx>
44 #include <Main/views.hxx>
45 #include <Math/fg_random.h>
46 #include <Math/mat3.h>
47 #include <Math/polar3d.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/%2d %d:%02d:%02d", 
113          p->tm_mon+1, p->tm_mday, 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_equiv_kts()
165         * current_options.get_speed_up();
166     return( speed );
167 }
168
169 float get_aoa( void )
170 {
171     float aoa = current_aircraft.fdm_state->get_Alpha() * RAD_TO_DEG;
172     return( aoa );
173 }
174
175 float get_roll( void )
176 {
177     float roll = current_aircraft.fdm_state->get_Phi();
178     return( roll );
179 }
180
181 float get_pitch( void )
182 {
183     float pitch = current_aircraft.fdm_state->get_Theta();
184     return( pitch );
185 }
186
187 float get_heading( void )
188 {
189     float heading = (current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG);
190     return( heading );
191 }
192
193 float get_altitude( void )
194 {
195 //  FGState *f;
196     // double rough_elev;
197
198 //  current_aircraft.fdm_state
199     // rough_elev = mesh_altitude(f->get_Longitude() * RAD_TO_ARCSEC,
200     //                         f->get_Latitude()  * RAD_TO_ARCSEC);
201     float altitude;
202
203     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
204         altitude = current_aircraft.fdm_state->get_Altitude();
205     } else {
206         altitude = (current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER);
207     }
208     return altitude;
209 }
210
211 float get_agl( void )
212 {
213     float agl;
214
215     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
216         agl = (current_aircraft.fdm_state->get_Altitude()
217                - scenery.cur_elev * METER_TO_FEET);
218     } else {
219         agl = (current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
220                - scenery.cur_elev);
221     }
222     return agl;
223 }
224
225 float get_sideslip( void )
226 {
227     float sideslip = current_aircraft.fdm_state->get_Beta();
228     return( sideslip );
229 }
230
231 float get_frame_rate( void )
232 {
233     float frame_rate = general.get_frame_rate();
234     return (frame_rate); 
235 }
236
237 float get_fov( void )
238 {
239     float fov = current_options.get_fov(); 
240     return (fov);
241 }
242
243 float get_vfc_ratio( void )
244 {
245     float vfc = current_view.get_vfc_ratio();
246     return (vfc);
247 }
248
249 float get_vfc_tris_drawn   ( void )
250 {
251     float rendered = current_view.get_tris_rendered();
252     return (rendered);
253 }
254
255 float get_vfc_tris_culled   ( void )
256 {
257     float culled = current_view.get_tris_culled();
258     return (culled);
259 }
260
261 float get_climb_rate( void )
262 {
263     float climb_rate;
264     if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
265         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
266     } else {
267         climb_rate = current_aircraft.fdm_state->get_Climb_Rate() * FEET_TO_METER * 60.0;
268     }
269     return (climb_rate);
270 }
271
272
273 float get_view_direction( void )
274 {
275     double view;
276  
277     view = FG_2PI - current_view.get_view_offset();
278     view = ( current_aircraft.fdm_state->get_Psi() + view) * RAD_TO_DEG;
279     
280     if(view > 360.)
281         view -= 360.;
282     else if(view<0.)
283         view += 360.;
284     
285     float fview = view;
286     return( fview );
287 }
288
289 #ifdef NOT_USED
290 /****************************************************************************/
291 /* Convert degrees to dd mm'ss.s" (DMS-Format)                              */
292 /****************************************************************************/
293 char *dmshh_format(double degrees)
294 {
295     static char buf[16];    
296     int deg_part;
297     int min_part;
298     double sec_part;
299     
300     if (degrees < 0)
301       degrees = -degrees;
302
303     deg_part = degrees;
304     min_part = 60.0 * (degrees - deg_part);
305     sec_part = 3600.0 * (degrees - deg_part - min_part / 60.0);
306
307     /* Round off hundredths */
308     if (sec_part + 0.005 >= 60.0)
309       sec_part -= 60.0, min_part += 1;
310     if (min_part >= 60)
311       min_part -= 60, deg_part += 1;
312
313     sprintf(buf,"%02d*%02d %05.2f",deg_part,min_part,sec_part);
314
315     return buf;
316 }
317 #endif // 0
318
319 /****************************************************************************/
320 /* Convert degrees to dd mm'ss.s'' (DMS-Format)                              */
321 /****************************************************************************/
322 static char *toDMS(float a)
323 {
324   int        neg = 0;
325   float       d, m, s;
326   static char  dms[16];
327
328   if (a < 0.0f) {
329     a   = -a;
330     neg = 1;
331   }
332   d = (float) ((int) a); 
333   a = (a - d) * 60.0f;
334   m = (float) ((int) a);
335   s = (a - m) * 60.0f;
336   
337   if (s > 59.5f) {
338     s  = 0.0f;
339     m += 1.0f;
340   }
341   if (m > 59.5f) {
342     m  = 0.0f;
343     d += 1.0f;
344   }
345   if (neg)
346     d = -d;
347   
348   sprintf(dms, "%.0f*%02.0f %04.1f", d, m, s);
349   return dms;
350 }
351
352
353 /****************************************************************************/
354 /* Convert degrees to dd mm.mmm' (DMM-Format)                               */
355 /****************************************************************************/
356 static char *toDM(float a)
357 {
358   int        neg = 0;
359   float       d, m;
360   static char  dm[16];
361   
362   if (a < 0.0f) {
363     a = -a;
364     neg = 1;
365   }
366
367   d = (float) ( (int) a);
368   m = (a - d) * 60.0f;
369   
370   if (m > 59.5f) {
371     m  = 0.0f;
372     d += 1.0f;
373   }
374   if (neg) d = -d;
375   
376   sprintf(dm, "%.0f*%06.3f", d, m);
377   return dm;
378 }
379
380 // Have to set the LatLon display type
381 //static char *(*fgLatLonFormat)(float) = toDM;
382 static char *(*fgLatLonFormat)(float);
383
384 char *coord_format_lat(float latitude)
385 {
386     static char buf[16];
387
388     sprintf(buf,"%s%c",
389 //      dmshh_format(latitude),
390 //      toDMS(latitude),
391 //      toDM(latitude),
392         fgLatLonFormat(latitude),           
393         latitude > 0 ? 'N' : 'S');
394     return buf;
395 }
396
397 char *coord_format_lon(float longitude)
398 {
399     static char buf[80];
400
401     sprintf(buf,"%s%c",
402 //      dmshh_format(longitude),
403 //      toDMS(longitude),
404 //      toDM(longitude),
405         fgLatLonFormat(longitude),
406         longitude > 0 ? 'E' : 'W');
407     return buf;
408 }
409
410 void fgLatLonFormatToggle( puObject *)
411 {
412     static int toggle = 0;
413
414     if ( toggle ) 
415         fgLatLonFormat = toDM;
416     else
417         fgLatLonFormat = toDMS;
418     
419     toggle = ~toggle;
420 }
421
422 #ifdef NOT_USED
423 char *coord_format_latlon(double latitude, double longitude)
424 {
425     static char buf[1024];
426
427     sprintf(buf,"%s%c %s%c",
428         dmshh_format(latitude),
429         latitude > 0 ? 'N' : 'S',
430         dmshh_format(longitude),
431         longitude > 0 ? 'E' : 'W');
432     return buf;
433 }
434 #endif
435
436
437 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
438 {
439     FG_LOG( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem" );
440
441     //  cockpit->code = 1;  /* It will be aircraft dependent */
442     //  cockpit->status = 0;
443
444     // If aircraft has HUD specified we will get the specs from its def
445     // file. For now we will depend upon hard coding in hud?
446     
447     // We must insure that the existing instrument link is purged.
448     // This is done by deleting the links in the list.
449     
450     // HI_Head is now a null pointer so we can generate a new list from the
451     // current aircraft.
452
453     fgHUDInit( cur_aircraft );
454     ac_cockpit = new fg_Cockpit();
455     
456     if ( current_options.get_panel_status() ) {
457         new FGPanel;
458     }
459
460     // Have to set the LatLon display type
461     fgLatLonFormat = toDM;
462     
463     FG_LOG( FG_COCKPIT, FG_INFO,
464         "  Code " << ac_cockpit->code() << " Status " 
465         << ac_cockpit->status() );
466
467 //  HUD_TextSize = (current_options.get_xsize() > 1000) ? 10 : 8;
468     HUD_TextSize = 10;
469     HUDtext = new fntRenderer();
470     HUDtext -> setFont      ( guiFntHandle ) ;
471     HUDtext -> setPointSize ( HUD_TextSize ) ;
472     HUD_TextList.setFont( HUDtext );
473
474     return true;
475 }
476
477
478 void fgCockpitUpdate( void ) {
479
480     int iwidth   = current_view.get_winWidth();
481     int iheight  = current_view.get_winHeight();
482     float width  = iwidth;
483     float height = iheight;
484     
485     FG_LOG( FG_COCKPIT, FG_DEBUG,
486         "Cockpit: code " << ac_cockpit->code() << " status " 
487         << ac_cockpit->status() );
488
489     if ( current_options.get_hud_status() ) {
490         // This will check the global hud linked list pointer.
491         // If these is anything to draw it will.
492         fgUpdateHUD();
493     }
494 #define DISPLAY_COUNTER
495 #ifdef DISPLAY_COUNTER
496     else
497     {
498         char buf[64];
499         float fps    =       get_frame_rate();
500 //      float tris   = fps * get_vfc_tris_drawn();
501 //      float culled = fps * get_vfc_tris_culled();
502 //      sprintf(buf,"%-4.1f  %7.0f  %7.0f", fps, tris, culled);
503         sprintf(buf,"%-5.1f", fps);
504
505         glMatrixMode(GL_PROJECTION);
506         glPushMatrix();
507         glLoadIdentity();
508         gluOrtho2D(0, width, 0, height);
509         glMatrixMode(GL_MODELVIEW);
510         glPushMatrix();
511         glLoadIdentity();
512
513         glDisable(GL_DEPTH_TEST);
514         glDisable(GL_LIGHTING);
515         
516         glColor3f (0.9, 0.4, 0.2);
517
518         guiFnt.drawString( buf,
519                            width/2 - guiFnt.getStringWidth(buf)/2,
520                            10 );
521         glEnable(GL_DEPTH_TEST);
522         glEnable(GL_LIGHTING);
523         glMatrixMode(GL_PROJECTION);
524         glPopMatrix();
525         glMatrixMode(GL_MODELVIEW);
526         glPopMatrix();
527     }
528 #endif // #ifdef DISPLAY_COUNTER
529     
530     if( current_options.get_panel_status() && 
531          (fabs( current_view.get_view_offset() ) < 0.2) )
532     {
533         xglViewport( 0, 0, iwidth, iheight );
534
535         FGPanel::OurPanel->Update();
536     }
537 }