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