12 #include <simgear/constants.h>
13 #include <simgear/math/fg_random.h>
14 #include <simgear/math/polar3d.hxx>
16 #include <Aircraft/aircraft.hxx>
18 #include <Scenery/scenery.hxx>
19 #include <Time/fg_timer.hxx>
24 #ifdef USE_HUD_TextList
25 #define textString( x , y, text, font ) TextString( text, x , y )
27 #define textString( x , y, text, font ) puDrawString ( guiFnt, text, x, y );
30 //============== Top of guage_instr class member definitions ==============
47 instr_scale( x, y, width, height,
49 (maxValue - minValue), // Always shows span?
52 major_divs, minor_divs,
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;
73 guage_instr( const guage_instr & image):
74 instr_scale( (instr_scale &) image)
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;
87 guage_instr & guage_instr ::
88 operator = (const guage_instr & rhs )
90 if( !(this == &rhs)) {
91 instr_scale::operator = (rhs);
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.
102 void guage_instr :: draw (void)
104 int marker_xs, marker_xe;
105 int marker_ys, marker_ye;
107 int width, height, bottom_4;
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();
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...
125 if( huds_vert(options) ) { // Vertical scale
126 drawOneLine( scrn_rect.left, // Bottom tick bar
131 drawOneLine( scrn_rect.left, // Top tick bar
136 marker_xs = scrn_rect.left;
139 if( huds_left(options) ) { // Read left, so line down right side
145 marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
148 if( huds_right(options) ) { // Read right, so down left sides
149 drawOneLine( scrn_rect.left,
154 marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
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;
165 // Work through from bottom to top of scale. Calculating where to put
166 // minor and major ticks.
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++ ) {
175 // Calculate the location of this tick
176 marker_ys = scrn_rect.top + FloatToInt((i - vmin) * factor()/* +.5f*/);
178 // We compute marker_ys even though we don't know if we will use
179 // either major or minor divisions. Simpler.
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,
190 if( huds_left(options) ) {
191 drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
194 drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
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
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,
213 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
216 if( !huds_notext(options) ) {
218 sprintf( TextScale, "%d",
219 FloatToInt(disp_val * data_scaling()/*+.5*/ ));
221 lenstr = getStringWidth( TextScale );
223 if( huds_left(options) && huds_right(options) ) {
224 text_x = mid_scr.x - lenstr/2 ;
227 if( huds_left(options) ) {
228 text_x = marker_xs - lenstr;
231 text_x = marker_xe - lenstr;
234 // Now we know where to put the text.
236 textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 );
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
246 text_y = scrn_rect.top + FloatToInt((cur_value - vmin) * factor() /*+.5f*/);
247 // text_x = marker_xs - scrn_rect.left;
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);
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);
263 } // End if VERTICAL SCALE TYPE
264 else { // Horizontal scale by default
265 drawOneLine( scrn_rect.left, // left tick bar
270 drawOneLine( width, // right tick bar
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*/);
279 if( huds_top(options) ) {
280 drawOneLine( scrn_rect.left,
283 scrn_rect.top); // Bottom box line
285 marker_ye = scrn_rect.top + scrn_rect.bottom / 2; // Tick point adjust
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);
293 if( huds_bottom(options) ) {
295 drawOneLine( scrn_rect.left, height, width, height);
297 marker_ys = height - scrn_rect.bottom / 2;
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);
308 int last = (int)vmax + 1; //FloatToInt(vmax)+1;
309 i = (int)vmin; //FloatToInt(vmin);
310 for( ; i <last ; i++ ) {
318 marker_xs = scrn_rect.left + FloatToInt((i - vmin) * factor()/* +.5f*/);
319 // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5f);
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))){
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,
333 if( huds_top(options) ) {
334 drawOneLine( marker_xs, marker_ys,
335 marker_xs, marker_ye - 4);
338 drawOneLine( marker_xs, marker_ys + 4,
339 marker_xs, marker_ye);
346 if( !(i%(int)div_max()) ) {
349 while( disp_val < 0 ) {
350 disp_val += modulo();
353 disp_val = i % (int)modulo();
357 sprintf( TextScale, "%d",
358 FloatToInt(disp_val * data_scaling()/* +.5*/ ));
359 lenstr = getStringWidth( TextScale);
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,
370 if( !huds_notext(options) ) {
371 textString ( marker_xs - lenstr, marker_ys + 4,
372 TextScale, GLUT_BITMAP_8_BY_13 );
376 drawOneLine( marker_xs, marker_ys,
377 marker_xs, marker_ye );
379 if( !huds_notext(options) ) {
380 if( huds_top(options) ) {
381 textString ( marker_xs - lenstr,
383 TextScale, GLUT_BITMAP_8_BY_13 );
386 textString( marker_xs - lenstr, scrn_rect.top,
387 TextScale, GLUT_BITMAP_8_BY_13 );