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