]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud.hxx
Fix two bugs in the new autopilot code
[flightgear.git] / src / Cockpit / hud.hxx
1 // hud.hxx -- hud defines and prototypes (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 #ifndef _OLDHUD_HXX
25 #define _OLDHUD_HXX
26
27 #ifndef __cplusplus
28 # error This library requires C++
29 #endif
30
31 #include <simgear/compiler.h>
32
33 #ifdef HAVE_CONFIG_H
34 #  include <config.h>
35 #endif
36
37 #ifdef __CYGWIN__
38 #include <ieeefp.h>
39 #endif
40
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include <algorithm>    // for_each()
45 #include <vector>       // STL vector
46 #include <deque>        // STL double ended queue
47 #include <fstream>
48
49 namespace osg {
50     class State;
51 }
52
53 #include <simgear/math/SGMath.hxx>
54 #include <simgear/constants.h>
55
56 #include <Include/fg_typedefs.h>
57 #include <Aircraft/aircraft.hxx>
58 #include <Aircraft/controls.hxx>
59 #include <FDM/flight.hxx>
60 #include <GUI/gui.h>
61 #include <Main/fg_props.hxx>
62 #include <Main/globals.hxx>
63 #include <Main/viewmgr.hxx>
64
65 class FGRunway;
66
67 using std::deque;
68 using std::vector;
69
70 #define float_to_int(v) SGMiscf::roundToInt(v)
71
72 // some of Norman's crazy optimizations. :-)
73
74 #ifndef WIN32
75 typedef struct {
76     int x, y;
77 } POINT;
78
79 typedef struct {
80     int top, bottom, left, right;
81 } RECT;
82 #endif
83
84 // View mode definitions
85
86 enum VIEW_MODES{ HUD_VIEW, PANEL_VIEW, CHASE_VIEW, TOWER_VIEW };
87
88 // Label constants
89 #define HUD_FONT_SMALL     1
90 #define HUD_FONT_LARGE     2
91
92 enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ;
93
94 #define HUDS_AUTOTICKS           0x0001
95 #define HUDS_VERT                0x0002
96 #define HUDS_HORZ                0x0000
97 #define HUDS_TOP                 0x0004
98 #define HUDS_BOTTOM              0x0008
99 #define HUDS_LEFT     HUDS_TOP
100 #define HUDS_RIGHT    HUDS_BOTTOM
101 #define HUDS_BOTH     (HUDS_LEFT | HUDS_RIGHT)
102 #define HUDS_NOTICKS             0x0010
103 #define HUDS_ARITHTIC            0x0020
104 #define HUDS_DECITICS            0x0040
105 #define HUDS_NOTEXT              0x0080
106
107 // in cockpit.cxx
108 extern float get_throttleval ( void );
109 extern float get_aileronval  ( void );
110 extern float get_elevatorval ( void );
111 extern float get_elev_trimval( void );
112 extern float get_rudderval   ( void );
113 extern float get_speed       ( void );
114 extern float get_aoa         ( void );
115 extern float get_nlf         ( void );
116 extern float get_roll        ( void );
117 extern float get_pitch       ( void );
118 extern float get_heading     ( void );
119 extern float get_view_direction( void );
120 extern float get_altitude    ( void );
121 extern float get_agl         ( void );
122 extern float get_sideslip    ( void );
123 extern float get_frame_rate  ( void );
124 extern float get_latitude    ( void );
125 extern float get_lat_min     ( void );
126 extern float get_longitude   ( void );
127 extern float get_long_min    ( void );
128 extern float get_fov         ( void );
129 extern float get_vfc_ratio   ( void );
130 extern float get_vfc_tris_drawn   ( void );
131 extern float get_vfc_tris_culled   ( void );
132 extern float get_climb_rate  ( void );
133 extern float get_mach( void );
134 extern char *coord_format_lat(float);
135 extern char *coord_format_lon(float);
136
137 extern char *get_formated_gmt_time( void );
138
139 enum  hudinstype{ HUDno_instr,
140                   HUDscale,
141                   HUDlabel,
142                   HUDladder,
143                   HUDcirc_ladder,
144                   HUDhorizon,
145                   HUDgauge,
146                   HUDdual_inst,
147                   HUDmoving_scale,
148                   HUDtbi
149 };
150
151 typedef struct gltagRGBTRIPLE { // rgbt
152     GLfloat Blue;
153     GLfloat Green;
154     GLfloat Red;
155 } glRGBTRIPLE;
156
157 class fgLineSeg2D {
158 private:
159     GLfloat x0, y0, x1, y1;
160
161 public:
162     fgLineSeg2D( GLfloat a = 0, GLfloat b =0, GLfloat c = 0, GLfloat d =0 )
163         : x0(a), y0(b),  x1(c), y1(d) {}
164
165     fgLineSeg2D( const fgLineSeg2D & image )
166         : x0(image.x0), y0(image.y0), x1(image.x1), y1(image.y1) {}
167
168     fgLineSeg2D& operator= ( const fgLineSeg2D & image ) { // seems unused
169         x0 = image.x0; y0 = image.y0; x1 = image.x1; y1 = image.y1; return *this;
170     }
171
172     void draw() const
173     {
174         glVertex2f(x0, y0);
175         glVertex2f(x1, y1);
176     }
177 };
178
179 class DrawLineSeg2D {
180     public:
181         void operator() (const fgLineSeg2D& elem) const {
182             elem.draw();
183         }
184 };
185
186
187 #define USE_HUD_TextList
188 extern fntTexFont        *HUD_Font;
189 extern float              HUD_TextSize;
190 extern fntRenderer       *HUDtext;
191 extern float HUD_matrix[16];
192
193 class fgText {
194 private:
195     float x, y;
196     string msg;
197         bool digit;
198     // seems unused   
199         
200 public:
201         fgText(float x, float y, const string& c, bool digits=false): x(x), y(y), msg( c), digit( digits) {};   
202
203     fgText( const fgText & image )
204                 : x(image.x), y(image.y), msg(image.msg), digit(image.digit) { }
205
206         fgText& operator = ( const fgText & image ) {
207                 x = image.x; y = image.y; msg= image.msg; digit = image.digit;
208                 return *this;
209         }
210         
211     static int getStringWidth ( const char *str )
212     {
213         if ( HUDtext && str ) {
214             float r, l ;
215             HUD_Font->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
216             return float_to_int( r - l );
217         }
218         return 0 ;
219     }
220
221     int StringWidth ()
222     {
223         if ( HUDtext && msg != "") {
224             float r, l ;
225             HUD_Font->getBBox ( msg.c_str(), HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
226             return float_to_int( r - l );
227         }
228         return 0 ;
229     }
230
231     // this code is changed to display Numbers with big/small digits
232     // according to MIL Standards for example Altitude above 10000 ft
233     // is shown as 10ooo.
234
235     void Draw(fntRenderer *fnt) {
236         if (digit) {
237             int c=0;
238             
239             int p=4;
240
241             if (msg[0]=='-') {
242                 //if negative value then increase the c and p values
243                 //for '-' sign.  c++;
244                 p++;
245             }
246                         
247                         for (string::size_type i = 0; i < msg.size(); i++) {
248                 if ((msg[i]>='0') && (msg[i]<='9'))
249                     c++;
250             }
251             float orig_size = fnt->getPointSize();
252             if (c>p) {
253                 fnt->setPointSize(HUD_TextSize * 0.8);
254                 int p2=(c-3)*8;  //advance to the last 3 digits
255
256                 fnt->start2f(x+p2,y);
257                 fnt->puts(msg.c_str() + c - 3); // display last 3 digits
258
259                 fnt->setPointSize(HUD_TextSize * 1.2);
260               
261                 fnt->start2f(x,y);
262                                 fnt->puts(msg.substr(0,c-3).c_str());
263             } else {
264                 fnt->setPointSize(HUD_TextSize * 1.2);
265                 fnt->start2f( x, y );
266                 fnt->puts(msg.c_str());
267             }
268             fnt->setPointSize(orig_size);
269         } else {
270             //if digits not true
271             fnt->start2f( x, y );
272             fnt->puts( msg.c_str()) ;
273         }
274     }
275
276     void Draw()
277     {
278                 guiFnt.drawString( msg.c_str(), float_to_int(x), float_to_int(y) );
279     }
280 };
281
282 class fgLineList {
283     vector < fgLineSeg2D > List;
284 public:
285     fgLineList( void ) {}
286     void add( const fgLineSeg2D& seg ) { List.push_back(seg); }
287         void erase( void ) { List.clear();}
288     void draw( void ) {
289         glBegin(GL_LINES);
290         for_each( List.begin(), List.end(), DrawLineSeg2D());
291         glEnd();
292     }
293 };
294
295 class fgTextList {
296     fntRenderer *Font;
297     vector< fgText > List;
298 public:
299     fgTextList ( void ) { Font = 0; }
300
301     void setFont( fntRenderer *Renderer ) { Font = Renderer; }
302     void add( const fgText& String ) { List.push_back(String); }
303     void erase( void ) { List.clear(); }
304     void draw( void );
305 };
306
307
308 inline void Text( fgTextList &List, float x, float y, char *s)
309 {
310     List.add( fgText( x, y, s) );
311 }
312
313 inline void Text( fgTextList &List, const fgText &me)
314 {
315     List.add(me);
316 }
317
318 inline void Line( fgLineList &List, float x1, float y1, float x2, float y2)
319 {
320     List.add(fgLineSeg2D(x1,y1,x2,y2));
321 }
322
323
324 // Declare our externals
325 extern fgTextList         HUD_TextList;
326 extern fgLineList         HUD_LineList;
327 extern fgLineList         HUD_StippleLineList;
328
329
330 class instr_item : public SGReferenced {  // An Abstract Base Class (ABC)
331 private:
332     static UINT        instances;     // More than 64K instruments? Nah!
333     static int         brightness;
334     static glRGBTRIPLE color;
335
336     UINT               handle;
337     RECT               scrn_pos;      // Framing - affects scale dimensions
338                                       // and orientation. Vert vs Horz, etc.
339     FLTFNPTR           load_value_fn;
340     float              disp_factor;   // Multiply by to get numbers shown on scale.
341     UINT               opts;
342     bool               is_enabled;
343     bool               broken;
344     UINT               scr_span;      // Working values for draw;
345     POINT              mid_span;      //
346     int                digits;
347
348 public:
349     instr_item( int            x,
350                 int            y,
351                 UINT           height,
352                 UINT           width,
353                 FLTFNPTR       data_source,
354                 float          data_scaling,
355                 UINT           options,
356                 bool           working = true,
357                 int            digit = 0);
358
359     virtual ~instr_item ();
360
361     void    set_data_source ( FLTFNPTR fn ) { load_value_fn = fn; }
362     int     get_brightness  ( void ) { return brightness;}
363     RECT    get_location    ( void ) { return scrn_pos;  }
364     bool    is_broken       ( void ) { return broken;    }
365     bool    enabled         ( void ) { return is_enabled;}
366     bool    data_available  ( void ) { return !!load_value_fn; }
367     float   get_value       ( void ) { return load_value_fn(); }
368     float   data_scaling    ( void ) { return disp_factor; }
369     UINT    get_span        ( void ) { return scr_span;  }
370     POINT   get_centroid    ( void ) { return mid_span;  }
371     UINT    get_options     ( void ) { return opts;      }
372     int     get_digits      ( void ) { return digits;         }
373     inline int get_x() const { return scrn_pos.left; }
374     inline int get_y() const { return scrn_pos.top; }
375     inline int get_width() const { return scrn_pos.right; }
376     inline int get_height() const { return scrn_pos.bottom; }
377
378     UINT    huds_vert     (UINT options) { return (options & HUDS_VERT); }
379     UINT    huds_left     (UINT options) { return (options & HUDS_LEFT); }
380     UINT    huds_right    (UINT options) { return (options & HUDS_RIGHT); }
381     UINT    huds_both     (UINT options) {
382         return ((options & HUDS_BOTH) == HUDS_BOTH);
383     }
384     UINT    huds_noticks  (UINT options) { return (options & HUDS_NOTICKS); }
385     UINT    huds_notext   (UINT options) { return (options & HUDS_NOTEXT); }
386     UINT    huds_top      (UINT options) { return (options & HUDS_TOP); }
387     UINT    huds_bottom   (UINT options) { return (options & HUDS_BOTTOM); }
388
389     virtual void display_enable( bool working ) { is_enabled = working;}
390
391     virtual void break_display ( bool bad );
392     virtual void SetBrightness( int illumination_level ); // fgHUDSetBright...
393     void         SetPosition  ( int x, int y, UINT width, UINT height );
394     UINT         get_Handle( void );
395     virtual void draw( void ) = 0;   // Required method in derived classes
396
397     void drawOneLine( float x1, float y1, float x2, float y2)
398     {
399         HUD_LineList.add(fgLineSeg2D(x1,y1,x2,y2));
400     }
401     void drawOneStippleLine( float x1, float y1, float x2, float y2)
402     {
403         HUD_StippleLineList.add(fgLineSeg2D(x1,y1,x2,y2));
404     }
405     void TextString( char *msg, float x, float y, bool digit )
406     {
407         HUD_TextList.add(fgText(x, y, msg,digit));
408     }
409     int getStringWidth ( char *str )
410     {
411         if ( HUDtext && str ) {
412             float r, l ;
413             HUD_Font->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
414             return float_to_int( r - l );
415         }
416         return 0 ;
417     }
418
419
420
421 };
422
423 typedef instr_item *HIptr;
424
425 class HUDdraw {
426     public:
427         void operator() (HIptr elem) const {
428             if ( elem->enabled())
429                 elem->draw();
430         }
431 };
432
433
434 extern int HUD_style;
435
436 // instr_item           This class has no other purpose than to maintain
437 //                      a linked list of instrument and derived class
438 // object pointers.
439
440
441 class instr_label : public instr_item {
442 private:
443     const char  *pformat;
444     
445     fgLabelJust justify;
446     int         fontSize;
447     int         blink;
448     string      format_buffer;
449     bool        lat;
450     bool        lon;
451     bool        lbox;
452     SGPropertyNode_ptr lon_node;
453     SGPropertyNode_ptr lat_node;
454
455 public:
456     instr_label(const SGPropertyNode *);
457     virtual void draw(void);
458 };
459
460
461 //
462 // fgRunway_instr   This class is responsible for rendering the active runway
463 //                  in the hud (if visible).
464 class runway_instr : public instr_item {
465 private:
466         void boundPoint(const sgdVec3& v, sgdVec3& m);
467         bool boundOutsidePoints(sgdVec3& v, sgdVec3& m);
468         bool drawLine(const sgdVec3& a1, const sgdVec3& a2,
469                 const sgdVec3& p1, const sgdVec3& p2);
470         void drawArrow();
471         FGRunway* get_active_runway();
472         void get_rwy_points(sgdVec3 *points);
473         void setLineWidth(void);
474
475         sgdVec3 points3d[6], points2d[6];
476         double mm[16],pm[16], arrowScale, arrowRad, lnScale;
477         double scaleDist, default_pitch, default_heading;
478         GLint view[4];
479         FGRunway* runway;
480         FGViewer* cockpit_view;
481         unsigned short stippleOut, stippleCen;
482         bool drawIA, drawIAAlways;
483         RECT location;
484         POINT center;
485
486 public:
487     runway_instr(const SGPropertyNode *);
488
489     virtual void draw( void );
490     void setArrowRotationRadius(double radius);
491     // Scales the runway indication arrow
492     void setArrowScale(double scale);
493     // Draws arrow when runway is not visible in HUD if draw=true
494     void setDrawArrow(bool draw);
495     // Always draws arrow if draw=true;
496     void setDrawArrowAlways(bool draw);
497     // Sets the maximum line scale
498     void setLineScale(double scale);
499     // Sets the distance where to start scaling the lines
500     void setScaleDist(double dist_nm);
501     // Sets the stipple pattern of the outline of the runway
502     void setStippleOutline(unsigned short stipple);
503     // Sets the stipple patter of the center line of the runway
504     void setStippleCenterline(unsigned short stipple);
505 };
506
507
508 //
509 // instr_scale           This class is an abstract base class for both moving
510 //                       scale and moving needle (fixed scale) indicators. It
511 // does not draw itself, but is not instanciable.
512 //
513
514 class instr_scale : public instr_item {
515 private:
516     float range_shown;   // Width Units.
517     float Maximum_value; //                ceiling.
518     float Minimum_value; // Representation floor.
519     float scale_factor;  // factor => screen units/range values.
520     UINT   Maj_div;       // major division marker units
521     UINT   Min_div;       // minor division marker units
522     UINT   Modulo;        // Roll over point
523     int    signif_digits; // digits to show to the right.
524
525 public:
526     instr_scale( int          x,
527                  int          y,
528                  UINT         width,
529                  UINT         height,
530                  FLTFNPTR     load_fn,
531                  UINT         options,
532                  float        show_range,
533                  float        max_value,
534                  float        min_value,
535                  float        disp_scaling,
536                  UINT         major_divs,
537                  UINT         minor_divs,
538                  UINT         rollover,
539                  int          dp_showing,
540                  bool         working = true);
541
542     virtual void draw    ( void ) {}; // No-op here. Defined in derived classes.
543     UINT   div_min       ( void ) { return Min_div;}
544     UINT   div_max       ( void ) { return Maj_div;}
545     float  min_val       ( void ) { return Minimum_value;}
546     float  max_val       ( void ) { return Maximum_value;}
547     UINT   modulo        ( void ) { return Modulo; }
548     float  factor        ( void ) { return scale_factor;}
549     float  range_to_show ( void ) { return range_shown;}
550 };
551
552 // hud_card                This class displays the indicated quantity on
553 //                         a scale that moves past the pointer. It may be
554 // horizontal or vertical, read above(left) or below(right) of the base
555 // line.
556
557 class hud_card : public instr_scale {
558 private:
559     float  val_span;
560     string type;
561     float  half_width_units;
562     bool   draw_tick_bottom;
563     bool   draw_tick_top;
564     bool   draw_tick_right;
565     bool   draw_tick_left;
566     bool   draw_cap_bottom;
567     bool   draw_cap_top;
568     bool   draw_cap_right;
569     bool   draw_cap_left;
570     float  marker_offset;
571     bool   pointer;
572     string pointer_type;
573     string tick_type;
574     string tick_length;
575     float  radius;
576     float  maxValue;
577     float  minValue;
578     int    divisions;
579     int    zoom;
580     UINT   Maj_div;
581     UINT   Min_div;
582
583 public:
584     hud_card(const SGPropertyNode *);
585     //    virtual void display_enable( bool setting );                  // FIXME
586     virtual void draw(void);
587     void circles(float, float, float);
588     void fixed(float, float, float, float, float, float);
589     void zoomed_scale(int, int);
590 };
591
592
593 class gauge_instr : public instr_scale {
594 public:
595     gauge_instr(const SGPropertyNode *);
596     virtual void draw( void );       // Required method in base class
597 };
598
599
600 //
601 // dual_instr_item         This class was created to form the base class
602 //                         for both panel and HUD Turn Bank Indicators.
603
604 class dual_instr_item : public instr_item {
605 private:
606     FLTFNPTR alt_data_source;
607
608 public:
609     dual_instr_item ( int       x,
610                       int       y,
611                       UINT      width,
612                       UINT      height,
613                       FLTFNPTR  chn1_source,
614                       FLTFNPTR  chn2_source,
615                       bool      working,
616                       UINT      options );
617
618     float current_ch1( void ) { return (float)alt_data_source(); }
619     float current_ch2( void ) { return (float)get_value(); }
620     virtual void draw( void ) {}
621 };
622
623
624 class fgTBI_instr : public dual_instr_item {
625 private:
626     UINT BankLimit;
627     UINT SlewLimit;
628     UINT scr_hole;
629     bool tsi;
630     float rad;
631
632 public:
633     fgTBI_instr(const SGPropertyNode *);
634
635     UINT bank_limit(void) { return BankLimit; }
636     UINT slew_limit(void) { return SlewLimit; }
637
638     virtual void draw(void);
639 };
640
641
642 class HudLadder : public dual_instr_item {
643 private:
644     UINT   width_units;
645     int    div_units;
646     UINT   minor_div;
647     UINT   label_pos;
648     UINT   scr_hole;
649     float  vmax;
650     float  vmin;
651     float  factor;
652     string hudladder_type;
653     bool   frl;
654     bool   target_spot;
655     bool   velocity_vector;
656     bool   drift_marker;
657     bool   alpha_bracket;
658     bool   energy_marker;
659     bool   climb_dive_marker;
660     bool   glide_slope_marker;
661     float  glide_slope;
662     bool   energy_worm;
663     bool   waypoint_marker;
664     int    zenith;
665     int    nadir;
666     int    hat;
667
668     // The Ladder has it's own temporary display lists
669     fgTextList         TextList;
670     fgLineList         LineList;
671     fgLineList         StippleLineList;
672
673 public:
674     HudLadder(const SGPropertyNode *);
675
676     virtual void draw(void);
677     void drawZenith(float, float, float);
678     void drawNadir(float, float, float);
679
680     void Text(float x, float y, char *s)
681     {
682         TextList.add(fgText(x, y, s));
683     }
684
685     void Line(float x1, float y1, float x2, float y2)
686     {
687         LineList.add(fgLineSeg2D(x1, y1, x2, y2));
688     }
689
690     void StippleLine(float x1, float y1, float x2, float y2)
691     {
692         StippleLineList.add(fgLineSeg2D(x1, y1, x2, y2));
693     }
694 };
695
696
697 extern int  fgHUDInit( fgAIRCRAFT * /* current_aircraft */ );
698 extern int  fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ );
699 extern void fgUpdateHUD( osg::State* );
700 extern void fgUpdateHUD( osg::State*, GLfloat x_start, GLfloat y_start,
701                          GLfloat x_end, GLfloat y_end );
702
703
704
705
706 class HUD_Properties : public SGPropertyChangeListener {
707 public:
708     HUD_Properties();
709     void valueChanged(SGPropertyNode *n);
710     void setColor() const;
711     bool isVisible() const { return _visible; }
712     bool isAntialiased() const { return _antialiased; }
713     bool isTransparent() const { return _transparent; }
714     float alphaClamp() const { return _cl; }
715
716 private:
717     float clamp(float f) { return f < 0.0f ? 0.0f : f > 1.0f ? 1.0f : f; }
718     SGPropertyNode_ptr _current;
719     SGPropertyNode_ptr _visibility;
720     SGPropertyNode_ptr _antialiasing;
721     SGPropertyNode_ptr _transparency;
722     SGPropertyNode_ptr _red, _green, _blue, _alpha;
723     SGPropertyNode_ptr _alpha_clamp;
724     SGPropertyNode_ptr _brightness;
725     bool _visible;
726     bool _antialiased;
727     bool _transparent;
728     float _r, _g, _b, _a, _cl;
729 };
730
731 #endif // _OLDHUD_H