]> git.mxchange.org Git - flightgear.git/blob - Cockpit/hud_ladr.cxx
534374691baa16d06a360c2c721b67c4cd7f5ae0
[flightgear.git] / Cockpit / hud_ladr.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include <config.h>
3 #endif
4
5 #ifdef HAVE_WINDOWS_H
6 #  include <windows.h>
7 #endif
8 #include <stdlib.h>
9 #include <string.h>
10 #include <Aircraft/aircraft.h>
11 #include <Debug/fg_debug.h>
12 #include <Include/fg_constants.h>
13 #include <Math/fg_random.h>
14 #include <Math/mat3.h>
15 #include <Math/polar3d.hxx>
16 #include <Scenery/scenery.hxx>
17 #include <Time/fg_timer.hxx>
18 #include <Weather/weather.h>
19
20
21 #include "hud.hxx"
22 //====================== Top of HudLadder Class =======================
23 HudLadder ::
24   HudLadder(  int       x,
25               int       y,
26               UINT      width,
27               UINT      height,
28               DBLFNPTR  ptch_source,
29               DBLFNPTR  roll_source,
30               double    span_units,
31               double    major_div,
32               double    minor_div,
33               UINT      screen_hole,
34               UINT      lbl_pos,
35               bool      working) :
36                dual_instr_item( x, y, width, height,
37                                 ptch_source,
38                                 roll_source,
39                                 working,
40                                 HUDS_RIGHT),
41                width_units    ( span_units   ),
42                div_units      ( major_div < 0? -major_div: major_div ),
43                minor_div      ( minor_div    ),
44                label_pos      ( lbl_pos      ),
45                scr_hole       ( screen_hole  ),
46                vmax           ( span_units/2 ),
47                vmin           ( -vmax        )
48 {
49   if( !width_units ) {
50     width_units = 45;
51     }
52   factor = (double)get_span() / (double) width_units;
53 }
54
55 HudLadder ::
56   ~HudLadder()
57 {
58 }
59
60 HudLadder ::
61   HudLadder( const HudLadder & image ) :
62         dual_instr_item( (dual_instr_item &) image),
63         width_units    ( image.width_units   ),
64         div_units      ( image.div_units     ),
65         label_pos      ( image.label_pos     ),
66         scr_hole       ( image.scr_hole      ),
67         vmax           ( image.vmax ),
68         vmin           ( image.vmin ),
69         factor         ( image.factor        )
70 {
71 }
72 HudLadder & HudLadder ::
73   operator = ( const HudLadder & rhs )
74 {
75   if( !(this == &rhs)) {
76     (dual_instr_item &)(*this) = (dual_instr_item &)rhs;
77     width_units  = rhs.width_units;
78     div_units    = rhs.div_units;
79     label_pos    = rhs.label_pos;
80     scr_hole     = rhs.scr_hole;
81     vmax         = rhs.vmax;
82     vmin         = rhs.vmin;
83     factor       = rhs.factor;
84     }
85   return *this;
86 }
87
88 //
89 //      Draws a climb ladder in the center of the HUD
90 //
91
92 void HudLadder :: draw( void )
93 {
94   double roll_value;
95   double pitch_value;
96   int    marker_y;
97   int    x_ini;
98   int    x_end;
99   int    y_ini;
100   int    y_end;
101   int    new_x_ini;
102   int    new_x_end;
103   int    new_y_ini;
104   int    new_y_end;
105   int    i;
106   POINT  centroid   = get_centroid();
107   RECT   box        = get_location();
108   int    scr_min    = box.top;
109   int    half_span  = box.right >> 1;
110   char   TextLadder[80];
111   int    condition;
112   int    label_length;
113   roll_value        = current_ch2();
114   GLfloat sinRoll   = sin( roll_value );
115   GLfloat cosRoll   = cos( roll_value );
116
117   pitch_value       = current_ch1() * RAD_TO_DEG;
118   vmin              = pitch_value - (double)width_units/2.0;
119   vmax              = pitch_value + (double)width_units/2.0;
120
121 // Box the target.
122   drawOneLine( centroid.x - 5, centroid.y,     centroid.x,     centroid.y + 5);
123   drawOneLine( centroid.x,     centroid.y + 5, centroid.x + 5, centroid.y);
124   drawOneLine( centroid.x + 5, centroid.y,     centroid.x,     centroid.y - 5);
125   drawOneLine( centroid.x,     centroid.y - 5, centroid.x - 5, centroid.y);
126
127   for( i=(int)vmin; i<=(int)vmax; i++ )  {  // Through integer pitch values...
128     condition = 1;
129     if( condition )      {
130       marker_y = centroid.y + (int)(((double)(i - pitch_value) * factor) + .5);
131       if( div_units ) {
132         if( !(i % div_units ))    {        //  At integral multiple of div
133           sprintf( TextLadder, "%d", i );
134           label_length = strlen( TextLadder );
135           if( scr_hole == 0 )           {
136             if( i ) {
137               x_ini = centroid.x - half_span;
138               }
139             else {                         // Make zero point wider on left
140               x_ini = centroid.x - half_span - 10;
141               }
142             y_ini = marker_y;
143             x_end = centroid.x + half_span;
144             y_end = marker_y;
145             new_x_ini = centroid.x + (int)(
146                        (x_ini - centroid.x) * cosRoll -
147                        (y_ini - centroid.y) * sinRoll);
148             new_y_ini = centroid.y + (int)(             \
149                        (x_ini - centroid.x) * sinRoll + \
150                        (y_ini - centroid.y) * cosRoll);
151             new_x_end = centroid.x + (int)(             \
152                        (x_end - centroid.x) * cosRoll - \
153                        (y_end - centroid.y) * sinRoll);
154             new_y_end = centroid.y + (int)(             \
155                        (x_end - centroid.x) * sinRoll + \
156                        (y_end - centroid.y) * cosRoll);
157
158             if( i >= 0 ) { // Above zero draw solid lines
159               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
160               }
161             else         { // Below zero draw dashed lines.
162               glEnable(GL_LINE_STIPPLE);
163               glLineStipple( 1, 0x00FF );
164               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
165               glDisable(GL_LINE_STIPPLE);
166               }
167             // Calculate the position of the left text and write it.
168             new_x_ini = centroid.x + (int)(
169                         (x_ini - 8 * label_length- 4 - centroid.x) * cosRoll -
170                         (y_ini - 4 ) * sinRoll);
171             new_y_ini = centroid.y + (int)(
172                         (x_ini - 8 * label_length- 4 - centroid.x) * sinRoll +
173                         (y_ini - 4 - centroid.y) * cosRoll);
174             strokeString( new_x_ini , new_y_ini ,
175                         TextLadder, GLUT_STROKE_ROMAN,
176                         roll_value );
177
178             // Calculate the position of the right text and write it.
179             new_x_end = centroid.x + (int)(                  \
180                        (x_end + 24 - 8 * label_length - centroid.x) * cosRoll - \
181                        (y_end -  4 - centroid.y) * sinRoll);
182             new_y_end = centroid.y + (int)(                  \
183                        (x_end + 24 - 8 * label_length - centroid.x) * sinRoll + \
184                        (y_end -  4 - centroid.y) * cosRoll);
185             strokeString( new_x_end,  new_y_end,
186                           TextLadder, GLUT_STROKE_ROMAN,
187                           roll_value );
188             }
189           else   {  // Draw ladder with space in the middle of the lines
190                     // Start by calculating the points and drawing the
191                     // left side lines.
192             if( i != 0 )  {
193               x_ini = centroid.x - half_span;
194               }
195             else          {
196               x_ini = centroid.x - half_span - 10;
197               }
198             y_ini = marker_y;
199             x_end = centroid.x - half_span + scr_hole/2;
200             y_end = marker_y;
201
202             new_x_end = centroid.x+  (int)(             \
203                         (x_end - centroid.x) * cosRoll -\
204                         (y_end - centroid.y) * sinRoll);
205             new_y_end = centroid.y+ (int)(              \
206                         (x_end - centroid.x) * sinRoll +\
207                         (y_end - centroid.y) * cosRoll);
208             new_x_ini = centroid.x + (int)(              \
209                         (x_ini - centroid.x) * cosRoll -\
210                         (y_ini - centroid.y) * sinRoll);
211             new_y_ini = centroid.y + (int)(             \
212                         (x_ini - centroid.x) * sinRoll +\
213                         (y_ini - centroid.y) * cosRoll);
214
215             if( i >= 0 )
216               {
217               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
218               }
219             else  {
220               glEnable(GL_LINE_STIPPLE);
221               glLineStipple( 1, 0x00FF );
222               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
223               glDisable(GL_LINE_STIPPLE);
224               }
225             // Now calculate the location of the left side label using
226             // the previously calculated start of the left side line.
227
228             x_ini = x_ini - (label_length + 32 + centroid.x);
229             if( i < 0) {
230               x_ini -= 8;
231               }
232             else {
233               if( i == 0 ) {
234                 x_ini += 20;
235                 }
236               }
237             y_ini = y_ini - ( 4 + centroid.y);
238
239             new_x_ini = centroid.x + (int)(x_ini * cosRoll - y_ini * sinRoll);
240             new_y_ini = centroid.y + (int)(x_ini * sinRoll + y_ini * cosRoll);
241             strokeString( new_x_ini , new_y_ini ,
242                           TextLadder, GLUT_STROKE_MONO_ROMAN,
243                           roll_value );
244
245             // Now calculate and draw the right side line location
246             x_ini = centroid.x + half_span - scr_hole/2;
247             y_ini = marker_y;
248             if( i != 0 )  {
249               x_end = centroid.x + half_span;
250               }
251             else          {
252               x_end = centroid.x + half_span + 10;
253               }
254             y_end = marker_y;
255
256             new_x_ini = centroid.x + (int)(         \
257                         (x_ini-centroid.x)*cosRoll -\
258                         (y_ini-centroid.y)*sinRoll);
259             new_y_ini = centroid.y + (int)(         \
260                         (x_ini-centroid.x)*sinRoll +\
261                         (y_ini-centroid.y)*cosRoll);
262             new_x_end = centroid.x + (int)(         \
263                         (x_end-centroid.x)*cosRoll -\
264                         (y_end-centroid.y)*sinRoll);
265             new_y_end = centroid.y +  (int)(        \
266                         (x_end-centroid.x)*sinRoll +\
267                         (y_end-centroid.y)*cosRoll);
268
269             if( i >= 0 )
270               {
271               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
272               }
273             else
274               {
275               glEnable(GL_LINE_STIPPLE);
276               glLineStipple( 1, 0x00FF );
277               drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
278               glDisable(GL_LINE_STIPPLE);
279               }
280
281             // Calculate the location and draw the right side label
282             // using the end of the line as previously calculated.
283             x_end -= centroid.x + label_length - 24;
284             if( i < 0 ) {
285               x_end -= 8;
286               }
287             y_end  = marker_y - ( 4 + centroid.y);
288             new_x_end = centroid.x + (int)( (GLfloat)x_end * cosRoll -
289                                             (GLfloat)y_end * sinRoll);
290             new_y_end = centroid.y + (int)( (GLfloat)x_end * sinRoll +
291                                             (GLfloat)y_end * cosRoll);
292             strokeString( new_x_end,  new_y_end,
293                           TextLadder, GLUT_STROKE_MONO_ROMAN,
294                           roll_value );
295             }
296           }
297         }
298       }
299     }
300 }
301