11 #include <simgear/constants.h>
12 #include <simgear/fg_random.h>
13 #include <simgear/mat3.h>
14 #include <simgear/polar3d.hxx>
16 #include <Aircraft/aircraft.hxx>
18 #include <Scenery/scenery.hxx>
19 #include <Time/fg_timer.hxx>
23 #ifdef USE_HUD_TextList
24 #define textString( x , y, text, font ) TextString( text, x , y )
26 #define textString( x , y, text, font ) puDrawString ( guiFnt, text, x, y );
29 //========== Top of hud_card class member definitions =============
38 float max_value, // 360
47 instr_scale( x,y,width,height,
50 max_value, min_value, disp_scaling,
51 major_divs, minor_divs, modulus,
53 val_span ( value_span)
55 half_width_units = range_to_show() / 2.0;
56 // UINT options = get_options();
57 // huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
58 // huds_right = options & HUDS_RIGHT;
59 // huds_left = options & HUDS_LEFT;
60 // huds_vert = options & HUDS_VERT;
61 // huds_notext = options & HUDS_NOTEXT;
62 // huds_top = options & HUDS_TOP;
63 // huds_bottom = options & HUDS_BOTTOM;
70 hud_card( const hud_card & image):
71 instr_scale( (const instr_scale & ) image),
72 val_span( image.val_span),
73 half_width_units (image.half_width_units)
75 // UINT options = get_options();
76 // huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
77 // huds_right = options & HUDS_RIGHT;
78 // huds_left = options & HUDS_LEFT;
79 // huds_vert = options & HUDS_VERT;
80 // huds_notext = options & HUDS_NOTEXT;
81 // huds_top = options & HUDS_TOP;
82 // huds_bottom = options & HUDS_BOTTOM;
85 hud_card & hud_card ::
86 operator = (const hud_card & rhs )
88 if( !( this == &rhs)){
89 instr_scale::operator = (rhs);
90 val_span = rhs.val_span;
91 half_width_units = rhs.half_width_units;
97 draw( void ) // (HUD_scale * pscale )
110 POINT mid_scr = get_centroid();
111 float cur_value = get_value();
112 RECT scrn_rect = get_location();
113 UINT options = get_options();
115 height = scrn_rect.top + scrn_rect.bottom;
116 width = scrn_rect.left + scrn_rect.right;
118 vmin = cur_value - half_width_units; // width units == needle travel
119 vmax = cur_value + half_width_units; // or picture unit span.
121 // Draw the basic markings for the scale...
123 if( huds_vert(options) ) { // Vertical scale
124 drawOneLine( scrn_rect.left, // Bottom tick bar
129 drawOneLine( scrn_rect.left, // Top tick bar
134 marker_xs = scrn_rect.left; // x start
135 marker_xe = width; // x extent
138 // glBegin(GL_LINES);
141 // glVertex2f( marker_xs, scrn_rect.top);
142 // glVertex2f( marker_xe, scrn_rect.top);
145 // glVertex2f( marker_xs, marker_ye);
146 // glVertex2f( marker_xe, marker_ye );
149 // We do not use else in the following so that combining the two
150 // options produces a "caged" display with double carrots. The
151 // same is done for horizontal card indicators.
153 if( huds_left(options) ) { // Calculate x marker offset
154 drawOneLine( marker_xe, scrn_rect.top,
155 marker_xe, marker_ye); // Cap right side
157 marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
159 // drawOneLine( marker_xs, mid_scr.y,
160 // marker_xe, mid_scr.y + scrn_rect.right / 6);
161 // drawOneLine( marker_xs, mid_scr.y,
162 // marker_xe, mid_scr.y - scrn_rect.right / 6);
164 glBegin(GL_LINE_STRIP);
165 glVertex2f( marker_xe, mid_scr.y + scrn_rect.right / 6);
166 glVertex2f( marker_xs, mid_scr.y);
167 glVertex2f( marker_xe, mid_scr.y - scrn_rect.right / 6);
170 if( huds_right(options) ) { // We'll default this for now.
171 drawOneLine( scrn_rect.left, scrn_rect.top,
172 scrn_rect.left, marker_ye ); // Cap left side
174 marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
176 // drawOneLine( scrn_rect.left, mid_scr.y + scrn_rect.right / 6,
177 // marker_xe, mid_scr.y );
178 // drawOneLine( scrn_rect.left, mid_scr.y - scrn_rect.right / 6,
179 // marker_xe, mid_scr.y);
180 glBegin(GL_LINE_STRIP);
181 glVertex2f( scrn_rect.left, mid_scr.y + scrn_rect.right / 6);
182 glVertex2f( marker_xe, mid_scr.y );
183 glVertex2f( scrn_rect.left, mid_scr.y - scrn_rect.right / 6);
187 // At this point marker x_start and x_end values are transposed.
188 // To keep this from confusing things they are now interchanged.
189 if(huds_both(options)) {
190 marker_ye = marker_xs;
191 marker_xs = marker_xe;
192 marker_xe = marker_ye;
195 // Work through from bottom to top of scale. Calculating where to put
196 // minor and major ticks.
198 // last = FloatToInt(vmax)+1;
199 // i = FloatToInt(vmin);
200 last = (int)vmax + 1;
202 for( ; i <last ; i++ )
211 if( condition ) { // Show a tick if necessary
212 // Calculate the location of this tick
213 marker_ys = scrn_rect.top + FloatToInt(((i - vmin) * factor()/*+.5f*/));
214 // marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
215 // Block calculation artifact from drawing ticks below min coordinate.
216 // Calculation here accounts for text height.
218 if(( marker_ys < (scrn_rect.top + 4)) |
219 ( marker_ys > (height - 4))) {
224 // if( (i%div_min()) == 0) {
225 if( !(i%(int)div_min())) {
226 if((( marker_ys - 5) > scrn_rect.top ) &&
227 (( marker_ys + 5) < (height))){
228 if( huds_both(options) ) {
229 drawOneLine( scrn_rect.left, marker_ys,
230 marker_xs, marker_ys );
231 drawOneLine( marker_xe, marker_ys,
233 // glBegin(GL_LINES);
234 // glVertex2f( scrn_rect.left, marker_ys );
235 // glVertex2f( marker_xs, marker_ys );
236 // glVertex2f( marker_xe, marker_ys);
237 // glVertex2f( scrn_rect.left + scrn_rect.right, marker_ys );
241 if( huds_left(options) ) {
242 drawOneLine( marker_xs + 4, marker_ys,
243 marker_xe, marker_ys );
246 drawOneLine( marker_xs, marker_ys,
247 marker_xe - 4, marker_ys );
254 if( !(i%(int)div_max()) )
259 disp_val += modulo();
261 // disp_val = i % (int)modulo();
263 disp_val = i % (int) modulo(); // ?????????
268 lenstr = sprintf( TextScale, "%d",
269 FloatToInt(disp_val * data_scaling()/*+.5*/));
270 // (int)(disp_val * data_scaling() +.5));
271 if(( (marker_ys - 8 ) > scrn_rect.top ) &&
272 ( (marker_ys + 8) < (height))){
273 if( huds_both(options) ) {
274 // drawOneLine( scrn_rect.left, marker_ys,
275 // marker_xs, marker_ys);
276 // drawOneLine( marker_xs, marker_ys,
277 // scrn_rect.left + scrn_rect.right,
279 glBegin(GL_LINE_STRIP);
280 glVertex2f( scrn_rect.left, marker_ys );
281 glVertex2f( marker_xs, marker_ys);
282 glVertex2f( width, marker_ys);
284 if( !huds_notext(options)) {
285 textString ( marker_xs + 2, marker_ys,
286 TextScale, GLUT_BITMAP_8_BY_13 );
290 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
291 if( !huds_notext(options) ) {
292 if( huds_left(options) ) {
293 textString( marker_xs - 8 * lenstr - 2,
295 TextScale, GLUT_BITMAP_8_BY_13 );
298 textString( marker_xe + 3 * lenstr,
300 TextScale, GLUT_BITMAP_8_BY_13 );
304 } // Else read oriented right
305 } // End if modulo division by major interval is zero
306 } // End if major interval divisor non-zero
307 } // End if condition
308 } // End for range of i from vmin to vmax
309 } // End if VERTICAL SCALE TYPE
310 else { // Horizontal scale by default
312 drawOneLine( scrn_rect.left, scrn_rect.top,
313 scrn_rect.left, height);
316 drawOneLine( width, scrn_rect.top,
320 marker_ys = scrn_rect.top; // Starting point for
321 marker_ye = height; // tick y location calcs
324 // glBegin(GL_LINES);
326 // glVertex2f( scrn_rect.left, scrn_rect.top);
327 // glVertex2f( scrn_rect.left, marker_ye);
330 // glVertex2f( marker_xe, scrn_rect.top);
331 // glVertex2f( marker_xe, marker_ye );
334 if( huds_top(options) ) {
336 drawOneLine( scrn_rect.left,
342 marker_ye = scrn_rect.top + scrn_rect.bottom / 2;
345 // drawOneLine( mid_scr.x, marker_ye,
346 // mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
347 // drawOneLine( mid_scr.x, marker_ye,
348 // mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
350 glBegin(GL_LINE_STRIP);
351 glVertex2f( mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
352 glVertex2f( mid_scr.x, marker_ye);
353 glVertex2f( mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
356 if( huds_bottom(options) ) {
358 drawOneLine( scrn_rect.left, height,
361 marker_ys = height - scrn_rect.bottom / 2;
364 // drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
365 // scrn_rect.top + scrn_rect.bottom,
366 // mid_scr.x, marker_ys );
367 // drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
368 // scrn_rect.top + scrn_rect.bottom,
369 // mid_scr.x , marker_ys );
370 glBegin(GL_LINE_STRIP);
371 glVertex2f( mid_scr.x + scrn_rect.bottom / 4,
373 glVertex2f( mid_scr.x , marker_ys );
374 glVertex2f( mid_scr.x - scrn_rect.bottom / 4,
379 // if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
380 // marker_xe = marker_ys;
381 // marker_ys = marker_ye;
382 // marker_ye = marker_xe;
385 // printf("vmin = %d vmax = %d\n", (int)vmin, (int)vmax);
387 // last = FloatToInt(vmax)+1;
388 // i = FloatToInt(vmin);
389 last = (int)vmax + 1;
391 for(; i <last ; i++ ) {
392 // for( i = (int)vmin; i <= (int)vmax; i++ ) {
393 // printf("<*> i = %d\n", i);
400 // printf("<**> i = %d\n", i);
402 // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
403 marker_xs = scrn_rect.left + FloatToInt(((i - vmin) * factor()/*+ .5f*/));
405 // if( (i%(int)div_min()) == 0 ) {
406 if( !(i%(int)div_min() )) {
407 // draw in ticks only if they aren't too close to the edge.
408 if((( marker_xs - 5) > scrn_rect.left ) &&
409 (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
411 if( huds_both(options) ) {
412 drawOneLine( marker_xs, scrn_rect.top,
413 marker_xs, marker_ys - 4);
414 drawOneLine( marker_xs, marker_ye + 4,
416 // glBegin(GL_LINES);
417 // glVertex2f( marker_xs, scrn_rect.top);
418 // glVertex2f( marker_xs, marker_ys - 4);
419 // glVertex2f( marker_xs, marker_ye + 4);
420 // glVertex2f( marker_xs, scrn_rect.top + scrn_rect.bottom);
424 if( huds_top(options)) {
425 drawOneLine( marker_xs, marker_ys,
426 marker_xs, marker_ye - 4);
429 drawOneLine( marker_xs, marker_ys + 4,
430 marker_xs, marker_ye);
436 // printf("<***> i = %d\n", i);
438 // printf("i = %d\n", i);
439 // if( (i%(int)div_max())==0 ) {
440 if( !(i%(int)div_max()) ) {
444 disp_val += modulo();
446 disp_val = i % (int) modulo(); // ?????????
450 // printf("disp_val = %d\n", disp_val);
451 // printf("%d\n", (int)(disp_val * (double)data_scaling() + 0.5));
452 lenstr = sprintf( TextScale, "%d",
453 // (int)(disp_val * data_scaling() +.5));
454 FloatToInt(disp_val * data_scaling()/*+.5*/));
455 // Draw major ticks and text only if far enough from the edge.
456 if(( (marker_xs - 10)> scrn_rect.left ) &&
457 ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
458 if( huds_both(options) ) {
459 // drawOneLine( marker_xs, scrn_rect.top,
460 // marker_xs, marker_ys);
461 // drawOneLine( marker_xs, marker_ye,
462 // marker_xs, scrn_rect.top + scrn_rect.bottom);
463 glBegin(GL_LINE_STRIP);
464 glVertex2f( marker_xs, scrn_rect.top);
465 glVertex2f( marker_xs, marker_ye);
466 glVertex2f( marker_xs, height);
468 if( !huds_notext(options) ) {
469 textString ( marker_xs - 4 * lenstr,
471 TextScale, GLUT_BITMAP_8_BY_13 );
475 drawOneLine( marker_xs, marker_ys,
476 marker_xs, marker_ye );
477 if( !huds_notext(options)) {
478 if( huds_top(options) ) {
479 textString ( marker_xs - 4 * lenstr,
481 TextScale, GLUT_BITMAP_8_BY_13 );
484 textString( marker_xs - 4 * lenstr,
486 TextScale, GLUT_BITMAP_8_BY_13 );
493 // printf("<****> i = %d\n", i);