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