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