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