11 #include <simgear/constants.h>
12 #include <simgear/math/fg_random.h>
13 #include <simgear/math/polar3d.hxx>
15 #include <Aircraft/aircraft.hxx>
17 #include <Scenery/scenery.hxx>
18 #include <Time/fg_timer.hxx>
22 #ifdef USE_HUD_TextList
23 #define textString( x , y, text, font ) TextString( text, x , y )
25 #define textString( x , y, text, font ) puDrawString ( guiFnt, text, x, y );
28 //========== Top of hud_card class member definitions =============
37 float max_value, // 360
46 instr_scale( x,y,width,height,
49 max_value, min_value, disp_scaling,
50 major_divs, minor_divs, modulus,
52 val_span ( value_span)
54 half_width_units = range_to_show() / 2.0;
55 // UINT options = get_options();
56 // huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
57 // huds_right = options & HUDS_RIGHT;
58 // huds_left = options & HUDS_LEFT;
59 // huds_vert = options & HUDS_VERT;
60 // huds_notext = options & HUDS_NOTEXT;
61 // huds_top = options & HUDS_TOP;
62 // huds_bottom = options & HUDS_BOTTOM;
69 hud_card( const hud_card & image):
70 instr_scale( (const instr_scale & ) image),
71 val_span( image.val_span),
72 half_width_units (image.half_width_units)
74 // UINT options = get_options();
75 // huds_both = (options & HUDS_BOTH) == HUDS_BOTH;
76 // huds_right = options & HUDS_RIGHT;
77 // huds_left = options & HUDS_LEFT;
78 // huds_vert = options & HUDS_VERT;
79 // huds_notext = options & HUDS_NOTEXT;
80 // huds_top = options & HUDS_TOP;
81 // huds_bottom = options & HUDS_BOTTOM;
84 hud_card & hud_card ::
85 operator = (const hud_card & rhs )
87 if( !( this == &rhs)){
88 instr_scale::operator = (rhs);
89 val_span = rhs.val_span;
90 half_width_units = rhs.half_width_units;
96 draw( void ) // (HUD_scale * pscale )
109 POINT mid_scr = get_centroid();
110 float cur_value = get_value();
111 RECT scrn_rect = get_location();
112 UINT options = get_options();
114 height = scrn_rect.top + scrn_rect.bottom;
115 width = scrn_rect.left + scrn_rect.right;
117 vmin = cur_value - half_width_units; // width units == needle travel
118 vmax = cur_value + half_width_units; // or picture unit span.
120 // Draw the basic markings for the scale...
122 if( huds_vert(options) ) { // Vertical scale
123 drawOneLine( scrn_rect.left, // Bottom tick bar
128 drawOneLine( scrn_rect.left, // Top tick bar
133 marker_xs = scrn_rect.left; // x start
134 marker_xe = width; // x extent
137 // glBegin(GL_LINES);
140 // glVertex2f( marker_xs, scrn_rect.top);
141 // glVertex2f( marker_xe, scrn_rect.top);
144 // glVertex2f( marker_xs, marker_ye);
145 // glVertex2f( marker_xe, marker_ye );
148 // We do not use else in the following so that combining the two
149 // options produces a "caged" display with double carrots. The
150 // same is done for horizontal card indicators.
152 if( huds_left(options) ) { // Calculate x marker offset
153 drawOneLine( marker_xe, scrn_rect.top,
154 marker_xe, marker_ye); // Cap right side
156 marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
158 // drawOneLine( marker_xs, mid_scr.y,
159 // marker_xe, mid_scr.y + scrn_rect.right / 6);
160 // drawOneLine( marker_xs, mid_scr.y,
161 // marker_xe, mid_scr.y - scrn_rect.right / 6);
163 glBegin(GL_LINE_STRIP);
164 glVertex2f( marker_xe, mid_scr.y + scrn_rect.right / 6);
165 glVertex2f( marker_xs, mid_scr.y);
166 glVertex2f( marker_xe, mid_scr.y - scrn_rect.right / 6);
169 if( huds_right(options) ) { // We'll default this for now.
170 drawOneLine( scrn_rect.left, scrn_rect.top,
171 scrn_rect.left, marker_ye ); // Cap left side
173 marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
175 // drawOneLine( scrn_rect.left, mid_scr.y + scrn_rect.right / 6,
176 // marker_xe, mid_scr.y );
177 // drawOneLine( scrn_rect.left, mid_scr.y - scrn_rect.right / 6,
178 // marker_xe, mid_scr.y);
179 glBegin(GL_LINE_STRIP);
180 glVertex2f( scrn_rect.left, mid_scr.y + scrn_rect.right / 6);
181 glVertex2f( marker_xe, mid_scr.y );
182 glVertex2f( scrn_rect.left, mid_scr.y - scrn_rect.right / 6);
186 // At this point marker x_start and x_end values are transposed.
187 // To keep this from confusing things they are now interchanged.
188 if(huds_both(options)) {
189 marker_ye = marker_xs;
190 marker_xs = marker_xe;
191 marker_xe = marker_ye;
194 // Work through from bottom to top of scale. Calculating where to put
195 // minor and major ticks.
197 // last = FloatToInt(vmax)+1;
198 // i = FloatToInt(vmin);
199 last = (int)vmax + 1;
201 for( ; i <last ; i++ )
210 if( condition ) { // Show a tick if necessary
211 // Calculate the location of this tick
212 marker_ys = scrn_rect.top + FloatToInt(((i - vmin) * factor()/*+.5f*/));
213 // marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
214 // Block calculation artifact from drawing ticks below min coordinate.
215 // Calculation here accounts for text height.
217 if(( marker_ys < (scrn_rect.top + 4)) |
218 ( marker_ys > (height - 4))) {
223 // if( (i%div_min()) == 0) {
224 if( !(i%(int)div_min())) {
225 if((( marker_ys - 5) > scrn_rect.top ) &&
226 (( marker_ys + 5) < (height))){
227 if( huds_both(options) ) {
228 drawOneLine( scrn_rect.left, marker_ys,
229 marker_xs, marker_ys );
230 drawOneLine( marker_xe, marker_ys,
232 // glBegin(GL_LINES);
233 // glVertex2f( scrn_rect.left, marker_ys );
234 // glVertex2f( marker_xs, marker_ys );
235 // glVertex2f( marker_xe, marker_ys);
236 // glVertex2f( scrn_rect.left + scrn_rect.right, marker_ys );
240 if( huds_left(options) ) {
241 drawOneLine( marker_xs + 4, marker_ys,
242 marker_xe, marker_ys );
245 drawOneLine( marker_xs, marker_ys,
246 marker_xe - 4, marker_ys );
253 if( !(i%(int)div_max()) )
258 disp_val += modulo();
260 // disp_val = i % (int)modulo();
262 disp_val = i % (int) modulo(); // ?????????
267 lenstr = sprintf( TextScale, "%d",
268 FloatToInt(disp_val * data_scaling()/*+.5*/));
269 // (int)(disp_val * data_scaling() +.5));
270 if(( (marker_ys - 8 ) > scrn_rect.top ) &&
271 ( (marker_ys + 8) < (height))){
272 if( huds_both(options) ) {
273 // drawOneLine( scrn_rect.left, marker_ys,
274 // marker_xs, marker_ys);
275 // drawOneLine( marker_xs, marker_ys,
276 // scrn_rect.left + scrn_rect.right,
278 glBegin(GL_LINE_STRIP);
279 glVertex2f( scrn_rect.left, marker_ys );
280 glVertex2f( marker_xs, marker_ys);
281 glVertex2f( width, marker_ys);
283 if( !huds_notext(options)) {
284 textString ( marker_xs + 2, marker_ys,
285 TextScale, GLUT_BITMAP_8_BY_13 );
289 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
290 if( !huds_notext(options) ) {
291 if( huds_left(options) ) {
292 textString( marker_xs - 8 * lenstr - 2,
294 TextScale, GLUT_BITMAP_8_BY_13 );
297 textString( marker_xe + 3 * lenstr,
299 TextScale, GLUT_BITMAP_8_BY_13 );
303 } // Else read oriented right
304 } // End if modulo division by major interval is zero
305 } // End if major interval divisor non-zero
306 } // End if condition
307 } // End for range of i from vmin to vmax
308 } // End if VERTICAL SCALE TYPE
309 else { // Horizontal scale by default
311 drawOneLine( scrn_rect.left, scrn_rect.top,
312 scrn_rect.left, height);
315 drawOneLine( width, scrn_rect.top,
319 marker_ys = scrn_rect.top; // Starting point for
320 marker_ye = height; // tick y location calcs
323 // glBegin(GL_LINES);
325 // glVertex2f( scrn_rect.left, scrn_rect.top);
326 // glVertex2f( scrn_rect.left, marker_ye);
329 // glVertex2f( marker_xe, scrn_rect.top);
330 // glVertex2f( marker_xe, marker_ye );
333 if( huds_top(options) ) {
335 drawOneLine( scrn_rect.left,
341 marker_ye = scrn_rect.top + scrn_rect.bottom / 2;
344 // drawOneLine( mid_scr.x, marker_ye,
345 // mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
346 // drawOneLine( mid_scr.x, marker_ye,
347 // mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
349 glBegin(GL_LINE_STRIP);
350 glVertex2f( mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
351 glVertex2f( mid_scr.x, marker_ye);
352 glVertex2f( mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
355 if( huds_bottom(options) ) {
357 drawOneLine( scrn_rect.left, height,
360 marker_ys = height - scrn_rect.bottom / 2;
363 // drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
364 // scrn_rect.top + scrn_rect.bottom,
365 // mid_scr.x, marker_ys );
366 // drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
367 // scrn_rect.top + scrn_rect.bottom,
368 // mid_scr.x , marker_ys );
369 glBegin(GL_LINE_STRIP);
370 glVertex2f( mid_scr.x + scrn_rect.bottom / 4,
372 glVertex2f( mid_scr.x , marker_ys );
373 glVertex2f( mid_scr.x - scrn_rect.bottom / 4,
378 // if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
379 // marker_xe = marker_ys;
380 // marker_ys = marker_ye;
381 // marker_ye = marker_xe;
384 // printf("vmin = %d vmax = %d\n", (int)vmin, (int)vmax);
386 // last = FloatToInt(vmax)+1;
387 // i = FloatToInt(vmin);
388 last = (int)vmax + 1;
390 for(; i <last ; i++ ) {
391 // for( i = (int)vmin; i <= (int)vmax; i++ ) {
392 // printf("<*> i = %d\n", i);
399 // printf("<**> i = %d\n", i);
401 // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
402 marker_xs = scrn_rect.left + FloatToInt(((i - vmin) * factor()/*+ .5f*/));
404 // if( (i%(int)div_min()) == 0 ) {
405 if( !(i%(int)div_min() )) {
406 // draw in ticks only if they aren't too close to the edge.
407 if((( marker_xs - 5) > scrn_rect.left ) &&
408 (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
410 if( huds_both(options) ) {
411 drawOneLine( marker_xs, scrn_rect.top,
412 marker_xs, marker_ys - 4);
413 drawOneLine( marker_xs, marker_ye + 4,
415 // glBegin(GL_LINES);
416 // glVertex2f( marker_xs, scrn_rect.top);
417 // glVertex2f( marker_xs, marker_ys - 4);
418 // glVertex2f( marker_xs, marker_ye + 4);
419 // glVertex2f( marker_xs, scrn_rect.top + scrn_rect.bottom);
423 if( huds_top(options)) {
424 drawOneLine( marker_xs, marker_ys,
425 marker_xs, marker_ye - 4);
428 drawOneLine( marker_xs, marker_ys + 4,
429 marker_xs, marker_ye);
435 // printf("<***> i = %d\n", i);
437 // printf("i = %d\n", i);
438 // if( (i%(int)div_max())==0 ) {
439 if( !(i%(int)div_max()) ) {
443 disp_val += modulo();
445 disp_val = i % (int) modulo(); // ?????????
449 // printf("disp_val = %d\n", disp_val);
450 // printf("%d\n", (int)(disp_val * (double)data_scaling() + 0.5));
451 lenstr = sprintf( TextScale, "%d",
452 // (int)(disp_val * data_scaling() +.5));
453 FloatToInt(disp_val * data_scaling()/*+.5*/));
454 // Draw major ticks and text only if far enough from the edge.
455 if(( (marker_xs - 10)> scrn_rect.left ) &&
456 ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
457 if( huds_both(options) ) {
458 // drawOneLine( marker_xs, scrn_rect.top,
459 // marker_xs, marker_ys);
460 // drawOneLine( marker_xs, marker_ye,
461 // marker_xs, scrn_rect.top + scrn_rect.bottom);
462 glBegin(GL_LINE_STRIP);
463 glVertex2f( marker_xs, scrn_rect.top);
464 glVertex2f( marker_xs, marker_ye);
465 glVertex2f( marker_xs, height);
467 if( !huds_notext(options) ) {
468 textString ( marker_xs - 4 * lenstr,
470 TextScale, GLUT_BITMAP_8_BY_13 );
474 drawOneLine( marker_xs, marker_ys,
475 marker_xs, marker_ye );
476 if( !huds_notext(options)) {
477 if( huds_top(options) ) {
478 textString ( marker_xs - 4 * lenstr,
480 TextScale, GLUT_BITMAP_8_BY_13 );
483 textString( marker_xs - 4 * lenstr,
485 TextScale, GLUT_BITMAP_8_BY_13 );
492 // printf("<****> i = %d\n", i);