From: curt Date: Fri, 3 Jul 1998 13:16:27 +0000 (+0000) Subject: Added Charlie Hotchkiss's HUD updates and improvementes. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=3a6278c4e0c5fc4738923a7125cbf065fb922a7b;p=flightgear.git Added Charlie Hotchkiss's HUD updates and improvementes. --- diff --git a/Cockpit/Makefile.am b/Cockpit/Makefile.am index 865b64f6b..4f16955e6 100644 --- a/Cockpit/Makefile.am +++ b/Cockpit/Makefile.am @@ -3,6 +3,8 @@ noinst_LIBRARIES = libCockpit.a libCockpit_a_SOURCES = \ cockpit.cxx cockpit.hxx \ hud.cxx hud.hxx \ + hud_card.cxx hud_dnst.cxx hud_guag.cxx hud_inst.cxx \ + hud_labl.cxx hud_ladr.cxx hud_scal.cxx hud_tbi.cxx \ panel.cxx panel.hxx INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator diff --git a/Cockpit/hud.cxx b/Cockpit/hud.cxx index 6dc3a86e6..27ed4b5e1 100644 --- a/Cockpit/hud.cxx +++ b/Cockpit/hud.cxx @@ -52,6 +52,12 @@ #include "hud.hxx" +#ifdef __sun__ +extern "C" { + extern void *memmove(void *, const void *, size_t); +} +#endif + // The following routines obtain information concerntin the aircraft's // current state and return it to calling instrument display routines. @@ -59,37 +65,8 @@ // //using namespace std; - -/* - -class instr_ptr { - private: - instr_item *pHI; - - public: - instr_ptr ( instr_item * pHudInstr = 0) : pHI( pHudInstr){} - ~instr_ptr() { if( pHI ) delete pHI; } - instr_ptr & operator = (const instr_ptr & rhs); - instr_ptr( const instr_ptr & image ); -} - -instr_ptr & -instr_ptr :: -operator = ( const instr_ptr & rhs ) -{ - if( !(this == &rhs )) { - pHI = new instr_item( *(rhs.pHI)); - } - return *this; -} - -instr_ptr :: -instr_ptr ( const instr_ptr & image ) : -{ - pHI = new instr_item( *(image.pHI)); -} -*/ -deque< instr_item * > HUD_deque; + + deque< instr_item * > HUD_deque; class locRECT { public: @@ -109,10 +86,6 @@ locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom) } // #define DEBUG -// #define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES); -// glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd(); -// - void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2) { glBegin(GL_LINES); @@ -134,8 +107,7 @@ void drawOneLine( RECT &rect) // /* textString - Bitmap font string */ -static void textString(int x, int y, char *msg, void *font) -{ +void textString( int x, int y, char *msg, void *font ){ glRasterPos2f(x, y); while (*msg) { glutBitmapCharacter(font, *msg); @@ -144,1325 +116,24 @@ static void textString(int x, int y, char *msg, void *font) } /* strokeString - Stroke font string */ -/* -static void strokeString(int x, int y, char *msg, void *font) + +void strokeString(int x, int y, char *msg, void *font, float theta) { +int xx; +int yy; + glPushMatrix(); - glTranslatef(x, y, 0); - glScalef(.04, .04, .04); + glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0); + xx = x * cos(theta) + y * sin( theta ); + yy = y * cos(theta) - x * sin( theta ); + glTranslatef( xx, yy, 0); + glScalef(.1, .1, 0.0); while (*msg) { glutStrokeCharacter(font, *msg); msg++; } glPopMatrix(); } -*/ - - - -// Abstract Base Class instr_item -// -UINT instr_item :: instances; // Initial value of zero - -// constructor ( No default provided ) - -instr_item :: - instr_item( RECT scr_pos, - DBLFNPTR data_source, - ReadOriented orientation, - bool working) : - handle ( ++instances ), - scrn_pos ( scr_pos ), - load_value_fn ( data_source ), - oriented ( orientation ), - is_enabled ( working ), - broken ( FALSE ), - brightness ( BRT_DARK ) -{ -int hitemp, widetemp; -int xtemp; - - // Check for inverted rect coords. We must have top/right > bottom - // left corners or derived classes will draw their boxes very oddly. - // This is the only place we can reliably validate this data. Note - // that the box may be entirely or partly located off the screen. - // This needs consideration and possibly a member function to move - // the box, a keen idea for supporting "editing" of the HUD. - if( scrn_pos.top < scrn_pos.bottom ) { - xtemp = scrn_pos.bottom; - scrn_pos.bottom = scrn_pos.top; - scrn_pos.top = xtemp; - } - if( scrn_pos.left > scrn_pos.right ) { - xtemp = scrn_pos.left; - scrn_pos.left = scrn_pos.right; - scrn_pos.right = xtemp; - } - - // Insure that the midpoint marker will fall exactly at the - // middle of the bar. - if( !((scr_pos.top-scr_pos.bottom) % 2)) { - scrn_pos.top++; - } - if( !((scr_pos.right - scr_pos.left ) % 2)) { - scrn_pos.right++; - } - // Set up convenience values for centroid of the box and - // the span values according to orientation - - hitemp = scr_pos.top - scr_pos.bottom; - widetemp = scr_pos.right - scr_pos.left; - if((orientation == ReadTOP) || (orientation == ReadBOTTOM)) { - scr_span = widetemp; - } - else { - scr_span = hitemp; - } - // Here we work out the centroid for the corrected box. - mid_span.x = scr_pos.left + ((scr_pos.right - scr_pos.left) >> 1); - mid_span.y = scr_pos.bottom + ((scr_pos.top - scr_pos.bottom) >> 1); -} - -// copy constructor -instr_item :: - instr_item ( const instr_item & image ): - handle ( ++instances ), - scrn_pos ( image.scrn_pos ), - load_value_fn( image.load_value_fn), - oriented ( image.oriented ), - is_enabled ( image.is_enabled ), - broken ( image.broken ), - brightness ( image.brightness ), - scr_span ( image.scr_span ), - mid_span ( image.mid_span ) -{ -} - -// assignment operator - -instr_item & instr_item :: operator = ( const instr_item & rhs ) -{ - if( !(this == &rhs )) { // Not an identity assignment - scrn_pos = rhs.scrn_pos; - load_value_fn = rhs.load_value_fn; - oriented = rhs.oriented; - is_enabled = rhs.is_enabled; - broken = rhs.broken; - brightness = rhs.brightness; - } - return *this; -} - -// destructor - -instr_item :: ~instr_item () -{ - if( instances ) { - instances--; - } -} - -void instr_item :: - update( void ) -{ -} - -// break_display This is emplaced to provide hooks for making -// instruments unreliable. The default behavior is -// to simply not display, but more sophisticated behavior is available -// by over riding the function which is virtual in this class. - -void instr_item :: - break_display ( bool bad ) -{ - broken = !!bad; - is_enabled = FALSE; -} - -void instr_item :: - SetBrightness ( int level ) -{ - brightness = level; // This is all we will do for now. Later the - // brightness levels will be sensitive both to - // the control knob and the outside light levels - // to emulated night vision effects. -} - -UINT instr_item :: get_Handle( void ) -{ - return handle; -} - -//======================= Top of instr_label class ========================= -instr_label :: - instr_label( RECT region, - DBLFNPTR data_source, - const char *label_format, - const char *pre_label_string, - const char *post_label_string, - ReadOriented orientation, - fgLabelJust justification, - int font_size, - int blinking, - bool working ): - instr_item( region, data_source, - orientation, working ), - pformat ( label_format ), - pre_str ( pre_label_string ), - post_str ( post_label_string ), - justify ( justification ), - fontSize ( font_size ), - blink ( blinking ) -{ -} - -// I put this in to make it easy to construct a class member using the current -// C code. - - -instr_label :: ~instr_label() -{ -} - -// Copy constructor -instr_label :: instr_label( const instr_label & image) : - instr_item((const instr_item &)image), - pformat ( image.pformat ), - pre_str ( image.pre_str ), - post_str ( image.post_str ), - blink ( image.blink ) -{ -} - -instr_label & instr_label ::operator = (const instr_label & rhs ) -{ - if( !(this == &rhs)) { - instr_item::operator = (rhs); - pformat = rhs.pformat; - fontSize = rhs.fontSize; - blink = rhs.blink; - justify = rhs.justify; - pre_str = rhs.pre_str; - post_str = rhs.post_str; - } - return *this; -} - - -// -// draw Draws a label anywhere in the HUD -// -// -void instr_label :: -draw( void ) // Required method in base class -{ - char format_buffer[80]; - char label_buffer[80]; - int posincr; - int lenstr; - RECT scrn_rect = get_location(); - - if( pre_str != NULL) { - if( post_str != NULL ) { - sprintf( format_buffer, "%s%s%s", pre_str, pformat, post_str ); - } - else { - sprintf( format_buffer, "%s%s", pre_str, pformat ); - } - } - else { - if( post_str != NULL ) { - sprintf( format_buffer, "%s%s", pformat, post_str ); - } - } // else do nothing if both pre and post strings are nulls. Interesting. - - sprintf( label_buffer, format_buffer, get_value() ); -#ifdef DEBUGHUD - fgPrintf( FG_COCKPIT, FG_DEBUG, format_buffer ); - fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" ); - fgPrintf( FG_COCKPIT, FG_DEBUG, label_buffer ); - fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" ); -#endif - lenstr = strlen( label_buffer ); - - posincr = 0; // default to RIGHT_JUST ... center located calc: -lenstr*8; - - if( justify == CENTER_JUST ) { - posincr = - (lenstr << 2); // -lenstr*4; - } - else { - if( justify == LEFT_JUST ) { - posincr = - (lenstr << 8); // 0; - } - } - - if( fontSize == SMALL ) { - textString( scrn_rect.left + posincr, scrn_rect.bottom, - label_buffer, GLUT_BITMAP_8_BY_13); - } - else { - if( fontSize == LARGE ) { - textString( scrn_rect.left + posincr, scrn_rect.bottom, - label_buffer, GLUT_BITMAP_9_BY_15); - } - } -} - -//============== Top of instr_scale class memeber definitions =============== -// -// Notes: -// 1. instr_scales divide the specified location into half and then -// the half opposite the read direction in half again. A bar is -// then drawn along the second divider. Scale ticks are drawn -// between the middle and quarter section lines (minor division -// markers) or just over the middle line. -// -// 2. This class was not intended to be instanciated. See moving_scale -// and guage_instr classes. -//============================================================================ -instr_scale :: -instr_scale ( RECT the_box, - DBLFNPTR load_fn, - ReadOriented orient, - int show_range, - int maxValue, - int minValue, - UINT major_divs, - UINT minor_divs, - UINT rollover, - bool working ) : - instr_item( the_box, load_fn, orient, working), - range_shown ( show_range ), - Maximum_value( maxValue ), - Minimum_value( minValue ), - Maj_div ( major_divs ), - Min_div ( minor_divs ), - Modulo ( rollover ) -{ -int temp; - - scale_factor = (double)get_span() / range_shown; - if( show_range < 0 ) { - range_shown = -range_shown; - } - temp = (Maximum_value - Minimum_value) / 100; - if( range_shown < temp ) { - range_shown = temp; - } -} - -instr_scale :: - instr_scale( const instr_scale & image ) : - instr_item( (const instr_item &) image), - range_shown ( image.range_shown ), - Maximum_value( image.Maximum_value ), - Minimum_value( image.Minimum_value ), - Maj_div ( image.Maj_div ), - Min_div ( image.Min_div ), - Modulo ( image.Modulo ), - scale_factor ( image.scale_factor ) -{ -} - -instr_scale & instr_scale :: operator = (const instr_scale & rhs ) -{ - if( !(this == &rhs)) { - instr_item::operator = (rhs); - Minimum_value = rhs.Minimum_value; - Maximum_value = rhs.Maximum_value; - Maj_div = rhs.Maj_div; - Min_div = rhs.Min_div; - Modulo = rhs.Modulo; - scale_factor = rhs.scale_factor; - range_shown = rhs.range_shown; - } - return *this; -} - -instr_scale :: ~ instr_scale () {} - -//========== Top of moving_scale_instr class member definitions ============= - -moving_scale :: -moving_scale( RECT the_box, - DBLFNPTR data_source, - ReadOriented orientation, - int max_value, - int min_value, - UINT major_divs, - UINT minor_divs, - UINT modulus, - double value_span, - bool working) : - instr_scale( the_box, - data_source, orientation, - (int)value_span, - max_value, min_value, - major_divs, minor_divs, modulus, - working), - val_span ( value_span) -{ - half_width_units = range_to_show() / 2.0; -} - -moving_scale :: -~moving_scale() { } - -moving_scale :: -moving_scale( const moving_scale & image): - instr_scale( (const instr_scale & ) image) -{ -} - -moving_scale & moving_scale :: -operator = (const moving_scale & rhs ) -{ - if( !( this == &rhs)){ - instr_scale::operator = (rhs); - } - return *this; -} - -void moving_scale :: -draw( void ) // (HUD_scale * pscale ) -{ - double vmin, vmax; - int marker_x; - int marker_y; - register i; - char TextScale[80]; - int condition; - int disp_val; - POINT mid_scr = get_centroid(); - POINT bias_bar; // eliminates some orientation checks - double cur_value = get_value(); - RECT scrn_rect = get_location(); - ReadOriented orientation = get_orientation(); - - vmin = cur_value - half_width_units; // width units == needle travel - vmax = cur_value + half_width_units; // or picture unit span. - - - if( (orientation == ReadLEFT) ||( orientation == ReadRIGHT)) // Vertical scale - { - if( orientation == ReadLEFT ) { // Calculate x marker offset - marker_x = scrn_rect.left - 6; - bias_bar.x = ((scrn_rect.right - mid_scr.x)>>1) + mid_scr.x; - } - else { // We'll default this for now. - marker_x = mid_scr.x; // scrn_rect.right; - bias_bar.x = ((mid_scr.x - scrn_rect.left)>>1) + scrn_rect.left; - } - - // Draw the basic markings for the scale... - - drawOneLine( bias_bar.x, // Vertical scale bar - scrn_rect.bottom, - bias_bar.x, - scrn_rect.top ); - - - if( orientation == ReadLEFT ) - { - - drawOneLine( bias_bar.x, // Bottom tick bar - scrn_rect.bottom, - mid_scr.x, - scrn_rect.bottom ); - - drawOneLine( bias_bar.x, // Top tick bar - scrn_rect.top, - mid_scr.x, - scrn_rect.top ); - - drawOneLine( scrn_rect.right, // Middle tick bar /Index - mid_scr.y, - bias_bar.x, - mid_scr.y ); - - } - else { // ReadRight - drawOneLine( bias_bar.x, - scrn_rect.bottom, - mid_scr.x, - scrn_rect.bottom ); - - drawOneLine( bias_bar.x, - scrn_rect.top, - mid_scr.x, - scrn_rect.top ); - - drawOneLine( scrn_rect.left, - mid_scr.y, - bias_bar.x, - mid_scr.y ); - } - - // Work through from bottom to top of scale. Calculating where to put - // minor and major ticks. - - for( i = (int)vmin; i <= (int)vmax; i++ ) - { -// if( sub_type == LIMIT ) { // Don't show ticks - condition = (i >= min_val()); // below Minimum value. -// } -// else { -// if( sub_type == NOLIMIT ) { -// condition = 1; -// } -// } - if( condition ) // Show a tick if necessary - { - // Calculate the location of this tick - marker_y = scrn_rect.bottom + (int)((i - vmin) * factor()); - - // Block calculation artifact from drawing ticks below min coordinate. - // Calculation here accounts for text height. - - if( marker_y < (scrn_rect.bottom + 4)) { // Magic number!!! - continue; - } - if( div_min()) { - if( (i%div_min()) == 0) { -// if( orientation == ReadLEFT ) -// { -// drawOneLine( marker_x + 3, marker_y, marker_x + 6, marker_y ); - drawOneLine( bias_bar.x, marker_y, mid_scr.x, marker_y ); -// } -// else { -// if( orientation == ReadRIGHT ) -// { -// drawOneLine( marker_x, marker_y, marker_x + 3, marker_y ); -// drawOneLine( bias_bar.x, marker_y, mid_scr.x, marker_y ); -// } -// } - } - } - if( div_max()) { - if( (i%div_max()) == 0 ) { -// drawOneLine( marker_x, marker_y, -// marker_x + 6, marker_y ); - if(modulo()) { - disp_val = i % modulo(); - if( disp_val < 0) { - disp_val += modulo(); - } - } - else { - disp_val = i; - } - sprintf( TextScale, "%d", disp_val ); - if( orientation == ReadLEFT ) { - drawOneLine( mid_scr.x - 3, marker_y, bias_bar.x, marker_y ); - - textString( marker_x - 8 * strlen(TextScale) - 2, marker_y - 4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - else { - drawOneLine( mid_scr.x + 3, marker_y, bias_bar.x, marker_y ); - textString( marker_x + 10, marker_y - 4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } // Else read oriented right - } // End if modulo division by major interval is zero - } // End if major interval divisor non-zero - } // End if condition - } // End for range of i from vmin to vmax - } // End if VERTICAL SCALE TYPE - else { // Horizontal scale by default - { - if( orientation == ReadTOP ) { - bias_bar.y = ((mid_scr.y - scrn_rect.bottom)>>1 ) + scrn_rect.bottom; - marker_y = bias_bar.y; // Don't use now - } - else { // We will assume no other possibility at this time. - bias_bar.y = ((scrn_rect.top - mid_scr.y)>>1 ) + mid_scr.y; - marker_y = bias_bar.y; // Don't use now - } - - drawOneLine( scrn_rect.left, - bias_bar.y, - scrn_rect.right, - bias_bar.y ); - - if( orientation == ReadTOP ) - { - drawOneLine( scrn_rect.left, - bias_bar.y, - scrn_rect.left, - mid_scr.y); - - drawOneLine( scrn_rect.right, - bias_bar.y, - scrn_rect.right, - mid_scr.y ); - - drawOneLine( mid_scr.x, - scrn_rect.bottom, - mid_scr.x, - bias_bar.y ); - - } - else { - if( orientation == ReadBOTTOM ) - { - drawOneLine( scrn_rect.left, - bias_bar.y, - scrn_rect.left, - mid_scr.y ); - - drawOneLine( scrn_rect.right, - bias_bar.y, - scrn_rect.right, - mid_scr.y ); - - drawOneLine( mid_scr.x, - scrn_rect.top, - mid_scr.x, - bias_bar.y ); - } - } - - for( i = (int)vmin; i <= (int)vmax; i++ ) // increment is faster than addition - { -// if( sub_type == LIMIT ) { - condition = (i >= min_val()); -// } -// else { -// if( sub_type == NOLIMIT ) { -// condition = 1; -// } -// } - if( condition ) { - marker_x = scrn_rect.left + (int)((i - vmin) * factor()); - if( div_min()){ - if( (i%(int)div_min()) == 0 ) { -// if( orientation == ReadTOP ) -// { -// drawOneLine( marker_x, marker_y, marker_x, marker_y + 3 ); - drawOneLine( marker_x, bias_bar.y, marker_x, mid_scr.y ); -// } -// else { -// drawOneLine( marker_x, marker_y + 3, marker_x, marker_y + 6 ); -// drawOneLine( marker_x, bias_bar.y, marker_x, mid_scr.y ); -// } - } - } - if( div_max()) { - if( (i%(int)div_max())==0 ) - { - if(modulo()) { - disp_val = i % modulo(); - if( disp_val < 0) { - disp_val += modulo(); - } - } - else { - disp_val = i; - } - sprintf( TextScale, "%d", disp_val ); - if( orientation == ReadTOP ) - { -// drawOneLine( marker_x, marker_y, marker_x, marker_y+6 ); - drawOneLine( marker_x, mid_scr.y + 3,marker_x, bias_bar.y ); - textString ( marker_x - 4 * strlen(TextScale), marker_y + 14, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - else { -// drawOneLine( marker_x, marker_y, marker_x, marker_y+6 ); - drawOneLine( marker_x, mid_scr.y - 3,marker_x, bias_bar.y ); - textString ( marker_x - 4 * strlen(TextScale), mid_scr.y - 14, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - } - } - } - } - } - } -} - -//============== Top of guage_instr class member definitions ============== - -guage_instr :: - guage_instr( RECT the_box, - DBLFNPTR load_fn, - ReadOriented readway, - int maxValue, - int minValue, - UINT major_divs, - UINT minor_divs, - UINT modulus, - bool working) : - instr_scale( the_box, - load_fn, readway, - maxValue, maxValue, minValue, - major_divs, minor_divs, - modulus, - 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_x; - int marker_y; - register i; - char TextScale[80]; -// int 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(); - ReadOriented orientation = get_orientation(); - - if( (orientation == ReadLEFT) ||( orientation == ReadRIGHT)) // Vertical scale - { - mid_scr = get_centroid(); - if( orientation == ReadLEFT ) // Calculate x marker offset - marker_x = scrn_rect.left - 6; - else // We'll default this for now. - marker_x = scrn_rect.right; - - // Draw the basic markings for the scale... - - if( orientation == ReadLEFT ) - { - - drawOneLine( scrn_rect.right - 3, // Bottom tick bar - scrn_rect.bottom, - scrn_rect.right, - scrn_rect.bottom ); - - drawOneLine( scrn_rect.right - 3, // Top tick bar - scrn_rect.top, - scrn_rect.right, - scrn_rect.top ); - } - else { - drawOneLine( scrn_rect.right, - scrn_rect.bottom, - scrn_rect.right+3, - scrn_rect.bottom ); - - drawOneLine( scrn_rect.right, - scrn_rect.top, - scrn_rect.right+3, - scrn_rect.top ); - } - - // Work through from bottom to top of scale. Calculating where to put - // minor and major ticks. - - for( i = (int)vmin; i <= (int)vmax; i++ ) - { - // Calculate the location of this tick - marker_y = scrn_rect.bottom + (int)((i - vmin) * factor()); - - if( div_min()) { - if( (i%div_min()) == 0) { - if( orientation == ReadLEFT ) - { - drawOneLine( marker_x + 3, marker_y, marker_x + 6, marker_y ); - } - else { - drawOneLine( marker_x, marker_y, marker_x + 3, marker_y ); - } - } - } - if( div_max()) { - if( (i%div_max()) == 0 ) { - drawOneLine( marker_x, marker_y, - marker_x + 6, marker_y ); - if(modulo()) { - disp_val = i % modulo(); - if( disp_val < 0) { - disp_val += modulo(); - } - } - else { - disp_val = i; - } - sprintf( TextScale, "%d", disp_val ); - if( orientation == ReadLEFT ) { - textString( marker_x - 8 * strlen(TextScale) - 2, marker_y - 4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - else { - if( orientation == ReadRIGHT ) { - textString( marker_x + 10, marker_y - 4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - } - } - } // End if condition - } // End for range of i from vmin to vmax - } // End if VERTICAL SCALE TYPE - else { // Horizontal scale by default - { - if( orientation == ReadTOP ) { - marker_y = scrn_rect.bottom; - } - else { - if( orientation == ReadBOTTOM ) { - marker_y = scrn_rect.bottom - 6; - } - } - drawOneLine( scrn_rect.left, - scrn_rect.bottom, - scrn_rect.right, - scrn_rect.bottom ); - - if( orientation == ReadTOP ) - { - drawOneLine( scrn_rect.left, - scrn_rect.bottom, - scrn_rect.left, - scrn_rect.bottom + 3 ); - - drawOneLine( scrn_rect.right, - scrn_rect.bottom, - scrn_rect.right, - scrn_rect.bottom + 6 ); - } - else { - if( orientation == ReadBOTTOM ) - { - drawOneLine( scrn_rect.left, - scrn_rect.bottom, - scrn_rect.left, - scrn_rect.bottom - 6 ); - - drawOneLine( scrn_rect.right, - scrn_rect.bottom, - scrn_rect.right, - scrn_rect.bottom - 6 ); - } - } - - for( i = (int)vmin; i <= (int)vmax; i++ ) // increment is faster than addition - { - marker_x = scrn_rect.left + (int)((i - vmin) * factor()); - if( div_min()) { - if( (i%div_min()) == 0 ) { - if( orientation == ReadTOP ) - { - drawOneLine( marker_x, marker_y, marker_x, marker_y + 3 ); - } - else { - if( orientation == ReadBOTTOM ) - { - drawOneLine( marker_x, marker_y + 3, marker_x, marker_y + 6 ); - } - } - } // End if minor tick called for. - } // End if minor ticks are of interest - if( div_max()) { - if( (i%div_max())==0 ) - { - // Modulo implies a "clock" style instrument. Needs work. - if(modulo()) { - disp_val = i % modulo(); - if( disp_val < 0) { - disp_val += modulo(); - } - } - else { // Scale doesn't roll around. - disp_val = i; - } - sprintf( TextScale, "%d", disp_val ); - if( orientation == ReadTOP ) - { - drawOneLine( marker_x, marker_y, marker_x, marker_y+6 ); - textString ( marker_x - 4 * strlen(TextScale), marker_y + 14, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - else { - if( orientation == ReadBOTTOM ) - { - drawOneLine( marker_x, marker_y, marker_x, marker_y+6 ); - textString ( marker_x - 4 * strlen(TextScale), marker_y - 14, - TextScale, GLUT_BITMAP_8_BY_13 ); - } // End if bottom - } // End else if not ReadTOP - } // End if major division point. - } // End if major divisions of interest. - } - } - } -} - -//============ Top of dual_instr_item class member definitions ============ - -dual_instr_item :: - dual_instr_item ( RECT the_box, - DBLFNPTR chn1_source, - DBLFNPTR chn2_source, - bool working, - ReadOriented readway ): - instr_item( the_box, chn1_source, readway, working), - alt_data_source( chn2_source ) -{ -} - -dual_instr_item :: - dual_instr_item( const dual_instr_item & image) : - instr_item ((instr_item &) image ), - alt_data_source( image.alt_data_source) -{ -} - -dual_instr_item & dual_instr_item :: - operator = (const dual_instr_item & rhs ) -{ - if( !(this == &rhs)) { - instr_item::operator = (rhs); - alt_data_source = rhs.alt_data_source; - } - return *this; -} - -//============ Top of fgTBI_instr class member definitions ============== - -fgTBI_instr :: -fgTBI_instr( RECT the_box, - DBLFNPTR chn1_source, - DBLFNPTR chn2_source, - UINT maxBankAngle, - UINT maxSlipAngle, - UINT gap_width, - bool working ) : - dual_instr_item( the_box, - chn1_source, - chn2_source, - working, - ReadTOP), - BankLimit (maxBankAngle), - SlewLimit (maxSlipAngle), - scr_hole (gap_width ) -{ -} - -fgTBI_instr :: ~fgTBI_instr() {} - -fgTBI_instr :: fgTBI_instr( const fgTBI_instr & image): - dual_instr_item( (const dual_instr_item &) image), - BankLimit( image.BankLimit), - SlewLimit( image.SlewLimit), - scr_hole ( image.scr_hole ) -{ -} - -fgTBI_instr & fgTBI_instr :: -operator = (const fgTBI_instr & rhs ) -{ - if( !(this == &rhs)) { - dual_instr_item::operator = (rhs); - BankLimit = rhs.BankLimit; - SlewLimit = rhs.SlewLimit; - scr_hole = rhs.scr_hole; - } - return *this; -} - -// -// Draws a Turn Bank Indicator on the screen -// - - void fgTBI_instr :: draw( void ) -{ - int x_inc1, y_inc1; - int x_inc2, y_inc2; - int x_t_inc1, y_t_inc1; - - int d_bottom_x, d_bottom_y; - int d_right_x, d_right_y; - int d_top_x, d_top_y; - int d_left_x, d_left_y; - - int inc_b_x, inc_b_y; - int inc_r_x, inc_r_y; - int inc_t_x, inc_t_y; - int inc_l_x, inc_l_y; - RECT My_box = get_location(); - POINT centroid = get_centroid(); - int tee_height = My_box.top - My_box.bottom; // Hack, hack. - -// struct fgFLIGHT *f = ¤t_aircraft.flight; - double sin_bank, cos_bank; - double bank_angle, sideslip_angle; - double ss_const; // sideslip angle pixels per rad - - bank_angle = current_ch2(); // Roll limit +/- 30 degrees - if( bank_angle < -FG_PI_2/3 ) { - bank_angle = -FG_PI_2/3; - }else if( bank_angle > FG_PI_2/3 ) { - bank_angle = FG_PI_2/3; - } - sideslip_angle = current_ch1(); // Sideslip limit +/- 20 degrees - if( sideslip_angle < -FG_PI/9 ) { - sideslip_angle = -FG_PI/9; - } else if( sideslip_angle > FG_PI/9 ) { - sideslip_angle = FG_PI/9; - } - - // sin_bank = sin( FG_2PI-FG_Phi ); - // cos_bank = cos( FG_2PI-FG_Phi ); - sin_bank = sin(FG_2PI-bank_angle); - cos_bank = cos(FG_2PI-bank_angle); - - x_inc1 = (int)(get_span() * cos_bank); - y_inc1 = (int)(get_span() * sin_bank); - x_inc2 = (int)(scr_hole * cos_bank); - y_inc2 = (int)(scr_hole * sin_bank); - - x_t_inc1 = (int)(tee_height * sin_bank); - y_t_inc1 = (int)(tee_height * cos_bank); - - d_bottom_x = 0; - d_bottom_y = (int)(-scr_hole); - d_right_x = (int)(scr_hole); - d_right_y = 0; - d_top_x = 0; - d_top_y = (int)(scr_hole); - d_left_x = (int)(-scr_hole); - d_left_y = 0; - - ss_const = (get_span()*2)/(FG_2PI/9); // width represents 40 degrees - - d_bottom_x += (int)(sideslip_angle*ss_const); - d_right_x += (int)(sideslip_angle*ss_const); - d_left_x += (int)(sideslip_angle*ss_const); - d_top_x += (int)(sideslip_angle*ss_const); - - inc_b_x = (int)(d_bottom_x*cos_bank-d_bottom_y*sin_bank); - inc_b_y = (int)(d_bottom_x*sin_bank+d_bottom_y*cos_bank); - inc_r_x = (int)(d_right_x*cos_bank-d_right_y*sin_bank); - inc_r_y = (int)(d_right_x*sin_bank+d_right_y*cos_bank); - inc_t_x = (int)(d_top_x*cos_bank-d_top_y*sin_bank); - inc_t_y = (int)(d_top_x*sin_bank+d_top_y*cos_bank); - inc_l_x = (int)(d_left_x*cos_bank-d_left_y*sin_bank); - inc_l_y = (int)(d_left_x*sin_bank+d_left_y*cos_bank); - - if( scr_hole == 0 ) - { - drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \ - centroid.x + x_inc1, centroid.y + y_inc1 ); - } - else - { - drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \ - centroid.x - x_inc2, centroid.y - y_inc2 ); - drawOneLine( centroid.x + x_inc2, centroid.y + y_inc2, \ - centroid.x + x_inc1, centroid.y + y_inc1 ); - } - - // draw teemarks - drawOneLine( centroid.x + x_inc2, \ - centroid.y + y_inc2, \ - centroid.x + x_inc2 + x_t_inc1, \ - centroid.y + y_inc2 - y_t_inc1 ); - drawOneLine( centroid.x - x_inc2, \ - centroid.y - y_inc2, \ - centroid.x - x_inc2 + x_t_inc1, \ - centroid.y - y_inc2 - y_t_inc1 ); - - // draw sideslip diamond (it is not yet positioned correctly ) - drawOneLine( centroid.x + inc_b_x, \ - centroid.y + inc_b_y, \ - centroid.x + inc_r_x, \ - centroid.y + inc_r_y ); - drawOneLine( centroid.x + inc_r_x, \ - centroid.y + inc_r_y, \ - centroid.x + inc_t_x, \ - centroid.y + inc_t_y ); - drawOneLine( centroid.x + inc_t_x, \ - centroid.y + inc_t_y, \ - centroid.x + inc_l_x, \ - centroid.y + inc_l_y ); - drawOneLine( centroid.x + inc_l_x, \ - centroid.y + inc_l_y, \ - centroid.x + inc_b_x, \ - centroid.y + inc_b_y ); - -} - -//====================== Top of HudLadder Class ======================= -HudLadder :: - HudLadder( RECT the_box, - DBLFNPTR ptch_source, - DBLFNPTR roll_source, - UINT span_units, - int major_div, - UINT minor_div, - UINT screen_hole, - UINT lbl_pos, - bool working) : - dual_instr_item( the_box, - ptch_source, - roll_source, - working, - ReadRIGHT ), - width_units ( span_units ), - div_units ( major_div < 0? -major_div: major_div ), - minor_div ( minor_div ), - label_pos ( lbl_pos ), - scr_hole ( screen_hole ), - vmax ( span_units/2 ), - vmin ( -vmax ) -{ - if( !width_units ) { - width_units = 45; - } - factor = (double)get_span() / (double) width_units; -} - -HudLadder :: - ~HudLadder() -{ -} - -HudLadder :: - HudLadder( const HudLadder & image ) : - dual_instr_item( (dual_instr_item &) image), - width_units ( image.width_units ), - div_units ( image.div_units ), - label_pos ( image.label_pos ), - scr_hole ( image.scr_hole ), - vmax ( image.vmax ), - vmin ( image.vmin ), - factor ( image.factor ) -{ -} -HudLadder & HudLadder :: - operator = ( const HudLadder & rhs ) -{ - if( !(this == &rhs)) { - (dual_instr_item &)(*this) = (dual_instr_item &)rhs; - width_units = rhs.width_units; - div_units = rhs.div_units; - label_pos = rhs.label_pos; - scr_hole = rhs.scr_hole; - vmax = rhs.vmax; - vmin = rhs.vmin; - factor = rhs.factor; - } - return *this; -} - -// -// Draws a climb ladder in the center of the HUD -// - -void HudLadder :: draw( void ) -{ - double roll_value, pitch_value; -// int marker_x; - int marker_y; - int scr_min; -// int scr_max; - int x_ini, x_end; - int y_ini, y_end; - int new_x_ini, new_x_end; - int new_y_ini, new_y_end; - register i; - POINT centroid = get_centroid(); - RECT box = get_location(); - int half_span = (box.right - box.left) >> 1; - char TextLadder[80]; - int condition; - - roll_value = current_ch2(); - pitch_value = current_ch1() * RAD_TO_DEG; - - vmin = (int)(pitch_value - (double)width_units/2.0); - vmax = (int)(pitch_value + (double)width_units/2.0); - - scr_min = box.bottom; // centroid.y - ((box.top - box.bottom) >> 1); -// scr_max = box.top; // scr_min + (box.top - box.bottom); -// marker_x = centroid.x - half_span; - -// Box the target. - drawOneLine( centroid.x - 5, centroid.y, centroid.x, centroid.y + 5); - drawOneLine( centroid.x, centroid.y + 5, centroid.x + 5, centroid.y); - drawOneLine( centroid.x + 5, centroid.y, centroid.x, centroid.y - 5); - drawOneLine( centroid.x, centroid.y - 5, centroid.x - 5, centroid.y); - - for( i=(int)vmin; i<=(int)vmax; i+=1 ) - { - condition = 1; - if( condition ) - { - marker_y = scr_min + (int)((i-vmin)*factor); - if( div_units ) { - if( i%div_units==0 ) - { - sprintf( TextLadder, "%d", i ); - if( scr_hole == 0 ) - { - if( i ) { - x_ini = centroid.x - half_span; - } - else { - x_ini = centroid.x - half_span - 10; - } - y_ini = marker_y; - x_end = centroid.x + half_span; - y_end = marker_y; - new_x_ini = centroid.x + (int)( \ - (x_ini - centroid.x) * cos(roll_value) - \ - (y_ini - centroid.y) * sin(roll_value)); - new_y_ini = centroid.y + (int)( \ - (x_ini - centroid.x) * sin(roll_value) + \ - (y_ini - centroid.y) * cos(roll_value)); - new_x_end = centroid.x + (int)( \ - (x_end - centroid.x) * cos(roll_value) - \ - (y_end - centroid.y) * sin(roll_value)); - new_y_end = centroid.y + (int)( \ - (x_end - centroid.x) * sin(roll_value) + \ - (y_end - centroid.y) * cos(roll_value)); - - if( i >= 0 ) - { - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - } - else - { - glEnable(GL_LINE_STIPPLE); - glLineStipple( 1, 0x00FF ); - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - glDisable(GL_LINE_STIPPLE); - } - textString( new_x_ini - 8 * strlen(TextLadder) - 8, - new_y_ini - 4, - TextLadder, GLUT_BITMAP_8_BY_13 ); - textString( new_x_end + 10, - new_y_end - 4, - TextLadder, GLUT_BITMAP_8_BY_13 ); - } - else - { - if( i != 0 ) { - x_ini = centroid.x - half_span; - } - else { - x_ini = centroid.x - half_span - 10; - } - y_ini = marker_y; - x_end = centroid.x - half_span + scr_hole/2; - y_end = marker_y; - new_x_ini = centroid.x+ (int)( \ - (x_ini - centroid.x) * cos(roll_value) -\ - (y_ini - centroid.y) * sin(roll_value)); - new_y_ini = centroid.y+ (int)( \ - (x_ini - centroid.x) * sin(roll_value) +\ - (y_ini - centroid.y) * cos(roll_value)); - new_x_end = centroid.x+ (int)( \ - (x_end - centroid.x) * cos(roll_value) -\ - (y_end - centroid.y) * sin(roll_value)); - new_y_end = centroid.y+ (int)( \ - (x_end - centroid.x) * sin(roll_value) +\ - (y_end - centroid.y) * cos(roll_value)); - - if( i >= 0 ) - { - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - } - else - { - glEnable(GL_LINE_STIPPLE); - glLineStipple( 1, 0x00FF ); - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - glDisable(GL_LINE_STIPPLE); - } - textString( new_x_ini - 8 * strlen(TextLadder) - 8, - new_y_ini - 4, - TextLadder, GLUT_BITMAP_8_BY_13 ); - - x_ini = centroid.x + half_span - scr_hole/2; - y_ini = marker_y; - if( i != 0 ) { - x_end = centroid.x + half_span; - } - else { - x_end = centroid.x + half_span + 10; - } - y_end = marker_y; - new_x_ini = centroid.x + (int)( \ - (x_ini-centroid.x)*cos(roll_value) -\ - (y_ini-centroid.y)*sin(roll_value)); - new_y_ini = centroid.y + (int)( \ - (x_ini-centroid.x)*sin(roll_value) +\ - (y_ini-centroid.y)*cos(roll_value)); - new_x_end = centroid.x + (int)( \ - (x_end-centroid.x)*cos(roll_value) -\ - (y_end-centroid.y)*sin(roll_value)); - new_y_end = centroid.y + (int)( \ - (x_end-centroid.x)*sin(roll_value) +\ - (y_end-centroid.y)*cos(roll_value)); - - if( i >= 0 ) - { - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - } - else - { - glEnable(GL_LINE_STIPPLE); - glLineStipple( 1, 0x00FF ); - drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end ); - glDisable(GL_LINE_STIPPLE); - } - textString( new_x_end+10, new_y_end-4, - TextLadder, GLUT_BITMAP_8_BY_13 ); - } - } - } - /* if( i%div_max()==0 ) - { - drawOneLine( marker_x, marker_y, marker_x+6, marker_y ); - sprintf( TextScale, "%d", i ); - if( orientation == LEFT ) - { - textString( marker_x-8*strlen(TextScale)-2, marker_y-4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - else if( orientation == RIGHT ) - { - textString( marker_x+10, marker_y-4, - TextScale, GLUT_BITMAP_8_BY_13 ); - } - } */ - } - } - -} //========================= End of Class Implementations=================== // fgHUDInit @@ -1474,13 +145,12 @@ void HudLadder :: draw( void ) // mustange and the engine readouts of a B36! // -#define INSTRDEFS 17 +#define INSTRDEFS 21 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) { instr_item *HIptr; int index; - RECT loc; fgPrintf( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD\n" ); @@ -1496,108 +166,93 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) // fgHUDSetTimeMode( hud, NIGHT ); // fgHUDSetBrightness( hud, BRT_LIGHT ); - for( index = 0; index <= INSTRDEFS; index++) { + index = 0; + + do { switch ( index ) { case 0: // TBI - // fgHUDAddHorizon( hud, 330, 100, 40, 5, 10, get_roll, get_sideslip ); - loc.left = 330 - 40; - loc.top = 110; - loc.right = 330 + 40; - loc.bottom = 100; - HIptr = (instr_item *) new fgTBI_instr( loc ); + HIptr = (instr_item *) new fgTBI_instr( 300, 100, 60, 10 ); break; case 1: // Artificial Horizon - // fgHUDAddLadder ( hud, 330, 285, 120, 180, 70, 10, - // NONE, 45, get_roll, get_pitch ); - loc.left = 270; // 330 - 60 - loc.top = 375; // 285 + 90 - loc.right = 390; // 330 + 60 - loc.bottom = 195; // 285 - 90 - HIptr = (instr_item *) new HudLadder( loc ); + HIptr = (instr_item *) new HudLadder( 270, 195, 120, 180 ); break; case 2: // KIAS - // fgHUDAddScale ( hud, VERTICAL, LIMIT, 200, 180, 380, 5, 10, - // LEFT, 0, 100, 50, 0, get_speed ); - loc.left = 160; - loc.top = 380; - loc.right = 200; - loc.bottom = 180; - HIptr = (instr_item *) new moving_scale( loc, - get_speed, - ReadLEFT, - 200, 0, - 10, 5, - 0, - 50.0, - TRUE); + HIptr = (instr_item *) new hud_card( 160, + 170, + 35, + 200, + get_speed, + HUDS_LEFT | HUDS_VERT, + 200.0, 0.0, + 1.0, + 10, 5, + 0, + 0, + 50.0, + true); + break; case 3: // Angle of Attack - // fgHUDAddScale ( hud, HORIZONTAL, NOLIMIT, 180, 250, 410, 1, 5, - // BOTTOM, -40, 50, 21, 0, get_aoa ); - loc.left = 250; - loc.top = 190; - loc.right = 410; - loc.bottom = 160; - HIptr = (instr_item *) new moving_scale( loc, - get_aoa, - ReadBOTTOM, - 50, -40, - 5, 1, - 0, - 21.0, - TRUE); + HIptr = (instr_item *) new hud_card( 450, + 195, + 30, + 150, + get_aoa, + HUDS_LEFT | HUDS_VERT, + 50, -40, + 1.0, + 5, 1, + 0, + 1, + 21.0, + true); break; case 4: // GYRO COMPASS - // fgHUDAddScale ( hud, HORIZONTAL, NOLIMIT, 380, 200, 460, 5, 10, - // TOP, 0, 50, 50, 360, get_heading ); - loc.left = 200; - loc.top = 410; - loc.right = 460; - loc.bottom = 380; - HIptr = (instr_item *) new moving_scale( loc, - get_heading, - ReadTOP, - 360, 0, - 10, 5, - 360, - 50, - TRUE); + HIptr = (instr_item *) new hud_card( 200, + 375, + 260, + 32, + get_heading, + HUDS_TOP, + 360, 0, + 1.0, + 10, 5, + 360, + 0, + 50, + true); break; case 5: // AMSL - // fgHUDAddScale ( hud, VERTICAL, LIMIT, 460, 180, 380, 25, 100, - // RIGHT, 0, 15000, 250, 0, get_altitude); - loc.left = 460; - loc.top = 380; - loc.right = 490; - loc.bottom = 180; - HIptr = (instr_item *) new moving_scale( loc, - get_altitude, - ReadRIGHT, - 15000, 0, - 100, 25, - 0, - 250, - TRUE); + HIptr = (instr_item *) new hud_card( 490, + 170, + 35, + 200, + get_altitude, + HUDS_RIGHT | HUDS_VERT, + 15000, 0, + 1.0, + 100, 25, + 0, + 0, + 250, + true); break; case 6: // Digital KIAS - // fgHUDAddLabel ( hud, 160, 150, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " Kts", "%5.0f", get_speed ); - loc.left = 160; - loc.top = 180; // Ignore - loc.right = 200; // Ignore - loc.bottom = 150; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 160, + 150, + 40, + 30, get_speed, "%5.0f", NULL, " Kts", - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1605,18 +260,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 7: // Digital Altimeter - // fgHUDAddLabel ( hud, 160, 135, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " m", "%5.0f", get_altitude ); - loc.left = 160; - loc.top = 145; // Ignore - loc.right = 200; // Ignore - loc.bottom = 135; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 160, + 135, + 40, + 10, get_altitude, "MSL %5.0f", NULL, " m", - ReadTOP, + HUDS_TOP, LEFT_JUST, SMALL, 0, @@ -1624,18 +276,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 8: // Roll indication diagnostic - // fgHUDAddLabel ( hud, 160, 120, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " Roll", "%5.2f", get_roll ); - loc.left = 160; - loc.top = 130; // Ignore - loc.right = 200; // Ignore - loc.bottom = 120; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 160, + 120, + 40, + 10, get_roll, "%5.2f", " Roll", " Deg", - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1643,18 +292,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 9: // Angle of attack diagnostic - // fgHUDAddLabel ( hud, 440, 150, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " AOA", "%5.2f", get_aoa ); - loc.left = 440; - loc.top = 160; // Ignore - loc.right = 500; // Ignore - loc.bottom = 150; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 440, + 150, + 60, + 10, get_aoa, - " %5.2f", - " AOA", + " %5.2f", + "AOA", " Deg", - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1662,18 +308,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 10: - // fgHUDAddLabel ( hud, 440, 135, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " Heading", "%5.0f", get_heading ); - loc.left = 440; - loc.top = 145; // Ignore - loc.right = 500; // Ignore - loc.bottom = 135; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 440, + 135, + 60, + 10, get_heading, - "%5.0f", - "Heading", + " %5.0f", + "Heading ", " Deg", - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1681,18 +324,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 11: - // fgHUDAddLabel ( hud, 440, 120, SMALL, NOBLINK, - // RIGHT_JUST, NULL, " Sideslip", "%5.2f", get_sideslip ); - loc.left = 440; - loc.top = 130; // Ignore - loc.right = 500; // Ignore - loc.bottom = 120; - HIptr = (instr_item *) new instr_label ( loc, + HIptr = (instr_item *) new instr_label ( 440, + 120, + 60, + 10, get_sideslip, "%5.2f", "Sideslip ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1700,15 +340,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 12: - loc.left = 440; - loc.top = 90; // Ignore - loc.right = 440; // Ignore - loc.bottom = 90; - HIptr = (instr_item *) new instr_label( loc, get_throttleval, - "%.2f", + HIptr = (instr_item *) new instr_label( 440, + 100, + 60, + 10, + get_throttleval, + "%5.2f", "Throttle ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1716,15 +356,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 13: - loc.left = 440; - loc.top = 70; // Ignore - loc.right = 500; // Ignore - loc.bottom = 75; - HIptr = (instr_item *) new instr_label( loc, get_elevatorval, + HIptr = (instr_item *) new instr_label( 440, + 85, + 60, + 10, + get_elevatorval, "%5.2f", - "Elevator", + "Elevator ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1732,31 +372,32 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 14: - loc.left = 440; - loc.top = 100; // Ignore - loc.right = 500; // Ignore - loc.bottom = 60; - HIptr = (instr_item *) new instr_label( loc, get_aileronval, + HIptr = (instr_item *) new instr_label( 440, + 60, + 60, + 10, + get_aileronval, "%5.2f", - "Aileron", + "Aileron ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, TRUE ); break; + case 15: - loc.left = 10; - loc.top = 100; // Ignore - loc.right = 500; // Ignore - loc.bottom = 10; - HIptr = (instr_item *) new instr_label( loc, get_frame_rate, + HIptr = (instr_item *) new instr_label( 10, + 10, + 60, + 10, + get_frame_rate, "%.1f", "Frame rate = ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1764,15 +405,15 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 16: - loc.left = 10; - loc.top = 100; // Ignore - loc.right = 500; // Ignore - loc.bottom = 25; - HIptr = (instr_item *) new instr_label( loc, get_vfc_ratio, + HIptr = (instr_item *) new instr_label( 10, + 25, + 90, + 10, + get_vfc_ratio, "%.2f", "VFC Ratio = ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, @@ -1780,39 +421,66 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ) break; case 17: - loc.left = 10; - loc.top = 100; // Ignore - loc.right = 500; // Ignore - loc.bottom = 40; - HIptr = (instr_item *) new instr_label( loc, get_fov, + HIptr = (instr_item *) new instr_label( 10, + 40, + 90, + 10, + get_fov, "%.1f", "FOV = ", NULL, - ReadTOP, + HUDS_TOP, RIGHT_JUST, SMALL, 0, TRUE ); break; + case 18: + HIptr = (instr_item *) new guage_instr( 50, // x + 200, // y + 100, // width + 20, // height + get_aileronval, // data source + HUDS_BOTTOM, + 100.0, + +1.0, + -1.0); + break; + + case 19: + HIptr = (instr_item *) new guage_instr( 90, // x + 225, // y + 20, // width + 100, // height + get_elevatorval, // data source + HUDS_BOTH | HUDS_VERT, + 100.0, // Scale data + +1.0, // Data Range + -1.0); + break; - // fgHUDAddControlSurfaces( hud, 10, 10, NULL ); -// loc.left = 250; -// loc.top = 190; -// loc.right = 410; -// loc.bottom = 180; -// HIptr = (instr_item *) new -// break; + case 20: + HIptr = (instr_item *) new guage_instr( 50, // x + 350, // y + 100, // width + 20, // height + get_rudderval, // data source + HUDS_TOP, + 100.0, + +1.0, + -1.0); + break; - default:; + default: + HIptr = 0;; } if( HIptr ) { // Anything to install? HUD_deque.insert( HUD_deque.begin(), HIptr); } + index++; } + while( HIptr ); -// fgHUDAddControl( hud, HORIZONTAL, 50, 25, get_aileronval ); // was 10, 10 -// fgHUDAddControl( hud, VERTICAL, 150, 25, get_elevatorval ); // was 10, 10 -// fgHUDAddControl( hud, HORIZONTAL, 250, 25, get_rudderval ); // was 10, 10 return 0; // For now. Later we may use this for an error code. } @@ -1916,9 +584,8 @@ void fgUpdateHUD( void ) { } /* $Log$ -/* Revision 1.12 1998/06/12 00:55:59 curt -/* Build only static libraries. -/* Declare memmove/memset for Sloaris. +/* Revision 1.13 1998/07/03 13:16:28 curt +/* Added Charlie Hotchkiss's HUD updates and improvementes. /* * Revision 1.11 1998/06/05 18:17:10 curt * Added the declaration of memmove needed by the stl which apparently diff --git a/Cockpit/hud.hxx b/Cockpit/hud.hxx index 8ef19ca71..c05260aa0 100644 --- a/Cockpit/hud.hxx +++ b/Cockpit/hud.hxx @@ -27,46 +27,48 @@ #ifndef _HUD_HXX #define _HUD_HXX - #ifndef __cplusplus # error This library requires C++ #endif - #ifdef HAVE_CONFIG_H # include #endif -#ifdef __sun__ -extern "C" void *memmove(void *, const void *, size_t); -extern "C" void *memset(void *, int, size_t); +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include +#include +#include + +#ifdef HAVE_VALUES_H +# include // for MAXINT #endif #include #include - #include #include #include -//using namespace std; - -#include // STL +#include // STL +#ifdef NEEDNAMESPACESTD +using namespace std; +#endif #ifndef WIN32 - typedef struct { int x, y; } POINT; - + typedef struct { int top, bottom, left, right; } RECT; - #endif - // View mode definitions enum VIEW_MODES{ HUD_VIEW, PANEL_VIEW, CHASE_VIEW, TOWER_VIEW }; @@ -112,6 +114,19 @@ enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ; #define LABEL_COUNTER 1 #define LABEL_WARNING 2 +#define HUDS_AUTOTICKS 0x0001 +#define HUDS_VERT 0x0002 +#define HUDS_HORZ 0x0000 +#define HUDS_TOP 0x0004 +#define HUDS_BOTTOM 0x0008 +#define HUDS_LEFT HUDS_TOP +#define HUDS_RIGHT HUDS_BOTTOM +#define HUDS_BOTH (HUDS_LEFT | HUDS_RIGHT) +#define HUDS_NOTICKS 0x0010 +#define HUDS_ARITHTIC 0x0020 +#define HUDS_DECITICS 0x0040 +#define HUDS_NOTEXT 0x0080 + // Ladder orientaion // #define HUD_VERTICAL 1 // #define HUD_HORIZONTAL 2 @@ -170,8 +185,6 @@ enum hudinstype{ HUDno_instr, HUDtbi }; -enum ReadOriented{ ReadRIGHT, ReadLEFT, ReadTOP, ReadBOTTOM }; - class instr_item { // An Abstract Base Class (ABC) private: static UINT instances; // More than 64K instruments? Nah! @@ -179,7 +192,7 @@ class instr_item { // An Abstract Base Class (ABC) RECT scrn_pos; // Framing - affects scale dimensions // and orientation. Vert vs Horz, etc. DBLFNPTR load_value_fn; - ReadOriented oriented; + UINT opts; bool is_enabled; bool broken; int brightness; @@ -187,9 +200,12 @@ class instr_item { // An Abstract Base Class (ABC) POINT mid_span; // public: - instr_item( RECT scrn_pos, + instr_item( int x, + int y, + UINT height, + UINT width, DBLFNPTR data_source, - ReadOriented orient, + UINT options, bool working = true); instr_item( const instr_item & image ); @@ -204,7 +220,7 @@ class instr_item { // An Abstract Base Class (ABC) double get_value ( void ) { return load_value_fn();} UINT get_span ( void ) { return scr_span; } POINT get_centroid ( void ) { return mid_span; } - ReadOriented get_orientation ( void ) { return oriented; } + UINT get_options ( void ) { return opts; } virtual void display_enable( bool working ) { is_enabled = !! working;} @@ -212,13 +228,13 @@ class instr_item { // An Abstract Base Class (ABC) virtual void update( void ); virtual void break_display ( bool bad ); virtual void SetBrightness( int illumination_level ); // fgHUDSetBright... + void SetPosition ( int x, int y, UINT width, UINT height ); UINT get_Handle( void ); virtual void draw( void ) = 0; // Required method in derived classes }; typedef instr_item *HIptr; - -extern deque< instr_item * > HUD_deque; +extern deque< instr_item *> HUD_deque; // instr_item This class has no other purpose than to maintain // a linked list of instrument and derived class @@ -235,16 +251,19 @@ class instr_label : public instr_item { int blink; public: - instr_label( RECT the_box, + instr_label( int x, + int y, + UINT width, + UINT height, DBLFNPTR data_source, const char *label_format, - const char *pre_label_string = 0, - const char *post_label_string = 0, - ReadOriented orientation = ReadTOP, - fgLabelJust justification = CENTER_JUST, - int font_size = SMALL, - int blinking = NOBLINK, - bool working = true); + const char *pre_label_string = 0, + const char *post_label_string = 0, + UINT options = HUDS_TOP, + fgLabelJust justification = CENTER_JUST, + int font_size = SMALL, + int blinking = NOBLINK, + bool working = true); ~instr_label(); @@ -264,25 +283,32 @@ typedef instr_label * pInstlabel; class instr_scale : public instr_item { private: - int range_shown; // Width Units. - int Maximum_value; // ceiling. - int Minimum_value; // Representation floor. + double range_shown; // Width Units. + double Maximum_value; // ceiling. + double Minimum_value; // Representation floor. + double scale_factor; // factor => screen units/range values. UINT Maj_div; // major division marker units UINT Min_div; // minor division marker units + double disp_factor; // Multiply by to get numbers shown on scale. UINT Modulo; // Roll over point - double scale_factor; // factor => screen units/range values. + int signif_digits; // digits to show to the right. public: - instr_scale( RECT the_box, + instr_scale( int x, + int y, + UINT width, + UINT height, DBLFNPTR load_fn, - ReadOriented orient, - int show_range, - int max_value, - int min_value = 0, - UINT major_divs = 10, - UINT minor_divs = 5, - UINT rollover = 0, - bool working = true); + UINT options, + double show_range, + double max_value = 100.0, + double min_value = 0.0, + double disp_scaling = 1.0, + UINT major_divs = 10, + UINT minor_divs = 5, + UINT rollover = 0, + int dp_showing = 2, + bool working = true); virtual ~instr_scale(); instr_scale( const instr_scale & image); @@ -291,57 +317,67 @@ class instr_scale : public instr_item { virtual void draw ( void ) {}; // No-op here. Defined in derived classes. UINT div_min ( void ) { return Min_div;} UINT div_max ( void ) { return Maj_div;} - int min_val ( void ) { return Minimum_value;} - int max_val ( void ) { return Maximum_value;} + double min_val ( void ) { return Minimum_value;} + double max_val ( void ) { return Maximum_value;} UINT modulo ( void ) { return Modulo; } double factor ( void ) { return scale_factor;} double range_to_show( void ) { return range_shown;} }; -// moving_scale_instr This class displays the indicated quantity on +// hud_card_ This class displays the indicated quantity on // a scale that moves past the pointer. It may be // horizontal or vertical, read above(left) or below(right) of the base // line. -class moving_scale : public instr_scale { +class hud_card : public instr_scale { private: double val_span; double half_width_units; public: - moving_scale( RECT box, - DBLFNPTR load_fn, - ReadOriented readway, - int maxValue, - int minValue, - UINT major_divs, - UINT minor_divs, - UINT modulator, - double value_span, - bool working = true); - - ~moving_scale(); - moving_scale( const moving_scale & image); - moving_scale & operator = (const moving_scale & rhs ); + hud_card( int x, + int y, + UINT width, + UINT height, + DBLFNPTR load_fn, + UINT options, + double maxValue = 100.0, + double minValue = 0.0, + double disp_scaling = 1.0, + UINT major_divs = 10, + UINT minor_divs = 5, + UINT modulator = 100, + int dp_showing = 2, + double value_span = 100.0, + bool working = true); + + ~hud_card(); + hud_card( const hud_card & image); + hud_card & operator = (const hud_card & rhs ); // virtual void display_enable( bool setting ); virtual void draw( void ); // Required method in base class }; -typedef moving_scale * pMoveScale; +typedef hud_card * pCardScale; class guage_instr : public instr_scale { private: public: - guage_instr( RECT box, - DBLFNPTR load_fn, - ReadOriented readway, - int maxValue, - int minValue, - UINT major_divs, - UINT minor_divs, - UINT modulus, - bool working = true); + guage_instr( int x, + int y, + UINT width, + UINT height, + DBLFNPTR load_fn, + UINT options, + double disp_scaling = 1.0, + double maxValue = 100, + double minValue = 0, + UINT major_divs = 50, + UINT minor_divs = 0, + int dp_showing = 2, + UINT modulus = 0, + bool working = true); ~guage_instr(); guage_instr( const guage_instr & image); @@ -359,11 +395,14 @@ class dual_instr_item : public instr_item { DBLFNPTR alt_data_source; public: - dual_instr_item ( RECT the_box, - DBLFNPTR chn1_source, - DBLFNPTR chn2_source, - bool working = true, - ReadOriented readway = ReadTOP); + dual_instr_item ( int x, + int y, + UINT width, + UINT height, + DBLFNPTR chn1_source, + DBLFNPTR chn2_source, + bool working = true, + UINT options = HUDS_TOP); virtual ~dual_instr_item() {}; dual_instr_item( const dual_instr_item & image); @@ -381,12 +420,15 @@ class fgTBI_instr : public dual_instr_item { UINT scr_hole; public: - fgTBI_instr( RECT the_box, + fgTBI_instr( int x, + int y, + UINT width, + UINT height, DBLFNPTR chn1_source = get_roll, DBLFNPTR chn2_source = get_sideslip, - UINT maxBankAngle = 45, - UINT maxSlipAngle = 5, - UINT gap_width = 5, + double maxBankAngle = 45.0, + double maxSlipAngle = 5.0, + UINT gap_width = 5.0, bool working = true); fgTBI_instr( const fgTBI_instr & image); @@ -409,19 +451,22 @@ class HudLadder : public dual_instr_item { UINT minor_div; UINT label_pos; UINT scr_hole; - int vmax; - int vmin; + double vmax; + double vmin; double factor; public: - HudLadder( RECT the_box, + HudLadder( int x, + int y, + UINT width, + UINT height, DBLFNPTR ptch_source = get_roll, DBLFNPTR roll_source = get_pitch, - UINT span_units = 45, - int division_units = 10, - UINT minor_division = 0, - UINT screen_hole = 70, - UINT lbl_pos = 0, + double span_units = 45.0, + double division_units = 10.0, + double minor_division = 0.0, + UINT screen_hole = 70, + UINT lbl_pos = 0, bool working = true ); ~HudLadder(); @@ -438,6 +483,17 @@ class HudLadder : public dual_instr_item { extern int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ ); extern void fgUpdateHUD( void ); +extern void drawOneLine ( UINT x1, UINT y1, UINT x2, UINT y2); +extern void drawOneLine ( RECT &rect); +extern void textString ( int x, + int y, + char *msg, + void *font = GLUT_BITMAP_8_BY_13); +extern void strokeString( int x, + int y, + char *msg, + void *font = GLUT_STROKE_ROMAN, + float theta = 0); /* bool AddHUDInstrument( instr_item *pBlackBox ); void DrawHUD ( void ); @@ -453,9 +509,8 @@ void fgHUDSetTimeMode( Hptr hud, int time_of_day ); #endif // _HUD_H /* $Log$ -/* Revision 1.7 1998/06/12 00:56:00 curt -/* Build only static libraries. -/* Declare memmove/memset for Sloaris. +/* Revision 1.8 1998/07/03 13:16:29 curt +/* Added Charlie Hotchkiss's HUD updates and improvementes. /* * Revision 1.6 1998/06/03 00:43:28 curt * No .h when including stl stuff. diff --git a/Cockpit/hud_card.cxx b/Cockpit/hud_card.cxx new file mode 100644 index 000000000..29a5c1b2f --- /dev/null +++ b/Cockpit/hud_card.cxx @@ -0,0 +1,380 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include