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