]> git.mxchange.org Git - flightgear.git/blobdiff - src/Cockpit/hud.cxx
In the process of changing, adding and removing files the last few years
[flightgear.git] / src / Cockpit / hud.cxx
index 92183ba1855ec54280175f27e18c0f2deb76b6ea..98b4f139493c6343c4ff93f719faaafcbd8cdccc 100644 (file)
 // $Id$
 
 #include <simgear/compiler.h>
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
+
+#include STL_STRING
+#include STL_FSTREAM
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #ifdef __BORLANDC__
 #  define exception c_exception
 #endif
+
 #include <math.h>
 
-#include <GL/glut.h>
 #include <stdlib.h>
-#include STL_STRING
-#include STL_FSTREAM
+#include <stdio.h>             // char related functions
+#include <string.h>            // strcmp()
+
+#include SG_GLU_H
 
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
-#include <simgear/misc/props.hxx>
-//#include <simgear/math/fg_random.h>
-//#include <simgear/math/polar3d.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/misc/sg_path.hxx>
 
 #include <Aircraft/aircraft.hxx>
-#include <Autopilot/newauto.hxx>
+#include <Autopilot/xmlauto.hxx>
 #include <GUI/gui.h>
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
-#ifdef FG_NETWORK_OLK
-#include <NetworkOLK/network.h>
-#endif
 #include <Scenery/scenery.hxx>
-//#include <Time/fg_timer.hxx>
 
-#if defined ( __sun__ ) || defined ( __sgi )
+#if defined (__sun) || defined ( __sgi )
 extern "C" {
     extern void *memmove(void *, const void *, size_t);
 }
@@ -170,6 +170,9 @@ static instr_item * readLabel( const SGPropertyNode * node);
 static instr_item * readTBI( const SGPropertyNode * node);
 //$$$ end   - added, Neetha, 28 Nov 2k
 
+static void drawHUD();
+static void fgUpdateHUDVirtual();
+
 void fgHUDalphaInit( void );
 
 class locRECT {
@@ -190,78 +193,6 @@ locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
 }
 // #define DEBUG
 
-#ifdef OLD_CODE
-void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
-{
-    glBegin(GL_LINES);
-    glVertex2f(x1, y1);
-    glVertex2f(x2, y2);
-    glEnd();
-}
-
-void drawOneLine( RECT &rect)
-{
-    glBegin(GL_LINES);
-    glVertex2f(rect.left, rect.top);
-    glVertex2f(rect.right, rect.bottom);
-    glEnd();
-}
-
-//
-// The following code deals with painting the "instrument" on the display
-//
-/* textString - Bitmap font string */
-
-void textString( int x, int y, char *msg, void *font,int digit) //suma
-{
-
-    if(*msg) {
-        //      puDrawString (  NULL, msg, x, y );
-        glRasterPos2f(x, y);
-        while (*msg) {
-            glutBitmapCharacter(font, *msg);
-            msg++;
-        }
-    }
-}
-
-
-/* strokeString - Stroke font string */
-void strokeString(int x, int y, char *msg, void *font, float theta)
-{
-    int xx;
-    int yy;
-    int c;
-    float sintheta,costheta;
-    
-
-    if(*msg) {
-        glPushMatrix();
-        glRotatef(theta * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
-        sintheta = sin(theta);
-        costheta = cos(theta);
-        xx = (int)(x * costheta + y * sintheta);
-        yy = (int)(y * costheta - x * sintheta);
-        glTranslatef( xx, yy, 0);
-        glScalef(.1, .1, 0.0);
-        while( (c=*msg++) ) {
-            glutStrokeCharacter(font, c);
-        }
-        glPopMatrix();
-    }
-}
-
-int getStringWidth ( char *str )
-{
-    if ( HUDtext && str ) {
-        float r, l ;
-        guiFntHandle->getBBox ( str, HUD_TextSize, 0, &l, &r, NULL, NULL ) ;
-        return FloatToInt( r - l );
-    }
-    return 0 ;
-}
-#endif // OLD_CODE
-
 //========================= End of Class Implementations===================
 // fgHUDInit
 //
@@ -306,11 +237,20 @@ readLadder(const SGPropertyNode * node)
     zenith                     = node->getIntValue("zenith");  //suma
     nadir                      = node->getIntValue("nadir");  //suma
     hat                                = node->getIntValue("hat");
-
+    // The factor assumes a base of 55 degrees per 640 pixels.
+    // Invert to convert the "compression" factor to a
+    // pixels-per-degree number.
+    if(fgGetBool("/sim/hud/enable3d", true))
+    {
+        if (HUD_style == 1)
+        {
+            factor = 1;
+            factor = (640./55.) / factor;
+        }
+    }
 
     SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
        
-                               
     p = (instr_item *) new HudLadder( name, x, y,
                                       width, height, factor,
                                       get_roll, get_pitch,
@@ -390,6 +330,8 @@ readCard(const SGPropertyNode * node)
         load_fn = get_aileronval;
     } else if (loadfn=="elevatorval") {
         load_fn = get_elevatorval;
+    } else if (loadfn=="elevatortrimval") {
+        load_fn = get_elev_trimval;
     } else if (loadfn=="rudderval") {
         load_fn = get_rudderval;
     } else if (loadfn=="throttleval") {
@@ -452,7 +394,7 @@ readLabel(const SGPropertyNode * node)
 {
     instr_item *p;
 
-    int font_size = (fgGetInt("/sim/startup/xsize") > 1000) ? LARGE : SMALL;
+    int font_size = (fgGetInt("/sim/startup/xsize") > 1000) ? HUD_FONT_LARGE : HUD_FONT_SMALL;
 
     name               = node->getStringValue("name");
     x                   = node->getIntValue("x");
@@ -513,6 +455,7 @@ readLabel(const SGPropertyNode * node)
         }
     }
 
+#ifdef ENABLE_SP_FMDS
     if ( loadfn== "aux1" ) {
         load_fn = get_aux1;
     } else if ( loadfn == "aux2" ) {
@@ -549,7 +492,9 @@ readLabel(const SGPropertyNode * node)
         load_fn = get_aux17;
     } else if ( loadfn == "aux18" ) {
         load_fn = get_aux18;
-    } else if ( loadfn == "ax" ) {
+    } else
+#endif
+      if ( loadfn == "ax" ) {
         load_fn = get_Ax;
     } else if ( loadfn == "speed" ) {
         load_fn = get_speed;
@@ -640,13 +585,38 @@ readTBI(const SGPropertyNode * node)
     return p;
 } //end readTBI
 
+static instr_item * 
+readRunway(const SGPropertyNode * node) {
+       name    = node->getStringValue("name");
+       x       = node->getIntValue("x");
+       y       = node->getIntValue("y");
+       width = node->getIntValue("width");
+       height = node->getIntValue("height");
+       scaling = node->getDoubleValue("scale");
+       working = node->getBoolValue("working",true);
+       runway_instr *ri = new runway_instr(x,y,width,height,scaling,working);
+       double scale = node->getDoubleValue("arrow_scale",1.0); 
+       ri->setDrawArrow((scale>0)?true:false);
+       ri->setDrawArrowAlways((scale>0)?node->getBoolValue("arrow_always"):false);
+       ri->setStippleOutline(node->getIntValue("outer_stipple",0xFFFF));
+       ri->setStippleCenterline(node->getIntValue("center_stipple",0xFFFF));
+       ri->setArrowRotationRadius(node->getDoubleValue("arrow_radius"));
+       ri->setArrowScale(scale);
+       ri->setLineScale(node->getDoubleValue("line_scale",1.0));
+       ri->setScaleDist(node->getDoubleValue("scale_dist_nm"));
+       SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
+       return (instr_item *) ri;
+}
+
 
 int readInstrument(const SGPropertyNode * node)
 {
+    static const SGPropertyNode *startup_units_node
+        = fgGetNode("/sim/startup/units");
 
     instr_item *HIptr;
     
-    if ( fgGetString("/sim/startup/units") == "feet" ) {
+    if ( !strcmp(startup_units_node->getStringValue(), "feet") ) {
         strcpy(units, " ft");
     } else {
         strcpy(units, " m");
@@ -696,6 +666,18 @@ int readInstrument(const SGPropertyNode * node)
 
         }//for - tbis
     }
+    
+    const SGPropertyNode * rwy_group = node->getNode("runways");
+    if (rwy_group != 0) {
+        int nRwy = rwy_group->nChildren();
+        for (int j = 0; j < nRwy; j++) {
+            SG_LOG( SG_COCKPIT, SG_DEBUG,
+                    "**************  Reading runway properties" );
+            HIptr = readRunway(rwy_group->getChild(j));
+            HUD_deque.insert( HUD_deque.begin(), HIptr);
+
+        }//for - runways
+    }    
     return 0;
 }//end readinstrument
 
@@ -737,7 +719,6 @@ int readHud( istream &input )
                << " from "
                << path.str());
 
-
         SGPropertyNode root2;
         try {
             readProperties(path.str(), &root2);
@@ -755,7 +736,6 @@ int readHud( istream &input )
 int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
 {
 
-
     HUD_style = 1;
 
     SG_LOG( SG_COCKPIT, SG_INFO, "Initializing current aircraft HUD" );
@@ -777,6 +757,23 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
     fgHUDalphaInit();
     fgHUDReshape();
 
+    if ( HUDtext ) {
+        // this chunk of code is not necessarily thread safe if the
+        // compiler optimizer reorders these statements.  Note that
+        // "delete ptr" does not set "ptr = NULL".  We have to do that
+        // ourselves.
+        fntRenderer *tmp = HUDtext;
+        HUDtext = NULL;
+        delete tmp;
+    }
+
+//    HUD_TextSize = fgGetInt("/sim/startup/xsize") / 60;
+    HUD_TextSize = 10;
+    HUDtext = new fntRenderer();
+    HUDtext -> setFont      ( guiFntHandle ) ;
+    HUDtext -> setPointSize ( HUD_TextSize ) ;
+    HUD_TextList.setFont( HUDtext );
+    
     return 0;  // For now. Later we may use this for an error code.
 
 }
@@ -806,19 +803,19 @@ int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
 }
 //$$$ End - added, Neetha, 28 Nov 2k  
 
-static int global_day_night_switch = DAY;
+static int global_day_night_switch = HUD_DAY;
 
 void HUD_masterswitch( bool incr )
 {
     if ( fgGetBool("/sim/hud/visibility") ) {
-       if ( global_day_night_switch == DAY ) {
-           global_day_night_switch = NIGHT;
+       if ( global_day_night_switch == HUD_DAY ) {
+           global_day_night_switch = HUD_NIGHT;
        } else {
            fgSetBool("/sim/hud/visibility", false);
        }
     } else {
         fgSetBool("/sim/hud/visibility", true);
-       global_day_night_switch = DAY;
+       global_day_night_switch = HUD_DAY;
     }  
 }
 
@@ -831,42 +828,42 @@ void HUD_brightkey( bool incr_bright )
        if( incr_bright ) {
            switch (brightness)
                {
-               case BRT_LIGHT:
-                   brightness = BRT_BLACK;
+               case HUD_BRT_LIGHT:
+                   brightness = HUD_BRT_BLACK;
                    break;
 
-               case BRT_MEDIUM:
-                   brightness = BRT_LIGHT;
+               case HUD_BRT_MEDIUM:
+                   brightness = HUD_BRT_LIGHT;
                    break;
 
-               case BRT_DARK:
-                   brightness = BRT_MEDIUM;
+               case HUD_BRT_DARK:
+                   brightness = HUD_BRT_MEDIUM;
                    break;
 
-               case BRT_BLACK:
-                   brightness = BRT_DARK;
+               case HUD_BRT_BLACK:
+                   brightness = HUD_BRT_DARK;
                    break;
 
                default:
-                   brightness = BRT_BLACK;
+                   brightness = HUD_BRT_BLACK;
                }
        } else {
            switch (brightness)
                {
-               case BRT_LIGHT:
-                   brightness = BRT_MEDIUM;
+               case HUD_BRT_LIGHT:
+                   brightness = HUD_BRT_MEDIUM;
                    break;
 
-               case BRT_MEDIUM:
-                   brightness = BRT_DARK;
+               case HUD_BRT_MEDIUM:
+                   brightness = HUD_BRT_DARK;
                    break;
 
-               case BRT_DARK:
-                   brightness = BRT_BLACK;
+               case HUD_BRT_DARK:
+                   brightness = HUD_BRT_BLACK;
                    break;
 
-               case BRT_BLACK:
-                   brightness = BRT_LIGHT;
+               case HUD_BRT_BLACK:
+                   brightness = HUD_BRT_LIGHT;
                    break;
 
                default:
@@ -931,7 +928,7 @@ void fgHUDalphaInit( void ) {
     char *s;
 
     int labelX = (DialogWidth / 2) -
-        (puGetStringWidth( puGetDefaultLabelFont(), Label ) / 2);
+        ( puGetDefaultLabelFont().getStringWidth( Label ) / 2);
        
     int nSliders = 1;
     int slider_x = 10;
@@ -946,8 +943,8 @@ void fgHUDalphaInit( void ) {
     puGetDefaultFonts ( &HUDalphaLegendFont, &HUDalphaLabelFont );
        
     HUDalphaDialog = new puDialogBox ( DialogX, DialogY ); {
-        int horiz_slider_height = puGetStringHeight (HUDalphaLabelFont) +
-            puGetStringDescender (HUDalphaLabelFont) +
+        int horiz_slider_height = HUDalphaLabelFont.getStringHeight() +
+            HUDalphaLabelFont.getStringDescender() +
             PUSTR_TGAP + PUSTR_BGAP + 5;
 
         /* puFrame *
@@ -998,6 +995,7 @@ void fgHUDalphaInit( void ) {
 
 
 void fgHUDReshape(void) {
+#if 0
     if ( HUDtext ) {
         // this chunk of code is not necessarily thread safe if the
         // compiler optimizer reorders these statements.  Note that
@@ -1014,6 +1012,7 @@ void fgHUDReshape(void) {
     HUDtext -> setFont      ( guiFntHandle ) ;
     HUDtext -> setPointSize ( HUD_TextSize ) ;
     HUD_TextList.setFont( HUDtext );
+#endif
 }
 
 
@@ -1032,6 +1031,13 @@ static void set_hud_color(float r, float g, float b) {
 //
 void fgUpdateHUD( void ) {
        
+    static const SGPropertyNode *enable3d_node = fgGetNode("/sim/hud/enable3d");
+    if( HUD_style == 1 && enable3d_node->getBoolValue() )
+    {
+        fgUpdateHUDVirtual();
+        return;
+    }
+    
     static const float normal_aspect = float(640) / float(480);
     // note: aspect_ratio is Y/X
     float current_aspect = 1.0f/globals->get_current_view()->get_aspect_ratio();
@@ -1046,69 +1052,128 @@ void fgUpdateHUD( void ) {
     }
 }
 
-void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
-                  GLfloat x_end, GLfloat y_end )
+void fgUpdateHUDVirtual()
 {
-    int brightness;
-    // int day_night_sw = current_aircraft.controls->day_night_switch;
-    int day_night_sw = global_day_night_switch;
-    int hud_displays = HUD_deque.size();
-    instr_item *pHUDInstr;
-    // float line_width;
-
-    if( !hud_displays ) {  // Trust everyone, but ALWAYS cut the cards!
-        return;
-    }
+    FGViewer* view = globals->get_current_view();
 
-    HUD_TextList.erase();
-    HUD_LineList.erase();
-    // HUD_StippleLineList.erase();
+    // Standard fgfs projection, with essentially meaningless clip
+    // planes (we'll map the whole HUD plane to z=-1)
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    gluPerspective(view->get_v_fov(), 1/view->get_aspect_ratio(), 0.1, 10);
+
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
   
-    pHUDInstr = HUD_deque[0];
-    brightness = pHUDInstr->get_brightness();
-    // brightness = HUD_deque.at(0)->get_brightness();
+    // Standard fgfs view direction computation
+    float lookat[3];
+    lookat[0] = -sin(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
+    lookat[1] = tan(SG_DEGREES_TO_RADIANS * view->getPitchOffset_deg());
+    lookat[2] = -cos(SG_DEGREES_TO_RADIANS * view->getHeadingOffset_deg());
+    if(fabs(lookat[1]) > 9999) lookat[1] = 9999; // FPU sanity
+    gluLookAt(0, 0, 0, lookat[0], lookat[1], lookat[2], 0, 1, 0);
+
+    // Map the -1:1 square to a 55.0x41.25 degree wide patch at z=1.
+    // This is the default fgfs field of view, which the HUD files are
+    // written to assume.
+    float dx = 0.52056705; // tan(55/2)
+    float dy = dx * 0.75;  // assumes 4:3 aspect ratio
+    float m[16];
+    m[0] = dx; m[4] =  0; m[ 8] = 0; m[12] = 0;
+    m[1] =  0; m[5] = dy; m[ 9] = 0; m[13] = 0;
+    m[2] =  0; m[6] =  0; m[10] = 1; m[14] = 0;
+    m[3] =  0; m[7] =  0; m[11] = 0; m[15] = 1;
+    glMultMatrixf(m);
+
+    // Convert the 640x480 "HUD standard" coordinate space to a square
+    // about the origin in the range [-1:1] at depth of -1
+    glScalef(1./320, 1./240, 1);
+    glTranslatef(-320, -240, -1);
+
+    // Do the deed
+    drawHUD();
+
+    // Clean up our mess
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+}
 
+void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
+                  GLfloat x_end, GLfloat y_end )
+{
     glMatrixMode(GL_PROJECTION);
     glPushMatrix();
-
     glLoadIdentity();
     gluOrtho2D(x_start, x_end, y_start, y_end);
+
     glMatrixMode(GL_MODELVIEW);
     glPushMatrix();
     glLoadIdentity();
 
+    drawHUD();
+
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+}
+
+void drawHUD()
+{
+    if( !HUD_deque.size() ) {  // Trust everyone, but ALWAYS cut the cards!
+        return;
+    }
+
+    HUD_TextList.erase();
+    HUD_LineList.erase();
+    // HUD_StippleLineList.erase();
+  
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_LIGHTING);
 
-    static const SGPropertyNode * antialiased_node
-        = fgGetNode("/sim/hud/antialiased");
+    static const SGPropertyNode *antialiased_node
+        = fgGetNode("/sim/hud/antialiased", true);
+    static const SGPropertyNode *heading_enabled
+        = fgGetNode("/autopilot/locks/heading", true);
+    static const SGPropertyNode *altitude_enabled
+        = fgGetNode("/autopilot/locks/altitude", true);
+
+    static char hud_hdg_text[256];
+    static char hud_wp0_text[256];
+    static char hud_wp1_text[256];
+    static char hud_wp2_text[256];
+    static char hud_alt_text[256];
 
     if( antialiased_node->getBoolValue() ) {
         glEnable(GL_LINE_SMOOTH);
         //       glEnable(GL_BLEND);
         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
         glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);
-        glLineWidth(1.5);
+        glLineWidth(2.0);
     } else {
         glLineWidth(1.0);
     }
 
-    if( day_night_sw == DAY) {
-        switch (brightness)
+    if( global_day_night_switch == HUD_DAY) {
+        switch (HUD_deque[0]->get_brightness())
             {
-            case BRT_LIGHT:
+            case HUD_BRT_LIGHT:
                 set_hud_color (0.1f, 0.9f, 0.1f);
                 break;
 
-            case BRT_MEDIUM:
+            case HUD_BRT_MEDIUM:
                 set_hud_color (0.1f, 0.7f, 0.0f);
                 break;
 
-            case BRT_DARK:
+            case HUD_BRT_DARK:
                 set_hud_color (0.0f, 0.6f, 0.0f);
                 break;
 
-            case BRT_BLACK:
+            case HUD_BRT_BLACK:
                 set_hud_color( 0.0f, 0.0f, 0.0f);
                 break;
 
@@ -1116,22 +1181,22 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
                 set_hud_color (0.1f, 0.9f, 0.1f);
             }
     } else {
-        if( day_night_sw == NIGHT) {
-            switch (brightness)
+        if( global_day_night_switch == HUD_NIGHT) {
+            switch (HUD_deque[0]->get_brightness())
                 {
-                case BRT_LIGHT:
+                case HUD_BRT_LIGHT:
                     set_hud_color (0.9f, 0.1f, 0.1f);
                     break;
 
-                case BRT_MEDIUM:
+                case HUD_BRT_MEDIUM:
                     set_hud_color (0.7f, 0.0f, 0.1f);
                     break;
 
-                case BRT_DARK:
+                case HUD_BRT_DARK:
                     set_hud_color (0.6f, 0.0f, 0.0f);
                     break;
 
-                case BRT_BLACK:
+                case HUD_BRT_BLACK:
                     set_hud_color( 0.0f, 0.0f, 0.0f);
                     break;
 
@@ -1143,74 +1208,63 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
         }
     }
 
-    deque < instr_item * > :: iterator current = HUD_deque.begin();
-    deque < instr_item * > :: iterator last = HUD_deque.end();
-
-    for ( ; current != last; ++current ) {
-        pHUDInstr = *current;
-
-        if( pHUDInstr->enabled()) {
-            //  fgPrintf( SG_COCKPIT, SG_DEBUG, "HUD Code %d  Status %d\n",
-            //            hud->code, hud->status );
-            pHUDInstr->draw();
-                 
-        }
-    }
-
-    char *gmt_str = get_formated_gmt_time();
-    HUD_TextList.add( fgText(40, 10, gmt_str, 0) );
+    for_each(HUD_deque.begin(), HUD_deque.end(), HUDdraw());
 
-#ifdef FG_NETWORK_OLK
-    if ( net_hud_display ) {
-        net_hud_update();
-    }
-#endif
+    HUD_TextList.add( fgText(40, 10, get_formated_gmt_time(), 0) );
 
 
-    // temporary
-    // extern bool fgAPAltitudeEnabled( void );
-    // extern bool fgAPHeadingEnabled( void );
-    // extern bool fgAPWayPointEnabled( void );
-    // extern char *fgAPget_TargetDistanceStr( void );
-    // extern char *fgAPget_TargetHeadingStr( void );
-    // extern char *fgAPget_TargetAltitudeStr( void );
-    // extern char *fgAPget_TargetLatLonStr( void );
-
     int apY = 480 - 80;
-    // char scratch[128];
-    // HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) );
-    // apY -= 15;
-    if( current_autopilot->get_HeadingEnabled() ) {
-        HUD_TextList.add( fgText( 40, apY, 
-                                  current_autopilot->get_TargetHeadingStr()) );
+    
+    
+    if (strcmp( heading_enabled->getStringValue(), "dg-heading-hold") == 0 ) {
+        snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
+                  fgGetDouble("/autopilot/settings/heading-bug-deg") );
+        HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
         apY -= 15;
-    }
-    if( current_autopilot->get_AltitudeEnabled() ) {
-        HUD_TextList.add( fgText( 40, apY, 
-                                  current_autopilot->get_TargetAltitudeStr()) );
+    } else if ( strcmp(heading_enabled->getStringValue(), "true-heading-hold") == 0 ) {
+        snprintf( hud_hdg_text, 256, "hdg = %.1f\n",
+                  fgGetDouble("/autopilot/settings/true-heading-deg") );
+        HUD_TextList.add( fgText( 40, apY, hud_hdg_text ) );
         apY -= 15;
-    }
-    if( current_autopilot->get_HeadingMode() == 
-        FGAutopilot::FG_HEADING_WAYPOINT )
-    {
-        char *wpstr;
-        wpstr = current_autopilot->get_TargetWP1Str();
-        if ( strlen( wpstr ) ) {
-            HUD_TextList.add( fgText( 40, apY, wpstr ) );
+
+        string wp0_id = fgGetString( "/autopilot/route-manager/wp[0]/id" );
+        if ( wp0_id.length() > 0 ) {
+            snprintf( hud_wp0_text, 256, "%5s %6.1fnm %s", wp0_id.c_str(), 
+                      fgGetDouble( "/autopilot/route-manager/wp[0]/dist" ),
+                      fgGetString( "/autopilot/route-manager/wp[0]/eta" ) );
+            HUD_TextList.add( fgText( 40, apY, hud_wp0_text ) );
             apY -= 15;
         }
-        wpstr = current_autopilot->get_TargetWP2Str();
-        if ( strlen( wpstr ) ) {
-            HUD_TextList.add( fgText( 40, apY, wpstr ) );
+        string wp1_id = fgGetString( "/autopilot/route-manager/wp[1]/id" );
+        if ( wp1_id.length() > 0 ) {
+            snprintf( hud_wp1_text, 256, "%5s %6.1fnm %s", wp1_id.c_str(), 
+                      fgGetDouble( "/autopilot/route-manager/wp[1]/dist" ),
+                      fgGetString( "/autopilot/route-manager/wp[1]/eta" ) );
+            HUD_TextList.add( fgText( 40, apY, hud_wp1_text ) );
             apY -= 15;
         }
-        wpstr = current_autopilot->get_TargetWP3Str();
-        if ( strlen( wpstr ) ) {
-            HUD_TextList.add( fgText( 40, apY, wpstr ) );
-                apY -= 15;
+        string wp2_id = fgGetString( "/autopilot/route-manager/wp-last/id" );
+        if ( wp2_id.length() > 0 ) {
+            snprintf( hud_wp2_text, 256, "%5s %6.1fnm %s", wp2_id.c_str(), 
+                      fgGetDouble( "/autopilot/route-manager/wp-last/dist" ),
+                      fgGetString( "/autopilot/route-manager/wp-last/eta" ) );
+            HUD_TextList.add( fgText( 40, apY, hud_wp2_text ) );
+            apY -= 15;
         }
     }
   
+    if ( strcmp( altitude_enabled->getStringValue(), "altitude-hold" ) == 0 ) {
+        snprintf( hud_alt_text, 256, "alt = %.0f\n",
+                  fgGetDouble("/autopilot/settings/target-altitude-ft") );
+        HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
+        apY -= 15;
+    } else if ( strcmp( altitude_enabled->getStringValue(), "agl-hold" ) == 0 ){
+        snprintf( hud_alt_text, 256, "agl = %.0f\n",
+                  fgGetDouble("/autopilot/settings/target-agl-ft") );
+        HUD_TextList.add( fgText( 40, apY, hud_alt_text ) );
+        apY -= 15;
+    }
+
     HUD_TextList.draw();
 
     HUD_LineList.draw();
@@ -1228,9 +1282,5 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
 
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_LIGHTING);
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(GL_MODELVIEW);
-    glPopMatrix();
 }