12 #include <simgear/constants.h>
13 #include <simgear/fg_random.h>
14 #include <simgear/mat3.h>
15 #include <simgear/polar3d.hxx>
17 #include <Aircraft/aircraft.hxx>
19 #include <Scenery/scenery.hxx>
20 #include <Time/fg_timer.hxx>
25 #ifdef USE_HUD_TextList
26 #define textString( x , y, text, font ) TextString( text, x , y )
28 #define textString( x , y, text, font ) puDrawString ( guiFnt, text, x, y );
31 //============== Top of guage_instr class member definitions ==============
48 instr_scale( x, y, width, height,
50 (maxValue - minValue), // Always shows span?
53 major_divs, minor_divs,
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;
74 guage_instr( const guage_instr & image):
75 instr_scale( (instr_scale &) image)
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;
88 guage_instr & guage_instr ::
89 operator = (const guage_instr & rhs )
91 if( !(this == &rhs)) {
92 instr_scale::operator = (rhs);
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.
103 void guage_instr :: draw (void)
105 int marker_xs, marker_xe;
106 int marker_ys, marker_ye;
108 int width, height, bottom_4;
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();
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...
126 if( huds_vert(options) ) { // Vertical scale
127 drawOneLine( scrn_rect.left, // Bottom tick bar
132 drawOneLine( scrn_rect.left, // Top tick bar
137 marker_xs = scrn_rect.left;
140 if( huds_left(options) ) { // Read left, so line down right side
146 marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
149 if( huds_right(options) ) { // Read right, so down left sides
150 drawOneLine( scrn_rect.left,
155 marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
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;
166 // Work through from bottom to top of scale. Calculating where to put
167 // minor and major ticks.
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++ ) {
176 // Calculate the location of this tick
177 marker_ys = scrn_rect.top + FloatToInt((i - vmin) * factor()/* +.5f*/);
179 // We compute marker_ys even though we don't know if we will use
180 // either major or minor divisions. Simpler.
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,
191 if( huds_left(options) ) {
192 drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
195 drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
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
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,
214 drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
217 if( !huds_notext(options) ) {
219 sprintf( TextScale, "%d",
220 FloatToInt(disp_val * data_scaling()/*+.5*/ ));
222 lenstr = getStringWidth( TextScale );
224 if( huds_left(options) && huds_right(options) ) {
225 text_x = mid_scr.x - lenstr/2 ;
228 if( huds_left(options) ) {
229 text_x = marker_xs - lenstr;
232 text_x = marker_xe - lenstr;
235 // Now we know where to put the text.
237 textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 );
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
247 text_y = scrn_rect.top + FloatToInt((cur_value - vmin) * factor() /*+.5f*/);
248 // text_x = marker_xs - scrn_rect.left;
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);
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);
264 } // End if VERTICAL SCALE TYPE
265 else { // Horizontal scale by default
266 drawOneLine( scrn_rect.left, // left tick bar
271 drawOneLine( width, // right tick bar
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*/);
280 if( huds_top(options) ) {
281 drawOneLine( scrn_rect.left,
284 scrn_rect.top); // Bottom box line
286 marker_ye = scrn_rect.top + scrn_rect.bottom / 2; // Tick point adjust
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);
294 if( huds_bottom(options) ) {
296 drawOneLine( scrn_rect.left, height, width, height);
298 marker_ys = height - scrn_rect.bottom / 2;
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);
309 int last = (int)vmax + 1; //FloatToInt(vmax)+1;
310 i = (int)vmin; //FloatToInt(vmin);
311 for( ; i <last ; i++ ) {
319 marker_xs = scrn_rect.left + FloatToInt((i - vmin) * factor()/* +.5f*/);
320 // marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5f);
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))){
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,
334 if( huds_top(options) ) {
335 drawOneLine( marker_xs, marker_ys,
336 marker_xs, marker_ye - 4);
339 drawOneLine( marker_xs, marker_ys + 4,
340 marker_xs, marker_ye);
347 if( !(i%(int)div_max()) ) {
350 while( disp_val < 0 ) {
351 disp_val += modulo();
354 disp_val = i % (int)modulo();
358 sprintf( TextScale, "%d",
359 FloatToInt(disp_val * data_scaling()/* +.5*/ ));
360 lenstr = getStringWidth( TextScale);
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,
371 if( !huds_notext(options) ) {
372 textString ( marker_xs - lenstr, marker_ys + 4,
373 TextScale, GLUT_BITMAP_8_BY_13 );
377 drawOneLine( marker_xs, marker_ys,
378 marker_xs, marker_ye );
380 if( !huds_notext(options) ) {
381 if( huds_top(options) ) {
382 textString ( marker_xs - lenstr,
384 TextScale, GLUT_BITMAP_8_BY_13 );
387 textString( marker_xs - lenstr, scrn_rect.top,
388 TextScale, GLUT_BITMAP_8_BY_13 );