]> git.mxchange.org Git - flightgear.git/blob - Cockpit/hud_guag.cxx
7ea060257aeaf33d1b54058e7f28c59e5ac04042
[flightgear.git] / Cockpit / hud_guag.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 guage_instr class member definitions ==============
23
24 guage_instr ::
25     guage_instr( int          x,
26                  int          y,
27                  UINT         width,
28                  UINT         height,
29                  DBLFNPTR     load_fn,
30                  UINT         options,
31                  double       disp_scale,
32                  double       maxValue,
33                  double       minValue,
34                  UINT         major_divs,
35                  UINT         minor_divs,
36                  int          dp_showing,
37                  UINT         modulus,
38                  bool         working) :
39            instr_scale( x, y, width, height,
40                         load_fn, options,
41                         (maxValue - minValue), // Always shows span?
42                         maxValue, minValue,
43                         disp_scale,
44                         major_divs, minor_divs,
45                         modulus, dp_showing,
46                         working)
47 {
48 }
49
50 guage_instr ::
51    ~guage_instr()
52 {
53 }
54
55 guage_instr ::
56     guage_instr( const guage_instr & image):
57        instr_scale( (instr_scale &) image)
58 {
59 }
60
61 guage_instr & guage_instr ::
62     operator = (const guage_instr & rhs )
63 {
64   if( !(this == &rhs)) {
65     instr_scale::operator = (rhs);
66     }
67   return *this;
68 }
69
70 // As implemented, draw only correctly draws a horizontal or vertical
71 // scale. It should contain a variation that permits clock type displays.
72 // Now is supports "tickless" displays such as control surface indicators.
73 // This routine should be worked over before using. Current value would be
74 // fetched and not used if not commented out. Clearly that is intollerable.
75
76 void guage_instr :: draw (void)
77 {
78   int marker_xs, marker_xe;
79   int marker_ys, marker_ye;
80   int text_x, text_y;
81   register i;
82   char TextScale[80];
83   bool condition;
84   int disp_val;
85   double vmin         = min_val();
86   double vmax         = max_val();
87   POINT mid_scr       = get_centroid();
88   double cur_value    = get_value();
89   RECT   scrn_rect    = get_location();
90   UINT options        = get_options();
91
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     if( options & HUDS_LEFT ) {     // Read left, so line down right side
109       drawOneLine( scrn_rect.left + scrn_rect.right,
110                    scrn_rect.top,
111                    scrn_rect.left + scrn_rect.right,
112                    scrn_rect.top + scrn_rect.bottom);
113
114       marker_xs  = marker_xe - scrn_rect.right / 3;   // Adjust tick xs
115       }
116     if( options & HUDS_RIGHT ) {     // Read  right, so down left sides
117       drawOneLine( scrn_rect.left,
118                    scrn_rect.top,
119                    scrn_rect.left,
120                    scrn_rect.top + scrn_rect.bottom);
121       marker_xe = scrn_rect.left + scrn_rect.right / 3;     // Adjust tick xe
122       }
123
124     // At this point marker x_start and x_end values are transposed.
125     // To keep this from confusing things they are now interchanged.
126     if(( options & HUDS_BOTH) == HUDS_BOTH) {
127       marker_ye = marker_xs;
128       marker_xs = marker_xe;
129       marker_xe = marker_ye;
130       }
131
132     // Work through from bottom to top of scale. Calculating where to put
133     // minor and major ticks.
134
135     if( !(options & HUDS_NOTICKS )) {    // If not no ticks...:)
136                                           // Calculate x marker offsets
137       for( i = (int)vmin; i <= (int)vmax; i++ ) {
138
139         // Calculate the location of this tick
140         marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
141
142         // We compute marker_ys even though we don't know if we will use
143         // either major or minor divisions. Simpler.
144
145         if( div_min()) {                  // Minor tick marks
146           if( (i%div_min()) == 0) {
147             if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
148                 drawOneLine( scrn_rect.left, marker_ys,
149                              marker_xs - 3, marker_ys );
150                 drawOneLine( marker_xe + 3, marker_ys,
151                              scrn_rect.left + scrn_rect.right, marker_ys );
152               }
153             else {
154               if( options & HUDS_LEFT) {
155                 drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
156                 }
157               else {
158                 drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
159                }
160               }
161             }
162           }
163
164           // Now we work on the major divisions. Since these are also labeled
165           // and no labels are drawn otherwise, we label inside this if
166           // statement.
167
168         if( div_max()) {                  // Major tick mark
169           if( (i%div_max()) == 0 )            {
170             if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
171
172                 drawOneLine( scrn_rect.left, marker_ys,
173                              marker_xs, marker_ys );
174                 drawOneLine( marker_xe, marker_ys,
175                              scrn_rect.left + scrn_rect.right, marker_ys );
176               }
177             else {
178               drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
179               }
180
181             if( !(options & HUDS_NOTEXT)) {
182               disp_val = i;
183               sprintf( TextScale, "%d",disp_val  * (int)(data_scaling() +.5));
184
185               if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
186                 text_x = mid_scr.x -  2 - ((3 * strlen( TextScale ))>>1);
187                 }
188               else {
189                 if( options & HUDS_LEFT )              {
190                   text_x = marker_xs - 2 - 3 * strlen( TextScale);
191                   }
192                 else {
193                   text_x = marker_xe + 10 - strlen( TextScale );
194                   }
195                 }
196               // Now we know where to put the text.
197               text_y = marker_ys;
198               textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 );
199               }
200             }
201           }  //
202         }  //
203       }  //
204     // Now that the scale is drawn, we draw in the pointer(s). Since labels
205     // have been drawn, text_x and text_y may be recycled. This is used
206     // with the marker start stops to produce a pointer for each side reading
207
208     text_y = scrn_rect.top + (int)((cur_value - vmin) * factor() + .5);
209 //    text_x = marker_xs - scrn_rect.left;
210
211     if( options & HUDS_RIGHT ) {
212       drawOneLine(scrn_rect.left, text_y + 5,
213                   marker_xe,      text_y);
214       drawOneLine(scrn_rect.left, text_y - 5,
215                   marker_xe,      text_y);
216       }
217     if( options & HUDS_LEFT ) {
218       drawOneLine(scrn_rect.left + scrn_rect.right, text_y + 5,
219                   marker_xs,                        text_y);
220       drawOneLine(scrn_rect.left + scrn_rect.right, text_y - 5,
221                   marker_xs,                        text_y);
222       }
223     }  // End if VERTICAL SCALE TYPE
224   else {                                // Horizontal scale by default
225     drawOneLine( scrn_rect.left,     // left tick bar
226                  scrn_rect.top,
227                  scrn_rect.left,
228                  scrn_rect.top + scrn_rect.bottom);
229
230     drawOneLine( scrn_rect.left + scrn_rect.right,    // right tick bar
231                  scrn_rect.top,
232                  scrn_rect.left + scrn_rect.right,
233                  scrn_rect.top  + scrn_rect.bottom );
234
235     marker_ys = scrn_rect.top;                       // Starting point for
236     marker_ye = scrn_rect.top + scrn_rect.bottom;    // tick y location calcs
237     marker_xs = scrn_rect.left + (int)((cur_value - vmin) * factor() + .5);
238
239     if( options & HUDS_TOP ) {
240       drawOneLine( scrn_rect.left,
241                    scrn_rect.top,
242                    scrn_rect.left + scrn_rect.right,
243                    scrn_rect.top);                    // Bottom box line
244
245       marker_ye  = scrn_rect.top + scrn_rect.bottom / 2;   // Tick point adjust
246                                                       // Bottom arrow
247       drawOneLine( marker_xs, marker_ye,
248                    marker_xs - scrn_rect.bottom / 4, scrn_rect.top);
249       drawOneLine( marker_xs, marker_ye,
250                    marker_xs + scrn_rect.bottom / 4, scrn_rect.top);
251       }
252     if( options & HUDS_BOTTOM) {
253       drawOneLine( scrn_rect.left,
254                    scrn_rect.top + scrn_rect.bottom,
255                    scrn_rect.left + scrn_rect.right,
256                    scrn_rect.top + scrn_rect.bottom);  // Top box line
257                                                        // Tick point adjust
258       marker_ys = scrn_rect.top +
259                   scrn_rect.bottom - scrn_rect.bottom  / 2;
260                                                        // Top arrow
261       drawOneLine( marker_xs + scrn_rect.bottom / 4,
262                           scrn_rect.top + scrn_rect.bottom,
263                    marker_xs,
264                           marker_ys );
265       drawOneLine( marker_xs - scrn_rect.bottom / 4,
266                           scrn_rect.top + scrn_rect.bottom,
267                    marker_xs ,
268                           marker_ys );
269       }
270
271     for( i = (int)vmin; i <= (int)vmax; i++ )   {
272       condition = true;
273       if( !modulo()) {
274         if( i < min_val()) {
275           condition = false;
276           }
277         }
278       if( condition )        {
279         marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
280         if( div_min()){
281           if( (i%(int)div_min()) == 0 ) {
282             // draw in ticks only if they aren't too close to the edge.
283             if((( marker_xs + 5) > scrn_rect.left ) ||
284                (( marker_xs - 5 )< (scrn_rect.left + scrn_rect.right))){
285
286               if( (options & HUDS_BOTH) == HUDS_BOTH ) {
287                 drawOneLine( marker_xs, scrn_rect.top,
288                              marker_xs, marker_ys - 4);
289                 drawOneLine( marker_xs, marker_ye + 4,
290                              marker_xs, scrn_rect.top + scrn_rect.bottom);
291                 }
292               else {
293                 if( options & HUDS_TOP) {
294                   drawOneLine( marker_xs, marker_ys,
295                                marker_xs, marker_ye - 4);
296                   }
297                 else {
298                   drawOneLine( marker_xs, marker_ys + 4,
299                                marker_xs, marker_ye);
300                   }
301                 }
302               }
303             }
304           }
305         if( div_max()) {
306           if( (i%(int)div_max())==0 ) {
307             if(modulo()) {
308               if( disp_val < 0) {
309                 disp_val += modulo();
310                 }
311               else {
312                 disp_val = i % modulo();
313                 }
314               }
315             else {
316               disp_val = i;
317               }
318             sprintf( TextScale, "%d", (int)(disp_val  * data_scaling() +.5));
319             // Draw major ticks and text only if far enough from the edge.
320             if(( (marker_xs - 10)> scrn_rect.left ) &&
321                ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
322               if( (options & HUDS_BOTH) == HUDS_BOTH) {
323                 drawOneLine( marker_xs, scrn_rect.top,
324                              marker_xs, marker_ys);
325                 drawOneLine( marker_xs, marker_ye,
326                              marker_xs, scrn_rect.top + scrn_rect.bottom);
327
328                 if( !(options & HUDS_NOTEXT)) {
329                   textString ( marker_xs - 4 * strlen(TextScale),
330                                marker_ys + 4,
331                                TextScale,  GLUT_BITMAP_8_BY_13 );
332                   }
333                 }
334               else {
335                 drawOneLine( marker_xs, marker_ys,
336                              marker_xs, marker_ye );
337                 if( !(options & HUDS_NOTEXT)) {
338                   if( options & HUDS_TOP )              {
339                   textString ( marker_xs - 4 * strlen(TextScale),
340                                scrn_rect.top + scrn_rect.bottom - 10,
341                                TextScale, GLUT_BITMAP_8_BY_13 );
342                     }
343                   else  {
344                     textString( marker_xs - 4 * strlen(TextScale),
345                                 scrn_rect.top,
346                                 TextScale, GLUT_BITMAP_8_BY_13 );
347                     }            
348                   }
349                 }
350               }
351             }
352           }
353         }
354       }
355     }
356 }
357
358