]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud_card.cxx
Updates to vacuum system model from Alex Perry.
[flightgear.git] / src / 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
11 #include <simgear/constants.h>
12 #include <simgear/math/fg_random.h>
13 #include <simgear/math/polar3d.hxx>
14
15 #include <Aircraft/aircraft.hxx>
16 #include <GUI/gui.h>
17 #include <Scenery/scenery.hxx>
18 #include <Time/fg_timer.hxx>
19
20 #include "hud.hxx"
21
22 #ifdef USE_HUD_TextList
23 #define textString( x , y, text, font )  TextString( text, x , y )
24 #else
25 #define textString( x , y, text, font )  puDrawString ( guiFnt, text, x, y );
26 #endif
27
28 //========== Top of hud_card class member definitions =============
29
30 hud_card ::
31 hud_card( int       x,
32           int       y,
33           UINT      width,
34           UINT      height,
35           FLTFNPTR  data_source,
36           UINT      options,
37           float    max_value, // 360
38           float    min_value, // 0
39           float    disp_scaling,
40           UINT      major_divs,
41           UINT      minor_divs,
42           UINT      modulus,  // 360
43           int       dp_showing,
44           float    value_span,
45           bool      working) :
46                 instr_scale( x,y,width,height,
47                              data_source, options,
48                              value_span,
49                              max_value, min_value, disp_scaling,
50                              major_divs, minor_divs, modulus,
51                              working),
52                 val_span   ( value_span)
53 {
54   half_width_units = range_to_show() / 2.0;
55 //  UINT options     = get_options();
56 //  huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
57 //  huds_right = options & HUDS_RIGHT;
58 //  huds_left = options & HUDS_LEFT;
59 //  huds_vert = options & HUDS_VERT;
60 //  huds_notext = options & HUDS_NOTEXT;
61 //  huds_top = options & HUDS_TOP;
62 //  huds_bottom = options & HUDS_BOTTOM;
63 }
64
65 hud_card ::
66 ~hud_card() { }
67
68 hud_card ::
69 hud_card( const hud_card & image):
70       instr_scale( (const instr_scale & ) image),
71       val_span( image.val_span),
72       half_width_units (image.half_width_units)
73 {
74 //  UINT options     = get_options();
75 //  huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
76 //  huds_right = options & HUDS_RIGHT;
77 //  huds_left = options & HUDS_LEFT;
78 //  huds_vert = options & HUDS_VERT;
79 //  huds_notext = options & HUDS_NOTEXT;
80 //  huds_top = options & HUDS_TOP;
81 //  huds_bottom = options & HUDS_BOTTOM;
82 }
83
84 hud_card & hud_card ::
85 operator = (const hud_card & rhs )
86 {
87   if( !( this == &rhs)){
88     instr_scale::operator = (rhs);
89     val_span = rhs.val_span;
90     half_width_units = rhs.half_width_units;
91     }
92   return *this;
93 }
94
95 void hud_card ::
96 draw( void ) //  (HUD_scale * pscale )
97 {
98   float vmin, vmax;
99   int marker_xs;
100   int marker_xe;
101   int marker_ys;
102   int marker_ye;
103   int lenstr;
104   int height, width;
105   int i, last;
106   char TextScale[80];
107   bool condition;
108   int disp_val = 0;
109   POINT mid_scr    = get_centroid();
110   float cur_value  = get_value();
111   RECT   scrn_rect = get_location();
112   UINT options     = get_options();
113
114   height = scrn_rect.top  + scrn_rect.bottom;
115   width = scrn_rect.left + scrn_rect.right;
116
117   vmin = cur_value - half_width_units; // width units == needle travel
118   vmax = cur_value + half_width_units; // or picture unit span.
119   
120   // Draw the basic markings for the scale...
121   
122   if( huds_vert(options) ) { // Vertical scale
123     drawOneLine( scrn_rect.left,     // Bottom tick bar
124                  scrn_rect.top,
125                  width,
126                  scrn_rect.top);
127
128     drawOneLine( scrn_rect.left,    // Top tick bar
129                  height,
130                  width,
131                  height );
132       
133       marker_xs = scrn_rect.left;  // x start
134       marker_xe = width;  // x extent
135       marker_ye = height;
136
137 //    glBegin(GL_LINES);
138       
139       // Bottom tick bar
140 //    glVertex2f( marker_xs, scrn_rect.top);
141 //    glVertex2f( marker_xe, scrn_rect.top);
142
143       // Top tick bar
144 //    glVertex2f( marker_xs, marker_ye);
145 //    glVertex2f( marker_xe, marker_ye );
146 //    glEnd();
147
148     // We do not use else in the following so that combining the two
149     // options produces a "caged" display with double carrots. The
150     // same is done for horizontal card indicators.
151
152       if( huds_left(options) ) {    // Calculate x marker offset
153           drawOneLine( marker_xe, scrn_rect.top,
154                        marker_xe, marker_ye); // Cap right side
155
156         marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
157                                                       // Indicator carrot
158 //      drawOneLine( marker_xs, mid_scr.y,
159 //                   marker_xe, mid_scr.y + scrn_rect.right / 6);
160 //      drawOneLine( marker_xs, mid_scr.y,
161 //                   marker_xe, mid_scr.y - scrn_rect.right / 6);
162
163         glBegin(GL_LINE_STRIP);
164         glVertex2f( marker_xe, mid_scr.y + scrn_rect.right / 6);
165         glVertex2f( marker_xs, mid_scr.y);
166         glVertex2f( marker_xe, mid_scr.y - scrn_rect.right / 6);
167         glEnd();
168     }
169     if( huds_right(options) ) {  // We'll default this for now.
170         drawOneLine( scrn_rect.left, scrn_rect.top,
171                      scrn_rect.left, marker_ye );  // Cap left side
172
173         marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
174                                                        // Indicator carrot
175 //      drawOneLine( scrn_rect.left, mid_scr.y +  scrn_rect.right / 6,
176 //                   marker_xe, mid_scr.y );
177 //      drawOneLine( scrn_rect.left, mid_scr.y -  scrn_rect.right / 6,
178 //                   marker_xe, mid_scr.y);
179         glBegin(GL_LINE_STRIP);
180         glVertex2f( scrn_rect.left, mid_scr.y +  scrn_rect.right / 6);
181         glVertex2f( marker_xe, mid_scr.y );
182         glVertex2f( scrn_rect.left, mid_scr.y -  scrn_rect.right / 6);
183         glEnd();
184     }
185
186     // At this point marker x_start and x_end values are transposed.
187     // To keep this from confusing things they are now interchanged.
188     if(huds_both(options)) {
189       marker_ye = marker_xs;
190       marker_xs = marker_xe;
191       marker_xe = marker_ye;
192       }
193
194     // Work through from bottom to top of scale. Calculating where to put
195     // minor and major ticks.
196
197 //  last = FloatToInt(vmax)+1;
198 //  i = FloatToInt(vmin);
199     last = (int)vmax + 1;
200     i = (int)vmin;
201     for( ; i <last ; i++ )
202     {
203       condition = true;
204       if( !modulo()) {
205         if( i < min_val()) {
206           condition = false;
207           }
208         }
209
210       if( condition ) {  // Show a tick if necessary
211                          // Calculate the location of this tick
212         marker_ys = scrn_rect.top + FloatToInt(((i - vmin) * factor()/*+.5f*/));
213 //        marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
214         // Block calculation artifact from drawing ticks below min coordinate.
215         // Calculation here accounts for text height.
216
217         if(( marker_ys < (scrn_rect.top + 4)) |
218            ( marker_ys > (height - 4))) {
219             // Magic numbers!!!
220           continue;
221           }
222         if( div_min()) {
223 //          if( (i%div_min()) == 0) {
224           if( !(i%(int)div_min())) {            
225             if((( marker_ys - 5) > scrn_rect.top ) &&
226                (( marker_ys + 5) < (height))){
227               if( huds_both(options) ) {
228                 drawOneLine( scrn_rect.left, marker_ys,
229                              marker_xs,      marker_ys );
230                 drawOneLine( marker_xe,      marker_ys,
231                              width,  marker_ys );
232 //                glBegin(GL_LINES);
233 //                glVertex2f( scrn_rect.left, marker_ys );
234 //                glVertex2f( marker_xs,      marker_ys );
235 //                glVertex2f( marker_xe,      marker_ys);
236 //                glVertex2f( scrn_rect.left + scrn_rect.right,  marker_ys );
237 //                glEnd();
238                   }
239               else {
240                 if( huds_left(options) ) {
241                   drawOneLine( marker_xs + 4, marker_ys,
242                                marker_xe,     marker_ys );
243                   }
244                 else {
245                   drawOneLine( marker_xs,     marker_ys,
246                                marker_xe - 4, marker_ys );
247                   }
248                 }
249               }
250             }
251           }
252         if( div_max() ) {
253           if( !(i%(int)div_max()) )         
254           {
255             if(modulo()) {
256                 if( disp_val < 0) {
257                     while(disp_val < 0)
258                         disp_val += modulo();
259 //              } else {
260 //                  disp_val = i % (int)modulo();
261                 }
262                 disp_val = i % (int) modulo(); // ?????????
263             } else {
264                 disp_val = i;
265             }
266
267             lenstr = sprintf( TextScale, "%d",
268                               FloatToInt(disp_val * data_scaling()/*+.5*/));
269 //                            (int)(disp_val  * data_scaling() +.5));
270             if(( (marker_ys - 8 ) > scrn_rect.top ) &&
271                ( (marker_ys + 8) < (height))){
272               if( huds_both(options) ) {
273 //                drawOneLine( scrn_rect.left, marker_ys,
274 //                             marker_xs,      marker_ys);
275 //                drawOneLine( marker_xs, marker_ys,
276 //                             scrn_rect.left + scrn_rect.right,
277 //                             marker_ys);
278                   glBegin(GL_LINE_STRIP);
279                   glVertex2f( scrn_rect.left, marker_ys );
280                   glVertex2f( marker_xs, marker_ys);
281                   glVertex2f( width, marker_ys);
282                   glEnd();
283                   if( !huds_notext(options)) {
284                       textString ( marker_xs + 2,  marker_ys,
285                                    TextScale,  GLUT_BITMAP_8_BY_13 );
286                   }
287               }
288               else {
289                 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
290                 if( !huds_notext(options) ) {
291                   if( huds_left(options) )              {
292                       textString( marker_xs -  8 * lenstr - 2,
293                                   marker_ys - 4,
294                                   TextScale, GLUT_BITMAP_8_BY_13 );
295                     }
296                   else  {
297                       textString( marker_xe + 3 * lenstr,
298                                   marker_ys - 4,
299                                   TextScale, GLUT_BITMAP_8_BY_13 );
300                   }
301                   }
302                 }
303               } // Else read oriented right
304             } // End if modulo division by major interval is zero
305           }  // End if major interval divisor non-zero
306         } // End if condition
307       } // End for range of i from vmin to vmax
308     }  // End if VERTICAL SCALE TYPE
309   else {                                // Horizontal scale by default
310       // left tick bar
311       drawOneLine( scrn_rect.left, scrn_rect.top,
312                    scrn_rect.left, height);
313
314       // right tick bar
315       drawOneLine( width, scrn_rect.top,
316                  width,
317                  height );
318       
319       marker_ys = scrn_rect.top;           // Starting point for
320       marker_ye = height;                  // tick y location calcs
321       marker_xe = width;
322
323 //    glBegin(GL_LINES);
324       // left tick bar
325 //    glVertex2f( scrn_rect.left, scrn_rect.top);
326 //    glVertex2f( scrn_rect.left, marker_ye);
327
328       // right tick bar
329 //    glVertex2f( marker_xe, scrn_rect.top);
330 //    glVertex2f( marker_xe, marker_ye );
331 //    glEnd();
332
333     if( huds_top(options) ) {
334         // Bottom box line
335         drawOneLine( scrn_rect.left,
336                      scrn_rect.top,
337                      width,
338                      scrn_rect.top);
339
340         // Tick point adjust
341         marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;
342         
343         // Bottom arrow
344 //      drawOneLine( mid_scr.x, marker_ye,
345 //                   mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
346 //      drawOneLine( mid_scr.x, marker_ye,
347 //                   mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
348
349         glBegin(GL_LINE_STRIP);
350         glVertex2f( mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
351         glVertex2f( mid_scr.x, marker_ye);
352         glVertex2f( mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
353         glEnd();
354     }
355     if( huds_bottom(options) ) {
356         // Top box line
357         drawOneLine( scrn_rect.left, height,
358                      width, height);
359         // Tick point adjust
360         marker_ys = height - scrn_rect.bottom  / 2;
361         
362         // Top arrow
363 //      drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
364 //                   scrn_rect.top + scrn_rect.bottom,
365 //                   mid_scr.x, marker_ys );
366 //      drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
367 //                   scrn_rect.top + scrn_rect.bottom,
368 //                   mid_scr.x , marker_ys );
369         glBegin(GL_LINE_STRIP);
370         glVertex2f( mid_scr.x + scrn_rect.bottom / 4,
371                     height);
372         glVertex2f( mid_scr.x , marker_ys );
373         glVertex2f( mid_scr.x - scrn_rect.bottom / 4,
374                     height);
375         glEnd();
376     }
377
378 //    if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
379 //      marker_xe = marker_ys;
380 //      marker_ys = marker_ye;
381 //      marker_ye = marker_xe;
382 //      }
383
384     // printf("vmin = %d  vmax = %d\n", (int)vmin, (int)vmax);
385
386 //  last = FloatToInt(vmax)+1;
387 //  i    = FloatToInt(vmin);
388     last = (int)vmax + 1;
389     i = (int)vmin;
390     for(; i <last ; i++ )      {
391 //    for( i = (int)vmin; i <= (int)vmax; i++ )     {
392       // printf("<*> i = %d\n", i);
393       condition = true;
394       if( !modulo()) {
395         if( i < min_val()) {
396           condition = false;
397           }
398         }
399       // printf("<**> i = %d\n", i);
400       if( condition )        {
401 //        marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
402         marker_xs = scrn_rect.left + FloatToInt(((i - vmin) * factor()/*+ .5f*/));
403         if( div_min()){
404 //          if( (i%(int)div_min()) == 0 ) {
405           if( !(i%(int)div_min() )) {           
406             // draw in ticks only if they aren't too close to the edge.
407             if((( marker_xs - 5) > scrn_rect.left ) &&
408                (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
409
410               if( huds_both(options) ) {
411                 drawOneLine( marker_xs, scrn_rect.top,
412                              marker_xs, marker_ys - 4);
413                 drawOneLine( marker_xs, marker_ye + 4,
414                              marker_xs, height);
415 //                glBegin(GL_LINES);
416 //                glVertex2f( marker_xs, scrn_rect.top);
417 //                glVertex2f( marker_xs, marker_ys - 4);
418 //                glVertex2f( marker_xs, marker_ye + 4);
419 //                glVertex2f( marker_xs, scrn_rect.top + scrn_rect.bottom);
420 //                glEnd();
421               }
422               else {
423                 if( huds_top(options)) {
424                   drawOneLine( marker_xs, marker_ys,
425                                marker_xs, marker_ye - 4);
426                   }
427                 else {
428                   drawOneLine( marker_xs, marker_ys + 4,
429                                marker_xs, marker_ye);
430                   }
431                 }
432               }
433             }
434           }
435     // printf("<***> i = %d\n", i);
436         if( div_max()) {
437       // printf("i = %d\n", i);
438 //          if( (i%(int)div_max())==0 ) {
439           if( !(i%(int)div_max()) ) {           
440             if(modulo()) {
441               if( disp_val < 0) {
442                   while(disp_val<0)
443                       disp_val += modulo();
444               }
445               disp_val = i % (int) modulo(); // ?????????
446             } else {
447               disp_val = i;
448             }
449         // printf("disp_val = %d\n", disp_val);
450         // printf("%d\n", (int)(disp_val  * (double)data_scaling() + 0.5));
451             lenstr = sprintf( TextScale, "%d",
452 //                            (int)(disp_val  * data_scaling() +.5));
453                               FloatToInt(disp_val * data_scaling()/*+.5*/));
454             // Draw major ticks and text only if far enough from the edge.
455             if(( (marker_xs - 10)> scrn_rect.left ) &&
456                ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
457               if( huds_both(options) ) {
458 //                drawOneLine( marker_xs, scrn_rect.top,
459 //                             marker_xs, marker_ys);
460 //                drawOneLine( marker_xs, marker_ye,
461 //                             marker_xs, scrn_rect.top + scrn_rect.bottom);
462                   glBegin(GL_LINE_STRIP);
463                   glVertex2f( marker_xs, scrn_rect.top);
464                   glVertex2f( marker_xs, marker_ye);
465                   glVertex2f( marker_xs, height);
466                   glEnd();
467                 if( !huds_notext(options) ) {
468                   textString ( marker_xs - 4 * lenstr,
469                                marker_ys + 4,
470                                TextScale,  GLUT_BITMAP_8_BY_13 );
471                   }
472                 }
473               else {
474                 drawOneLine( marker_xs, marker_ys,
475                              marker_xs, marker_ye );
476                 if( !huds_notext(options)) {
477                   if( huds_top(options) )              {
478                     textString ( marker_xs - 4 * lenstr,
479                                  height - 10,
480                                  TextScale, GLUT_BITMAP_8_BY_13 );
481                     }
482                   else  {
483                     textString( marker_xs - 4 * lenstr,
484                                 scrn_rect.top,
485                                 TextScale, GLUT_BITMAP_8_BY_13 );
486                     }
487                   }
488                 }
489               }
490             }
491       }
492     // printf("<****> i = %d\n", i);
493         }
494       }
495     }
496 }
497