#ifdef HAVE_CONFIG_H # include <config.h> #endif #ifdef HAVE_WINDOWS_H # include <windows.h> #endif #include <stdlib.h> #include <string.h> #include <Aircraft/aircraft.hxx> #include <Include/fg_constants.h> #include <Math/fg_random.h> #include <Math/mat3.h> #include <Math/polar3d.hxx> #include <Scenery/scenery.hxx> #include <Time/fg_timer.hxx> #include "hud.hxx" //============== Top of guage_instr class member definitions ============== guage_instr :: guage_instr( int x, int y, UINT width, UINT height, DBLFNPTR load_fn, UINT options, double disp_scale, double maxValue, double minValue, UINT major_divs, UINT minor_divs, int dp_showing, UINT modulus, bool working) : instr_scale( x, y, width, height, load_fn, options, (maxValue - minValue), // Always shows span? maxValue, minValue, disp_scale, major_divs, minor_divs, modulus, dp_showing, working) { } guage_instr :: ~guage_instr() { } guage_instr :: guage_instr( const guage_instr & image): instr_scale( (instr_scale &) image) { } guage_instr & guage_instr :: operator = (const guage_instr & rhs ) { if( !(this == &rhs)) { instr_scale::operator = (rhs); } return *this; } // As implemented, draw only correctly draws a horizontal or vertical // scale. It should contain a variation that permits clock type displays. // Now is supports "tickless" displays such as control surface indicators. // This routine should be worked over before using. Current value would be // fetched and not used if not commented out. Clearly that is intollerable. void guage_instr :: draw (void) { int marker_xs, marker_xe; int marker_ys, marker_ye; int text_x, text_y; int i; char TextScale[80]; bool condition; int disp_val; double vmin = min_val(); double vmax = max_val(); POINT mid_scr = get_centroid(); double cur_value = get_value(); RECT scrn_rect = get_location(); UINT options = get_options(); // Draw the basic markings for the scale... if( options & HUDS_VERT ) { // Vertical scale drawOneLine( scrn_rect.left, // Bottom tick bar scrn_rect.top, scrn_rect.left + scrn_rect.right, scrn_rect.top); drawOneLine( scrn_rect.left, // Top tick bar scrn_rect.top + scrn_rect.bottom, scrn_rect.left + scrn_rect.right, scrn_rect.top + scrn_rect.bottom ); marker_xs = scrn_rect.left; marker_xe = scrn_rect.left + scrn_rect.right; if( options & HUDS_LEFT ) { // Read left, so line down right side drawOneLine( scrn_rect.left + scrn_rect.right, scrn_rect.top, scrn_rect.left + scrn_rect.right, scrn_rect.top + scrn_rect.bottom); marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs } if( options & HUDS_RIGHT ) { // Read right, so down left sides drawOneLine( scrn_rect.left, scrn_rect.top, scrn_rect.left, scrn_rect.top + scrn_rect.bottom); marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe } // At this point marker x_start and x_end values are transposed. // To keep this from confusing things they are now interchanged. if(( options & HUDS_BOTH) == HUDS_BOTH) { marker_ye = marker_xs; marker_xs = marker_xe; marker_xe = marker_ye; } // Work through from bottom to top of scale. Calculating where to put // minor and major ticks. if( !(options & HUDS_NOTICKS )) { // If not no ticks...:) // Calculate x marker offsets for( i = (int)vmin; i <= (int)vmax; i++ ) { // Calculate the location of this tick marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5); // We compute marker_ys even though we don't know if we will use // either major or minor divisions. Simpler. if( div_min()) { // Minor tick marks if( (i%div_min()) == 0) { if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) { drawOneLine( scrn_rect.left, marker_ys, marker_xs - 3, marker_ys ); drawOneLine( marker_xe + 3, marker_ys, scrn_rect.left + scrn_rect.right, marker_ys ); } else { if( options & HUDS_LEFT) { drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys ); } else { drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys ); } } } } // Now we work on the major divisions. Since these are also labeled // and no labels are drawn otherwise, we label inside this if // statement. if( div_max()) { // Major tick mark if( (i%div_max()) == 0 ) { if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) { drawOneLine( scrn_rect.left, marker_ys, marker_xs, marker_ys ); drawOneLine( marker_xe, marker_ys, scrn_rect.left + scrn_rect.right, marker_ys ); } else { drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys ); } if( !(options & HUDS_NOTEXT)) { disp_val = i; sprintf( TextScale, "%d",disp_val * (int)(data_scaling() +.5)); if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) { text_x = mid_scr.x - 2 - ((3 * strlen( TextScale ))>>1); } else { if( options & HUDS_LEFT ) { text_x = marker_xs - 2 - 3 * strlen( TextScale); } else { text_x = marker_xe + 10 - strlen( TextScale ); } } // Now we know where to put the text. text_y = marker_ys; textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 ); } } } // } // } // // Now that the scale is drawn, we draw in the pointer(s). Since labels // have been drawn, text_x and text_y may be recycled. This is used // with the marker start stops to produce a pointer for each side reading text_y = scrn_rect.top + (int)((cur_value - vmin) * factor() + .5); // text_x = marker_xs - scrn_rect.left; if( options & HUDS_RIGHT ) { drawOneLine(scrn_rect.left, text_y + 5, marker_xe, text_y); drawOneLine(scrn_rect.left, text_y - 5, marker_xe, text_y); } if( options & HUDS_LEFT ) { drawOneLine(scrn_rect.left + scrn_rect.right, text_y + 5, marker_xs, text_y); drawOneLine(scrn_rect.left + scrn_rect.right, text_y - 5, marker_xs, text_y); } } // End if VERTICAL SCALE TYPE else { // Horizontal scale by default drawOneLine( scrn_rect.left, // left tick bar scrn_rect.top, scrn_rect.left, scrn_rect.top + scrn_rect.bottom); drawOneLine( scrn_rect.left + scrn_rect.right, // right tick bar scrn_rect.top, scrn_rect.left + scrn_rect.right, scrn_rect.top + scrn_rect.bottom ); marker_ys = scrn_rect.top; // Starting point for marker_ye = scrn_rect.top + scrn_rect.bottom; // tick y location calcs marker_xs = scrn_rect.left + (int)((cur_value - vmin) * factor() + .5); if( options & HUDS_TOP ) { drawOneLine( scrn_rect.left, scrn_rect.top, scrn_rect.left + scrn_rect.right, scrn_rect.top); // Bottom box line marker_ye = scrn_rect.top + scrn_rect.bottom / 2; // Tick point adjust // Bottom arrow drawOneLine( marker_xs, marker_ye, marker_xs - scrn_rect.bottom / 4, scrn_rect.top); drawOneLine( marker_xs, marker_ye, marker_xs + scrn_rect.bottom / 4, scrn_rect.top); } if( options & HUDS_BOTTOM) { drawOneLine( scrn_rect.left, scrn_rect.top + scrn_rect.bottom, scrn_rect.left + scrn_rect.right, scrn_rect.top + scrn_rect.bottom); // Top box line // Tick point adjust marker_ys = scrn_rect.top + scrn_rect.bottom - scrn_rect.bottom / 2; // Top arrow drawOneLine( marker_xs + scrn_rect.bottom / 4, scrn_rect.top + scrn_rect.bottom, marker_xs, marker_ys ); drawOneLine( marker_xs - scrn_rect.bottom / 4, scrn_rect.top + scrn_rect.bottom, marker_xs , marker_ys ); } for( i = (int)vmin; i <= (int)vmax; i++ ) { condition = true; if( !modulo()) { if( i < min_val()) { condition = false; } } if( condition ) { marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5); if( div_min()){ if( (i%(int)div_min()) == 0 ) { // draw in ticks only if they aren't too close to the edge. if((( marker_xs + 5) > scrn_rect.left ) || (( marker_xs - 5 )< (scrn_rect.left + scrn_rect.right))){ if( (options & HUDS_BOTH) == HUDS_BOTH ) { drawOneLine( marker_xs, scrn_rect.top, marker_xs, marker_ys - 4); drawOneLine( marker_xs, marker_ye + 4, marker_xs, scrn_rect.top + scrn_rect.bottom); } else { if( options & HUDS_TOP) { drawOneLine( marker_xs, marker_ys, marker_xs, marker_ye - 4); } else { drawOneLine( marker_xs, marker_ys + 4, marker_xs, marker_ye); } } } } } if( div_max()) { if( (i%(int)div_max())==0 ) { if(modulo()) { if( disp_val < 0) { disp_val += modulo(); } else { disp_val = i % modulo(); } } else { disp_val = i; } sprintf( TextScale, "%d", (int)(disp_val * data_scaling() +.5)); // Draw major ticks and text only if far enough from the edge. if(( (marker_xs - 10)> scrn_rect.left ) && ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){ if( (options & HUDS_BOTH) == HUDS_BOTH) { drawOneLine( marker_xs, scrn_rect.top, marker_xs, marker_ys); drawOneLine( marker_xs, marker_ye, marker_xs, scrn_rect.top + scrn_rect.bottom); if( !(options & HUDS_NOTEXT)) { textString ( marker_xs - 4 * strlen(TextScale), marker_ys + 4, TextScale, GLUT_BITMAP_8_BY_13 ); } } else { drawOneLine( marker_xs, marker_ys, marker_xs, marker_ye ); if( !(options & HUDS_NOTEXT)) { if( options & HUDS_TOP ) { textString ( marker_xs - 4 * strlen(TextScale), scrn_rect.top + scrn_rect.bottom - 10, TextScale, GLUT_BITMAP_8_BY_13 ); } else { textString( marker_xs - 4 * strlen(TextScale), scrn_rect.top, TextScale, GLUT_BITMAP_8_BY_13 ); } } } } } } } } } }