]> git.mxchange.org Git - flightgear.git/blob - Cockpit/hud_card.cxx
C++ ifying ...
[flightgear.git] / Cockpit / hud_card.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.hxx>
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
19
20 #include "hud.hxx"
21 //========== Top of hud_card class member definitions =============
22
23 hud_card ::
24 hud_card( int       x,
25           int       y,
26           UINT      width,
27           UINT      height,
28           DBLFNPTR  data_source,
29           UINT      options,
30           double    max_value,
31           double    min_value,
32           double    disp_scaling,
33           UINT      major_divs,
34           UINT      minor_divs,
35           UINT      modulus,
36           int       dp_showing,
37           double    value_span,
38           bool      working) :
39                 instr_scale( x,y,width,height,
40                              data_source, options,
41                              value_span,
42                              max_value, min_value, disp_scaling,
43                              major_divs, minor_divs, modulus,
44                              working),
45                 val_span   ( value_span)
46 {
47   half_width_units = range_to_show() / 2.0;
48 }
49
50 hud_card ::
51 ~hud_card() { }
52
53 hud_card ::
54 hud_card( const hud_card & image):
55       instr_scale( (const instr_scale & ) image),
56       val_span( image.val_span),
57       half_width_units (image.half_width_units)
58 {
59 }
60
61 hud_card & hud_card ::
62 operator = (const hud_card & rhs )
63 {
64   if( !( this == &rhs)){
65     instr_scale::operator = (rhs);
66     val_span = rhs.val_span;
67     half_width_units = rhs.half_width_units;
68     }
69   return *this;
70 }
71
72 void hud_card ::
73 draw( void ) //  (HUD_scale * pscale )
74 {
75   double vmin, vmax;
76   int marker_xs;
77   int marker_xe;
78   int marker_ys;
79   int marker_ye;
80   /* register */ int i;
81   char TextScale[80];
82   bool condition;
83   int disp_val = 0;
84   POINT mid_scr    = get_centroid();
85   double cur_value = get_value();
86   RECT   scrn_rect = get_location();
87   UINT options     = get_options();
88
89   vmin = cur_value - half_width_units; // width units == needle travel
90   vmax = cur_value + half_width_units; // or picture unit span.
91     // Draw the basic markings for the scale...
92
93   if( options & HUDS_VERT ) { // Vertical scale
94     drawOneLine( scrn_rect.left,     // Bottom tick bar
95                  scrn_rect.top,
96                  scrn_rect.left + scrn_rect.right,
97                  scrn_rect.top);
98
99     drawOneLine( scrn_rect.left,    // Top tick bar
100                  scrn_rect.top  + scrn_rect.bottom,
101                  scrn_rect.left + scrn_rect.right,
102                  scrn_rect.top  + scrn_rect.bottom );
103
104     marker_xs = scrn_rect.left;
105     marker_xe = scrn_rect.left + scrn_rect.right;
106
107     // We do not use else in the following so that combining the two
108     // options produces a "caged" display with double carrots. The
109     // same is done for horizontal card indicators.
110
111     if( options & HUDS_LEFT ) {    // Calculate x marker offset
112       drawOneLine( scrn_rect.left + scrn_rect.right,
113                    scrn_rect.top,
114                    scrn_rect.left + scrn_rect.right,
115                    scrn_rect.top + scrn_rect.bottom); // Cap right side
116
117       marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
118                                                       // Indicator carrot
119       drawOneLine( marker_xs, mid_scr.y,
120                    marker_xe, mid_scr.y + scrn_rect.right / 6);
121       drawOneLine( marker_xs, mid_scr.y,
122                    marker_xe, mid_scr.y - scrn_rect.right / 6);
123
124       }
125     if( options & HUDS_RIGHT ) {  // We'll default this for now.
126       drawOneLine( scrn_rect.left,
127                    scrn_rect.top,
128                    scrn_rect.left,
129                    scrn_rect.top + scrn_rect.bottom);  // Cap left side
130
131       marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
132                                                        // Indicator carrot
133       drawOneLine( scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
134                    marker_xe, mid_scr.y );
135       drawOneLine( scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
136                    marker_xe, mid_scr.y);
137       }
138
139     // At this point marker x_start and x_end values are transposed.
140     // To keep this from confusing things they are now interchanged.
141     if(( options & HUDS_BOTH) == HUDS_BOTH) {
142       marker_ye = marker_xs;
143       marker_xs = marker_xe;
144       marker_xe = marker_ye;
145       }
146
147     // Work through from bottom to top of scale. Calculating where to put
148     // minor and major ticks.
149
150     for( i = (int)vmin; i <= (int)vmax; i++ )      {
151       condition = true;
152       if( !modulo()) {
153         if( i < min_val()) {
154           condition = false;
155           }
156         }
157
158       if( condition ) {  // Show a tick if necessary
159                          // Calculate the location of this tick
160         marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
161
162         // Block calculation artifact from drawing ticks below min coordinate.
163         // Calculation here accounts for text height.
164
165         if(( marker_ys < (scrn_rect.top + 4)) |
166            ( marker_ys > (scrn_rect.top + scrn_rect.bottom - 4))) {
167             // Magic numbers!!!
168           continue;
169           }
170         if( div_min()) {
171           if( (i%div_min()) == 0) {
172             if((( marker_ys - 5) > scrn_rect.top ) &&
173                (( marker_ys + 5) < (scrn_rect.top + scrn_rect.bottom))){
174               if( (options & HUDS_BOTH) == HUDS_BOTH ) {
175                 drawOneLine( scrn_rect.left, marker_ys,
176                              marker_xs,      marker_ys );
177                 drawOneLine( marker_xe,      marker_ys,
178                              scrn_rect.left + scrn_rect.right,  marker_ys );
179                 }
180               else {
181                 if( options & HUDS_LEFT ) {
182                   drawOneLine( marker_xs + 4, marker_ys,
183                                marker_xe,     marker_ys );
184                   }
185                 else {
186                   drawOneLine( marker_xs,     marker_ys,
187                                marker_xe - 4, marker_ys );
188                   }
189                 }
190               }
191             }
192           }
193         if( div_max()) {
194           if( !(i%(int)div_max())){
195             if(modulo()) {
196               if( disp_val < 0) {
197                 disp_val += modulo();
198                 }
199               else {
200                 disp_val = i % modulo();
201                 }
202               }
203             else {
204               disp_val = i;
205               }
206             sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
207             if(( (marker_ys - 8 ) > scrn_rect.top ) &&
208                ( (marker_ys + 8) < (scrn_rect.top + scrn_rect.bottom))){
209               if( (options & HUDS_BOTH) == HUDS_BOTH) {
210                 drawOneLine( scrn_rect.left, marker_ys,
211                              marker_xs,      marker_ys);
212                 drawOneLine( marker_xs,                  marker_ys,
213                              scrn_rect.left + scrn_rect.right,
214                              marker_ys);
215                 if( !(options & HUDS_NOTEXT)) {
216                   textString ( marker_xs + 2,  marker_ys,
217                                TextScale,  GLUT_BITMAP_8_BY_13 );
218                   }
219                 }
220               else {
221                 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
222                 if( !(options & HUDS_NOTEXT)) {
223                   if( options & HUDS_LEFT )              {
224                     textString( marker_xs -  8 * strlen(TextScale) - 2,
225                                 marker_ys - 4,
226                                 TextScale, GLUT_BITMAP_8_BY_13 );
227                     }
228                   else  {
229                     textString( marker_xe + 3 * strlen(TextScale),
230                                 marker_ys - 4,
231                                 TextScale, GLUT_BITMAP_8_BY_13 );
232                     }
233                   }
234                 }
235               } // Else read oriented right
236             } // End if modulo division by major interval is zero
237           }  // End if major interval divisor non-zero
238         } // End if condition
239       } // End for range of i from vmin to vmax
240     }  // End if VERTICAL SCALE TYPE
241   else {                                // Horizontal scale by default
242     drawOneLine( scrn_rect.left,     // left tick bar
243                  scrn_rect.top,
244                  scrn_rect.left,
245                  scrn_rect.top + scrn_rect.bottom);
246
247     drawOneLine( scrn_rect.left + scrn_rect.right,    // right tick bar
248                  scrn_rect.top,
249                  scrn_rect.left + scrn_rect.right,
250                  scrn_rect.top  + scrn_rect.bottom );
251
252     marker_ys = scrn_rect.top;                       // Starting point for
253     marker_ye = scrn_rect.top + scrn_rect.bottom;    // tick y location calcs
254
255     if( options & HUDS_TOP ) {
256       drawOneLine( scrn_rect.left,
257                    scrn_rect.top,
258                    scrn_rect.left + scrn_rect.right,
259                    scrn_rect.top);                    // Bottom box line
260
261       marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;   // Tick point adjust
262                                                       // Bottom arrow
263       drawOneLine( mid_scr.x, marker_ye,
264                    mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
265       drawOneLine( mid_scr.x, marker_ye,
266                    mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
267       }
268     if( options & HUDS_BOTTOM) {
269       drawOneLine( scrn_rect.left,
270                    scrn_rect.top + scrn_rect.bottom,
271                    scrn_rect.left + scrn_rect.right,
272                    scrn_rect.top + scrn_rect.bottom);  // Top box line
273                                                        // Tick point adjust
274       marker_ys = scrn_rect.top +
275                   scrn_rect.bottom - scrn_rect.bottom  / 2;
276                                                        // Top arrow
277       drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
278                           scrn_rect.top + scrn_rect.bottom,
279                    mid_scr.x ,
280                           marker_ys );
281       drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
282                           scrn_rect.top + scrn_rect.bottom,
283                    mid_scr.x ,
284                           marker_ys );
285       }
286
287 //    if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
288 //      marker_xe = marker_ys;
289 //      marker_ys = marker_ye;
290 //      marker_ye = marker_xe;
291 //      }
292
293     // printf("vmin = %d  vmax = %d\n", (int)vmin, (int)vmax);
294     for( i = (int)vmin; i <= (int)vmax; i++ )     {
295       // printf("<*> i = %d\n", i);
296       condition = true;
297       if( !modulo()) {
298         if( i < min_val()) {
299           condition = false;
300           }
301         }
302       // printf("<**> i = %d\n", i);
303       if( condition )        {
304         marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
305         if( div_min()){
306           if( (i%(int)div_min()) == 0 ) {
307             // draw in ticks only if they aren't too close to the edge.
308             if((( marker_xs - 5) > scrn_rect.left ) &&
309                (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
310
311               if( (options & HUDS_BOTH) == HUDS_BOTH ) {
312                 drawOneLine( marker_xs, scrn_rect.top,
313                              marker_xs, marker_ys - 4);
314                 drawOneLine( marker_xs, marker_ye + 4,
315                              marker_xs, scrn_rect.top + scrn_rect.bottom);
316                 }
317               else {
318                 if( options & HUDS_TOP) {
319                   drawOneLine( marker_xs, marker_ys,
320                                marker_xs, marker_ye - 4);
321                   }
322                 else {
323                   drawOneLine( marker_xs, marker_ys + 4,
324                                marker_xs, marker_ye);
325                   }
326                 }
327               }
328             }
329           }
330         // printf("<***> i = %d\n", i);
331         if( div_max()) {
332           // printf("i = %d\n", i);
333           if( (i%(int)div_max())==0 ) {
334             if(modulo()) {
335               if( disp_val < 0) {
336                 disp_val += modulo();
337                 }
338               else {
339                 disp_val = i % modulo();
340                 }
341               }
342             else {
343               disp_val = i;
344               }
345             // printf("disp_val = %d\n", disp_val);
346             // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
347             sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
348             // Draw major ticks and text only if far enough from the edge.
349             if(( (marker_xs - 10)> scrn_rect.left ) &&
350                ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
351               if( (options & HUDS_BOTH) == HUDS_BOTH) {
352                 drawOneLine( marker_xs, scrn_rect.top,
353                              marker_xs, marker_ys);
354                 drawOneLine( marker_xs, marker_ye,
355                              marker_xs, scrn_rect.top + scrn_rect.bottom);
356
357                 if( !(options & HUDS_NOTEXT)) {
358                   textString ( marker_xs - 4 * strlen(TextScale),
359                                marker_ys + 4,
360                                TextScale,  GLUT_BITMAP_8_BY_13 );
361                   }
362                 }
363               else {
364                 drawOneLine( marker_xs, marker_ys,
365                              marker_xs, marker_ye );
366                 if( !(options & HUDS_NOTEXT)) {
367                   if( options & HUDS_TOP )              {
368                     textString ( marker_xs - 4 * strlen(TextScale),
369                                  scrn_rect.top + scrn_rect.bottom - 10,
370                                  TextScale, GLUT_BITMAP_8_BY_13 );
371                     }
372                   else  {
373                     textString( marker_xs - 4 * strlen(TextScale),
374                                 scrn_rect.top,
375                                 TextScale, GLUT_BITMAP_8_BY_13 );
376                     }
377                   }
378                 }
379               }
380             }
381           }
382         // printf("<****> i = %d\n", i);
383         }
384       }
385     }
386 }
387