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