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