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