]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/options.cxx
GUI windows are now draggable. This missing feature has annoyed me
[flightgear.git] / src / Main / options.cxx
index 2db0c79a16b72bb1867c07b4eef407261bac2401..0e19d6ee38f6f7f379c5826334d07d2873150ec1 100644 (file)
@@ -26,7 +26,7 @@
 #endif
 
 #include <simgear/compiler.h>
-#include <simgear/misc/exception.hxx>
+#include <simgear/structure/exception.hxx>
 #include <simgear/debug/logstream.hxx>
 
 #include <math.h>              // rint()
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sgstream.hxx>
 #include <simgear/misc/sg_path.hxx>
-#include <simgear/route/route.hxx>
-#include <simgear/route/waypoint.hxx>
 
 // #include <Include/general.hxx>
 // #include <Airports/simple.hxx>
 // #include <Cockpit/cockpit.hxx>
 // #include <FDM/flight.hxx>
 // #include <FDM/UIUCModel/uiuc_aircraftdir.h>
-#ifdef FG_NETWORK_OLK
-#  include <NetworkOLK/network.h>
-#endif
 
+#include <Autopilot/route_mgr.hxx>
 #include <GUI/gui.h>
 
 #include "globals.hxx"
 #include "fg_init.hxx"
 #include "fg_props.hxx"
 #include "options.hxx"
+#include "util.hxx"
 #include "viewmgr.hxx"
 
 
@@ -180,13 +177,14 @@ fgSetDefaults ()
 #else
     fgSetString("/sim/startup/browser-app", "webrun.bat");
 #endif
-    fgSetInt("/sim/log-level", SG_WARN);
+    fgSetString("/sim/logging/priority", "alert");
 
                                // Features
+    fgSetBool("/sim/hud/antialiased", false);
+    fgSetBool("/sim/hud/enable3d", true);
     fgSetBool("/sim/hud/visibility", false);
     fgSetBool("/sim/panel/visibility", true);
     fgSetBool("/sim/sound/audible", true);
-    fgSetBool("/sim/hud/antialiased", false);
 
                                // Flight Model options
     fgSetString("/sim/flight-model", "jsb");
@@ -202,13 +200,15 @@ fgSetDefaults ()
     fgSetBool("/sim/rendering/skyblend", true);
     fgSetBool("/sim/rendering/textures", true);
     fgSetBool("/sim/rendering/wireframe", false);
+    fgSetBool("/sim/rendering/horizon-effect", false);
+    fgSetBool("/sim/rendering/enhanced-lighting", false);
     fgSetBool("/sim/rendering/distance-attenuation", false);
+    fgSetBool("/sim/rendering/specular-highlight", true);
     fgSetInt("/sim/startup/xsize", 800);
     fgSetInt("/sim/startup/ysize", 600);
     fgSetInt("/sim/rendering/bits-per-pixel", 16);
     fgSetString("/sim/view-mode", "pilot");
     fgSetDouble("/sim/current-view/heading-offset-deg", 0);
-    fgSetDouble("/environment/visibility-m", 20000);
 
                                // HUD options
     fgSetString("/sim/startup/units", "feet");
@@ -219,9 +219,6 @@ fgSetDefaults ()
     fgSetString("/sim/startup/time-offset-type", "system-offset");
     fgSetLong("/sim/time/cur-time-override", 0);
 
-    fgSetBool("/sim/networking/network-olk", false);
-    fgSetString("/sim/networking/call-sign", "Johnny");
-
                                 // Freeze options
     fgSetBool("/sim/freeze/master", false);
     fgSetBool("/sim/freeze/position", false);
@@ -238,7 +235,6 @@ fgSetDefaults ()
 
 }
 
-
 static bool
 parse_wind (const string &wind, double * min_hdg, double * max_hdg,
            double * speed, double * gust)
@@ -538,62 +534,19 @@ add_channel( const string& type, const string& channel_str ) {
     return true;
 }
 
-
-static void
-setup_wind (double min_hdg, double max_hdg, double speed, double gust)
-{
-  fgSetDouble("/environment/wind-from-heading-deg", min_hdg);
-  fgSetDouble("/environment/params/min-wind-from-heading-deg", min_hdg);
-  fgSetDouble("/environment/params/max-wind-from-heading-deg", max_hdg);
-  fgSetDouble("/environment/wind-speed-kt", speed);
-  fgSetDouble("/environment/params/base-wind-speed-kt", speed);
-  fgSetDouble("/environment/params/gust-wind-speed-kt", gust);
-
-  SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' << 
-        speed << " knots" << endl);
-
-#ifdef FG_WEATHERCM
-  // convert to fps
-  speed *= SG_NM_TO_METER * SG_METER_TO_FEET * (1.0/3600);
-  while (min_hdg > 360)
-    min_hdg -= 360;
-  while (min_hdg <= 0)
-    min_hdg += 360;
-  min_hdg *= SGD_DEGREES_TO_RADIANS;
-  fgSetDouble("/environment/wind-from-north-fps", speed * cos(dir));
-  fgSetDouble("/environment/wind-from-east-fps", speed * sin(dir));
-#endif // FG_WEATHERCM
-}
-
+// The parse wp and parse flight-plan options don't work anymore, because 
+// the route manager and the airport subsystems have not yet been initialized
+// at this stage. 
 
 // Parse --wp=ID[@alt]
-static bool 
+static void 
 parse_wp( const string& arg ) {
-    string id, alt_str;
-    double alt = 0.0;
-
-    string::size_type pos = arg.find( "@" );
-    if ( pos != string::npos ) {
-       id = arg.substr( 0, pos );
-       alt_str = arg.substr( pos + 1 );
-       // cout << "id str = " << id << "  alt str = " << alt_str << endl;
-       alt = atof( alt_str.c_str() );
-       if ( !strcmp(fgGetString("/sim/startup/units"), "feet") ) {
-           alt *= SG_FEET_TO_METER;
-       }
-    } else {
-       id = arg;
-    }
-
-    FGAirport a;
-    if ( fgFindAirportID( id, &a ) ) {
-       SGWayPoint wp( a.longitude, a.latitude, alt, SGWayPoint::WGS84, id );
-       globals->get_route()->add_waypoint( wp );
-
-       return true;
-    } else {
-       return false;
+    string_list *waypoints = globals->get_initial_waypoints();
+    if (!waypoints) {
+        waypoints = new string_list;
     }
+    waypoints->push_back(arg);
+    globals->set_initial_waypoints(waypoints);
 }
 
 
@@ -601,31 +554,34 @@ parse_wp( const string& arg ) {
 static bool 
 parse_flightplan(const string& arg)
 {
-    sg_gzifstream in(arg.c_str());
-    if ( !in.is_open() ) {
-       return false;
-    }
-    while ( true ) {
-       string line;
-
+  string_list *waypoints = globals->get_initial_waypoints();
+  if (!waypoints)
+    waypoints = new string_list;
+  sg_gzifstream in(arg.c_str());
+  if ( !in.is_open() ) {
+    return false;
+  }
+  while ( true ) {
+    string line;
+    
 #if defined( macintosh )
-        getline( in, line, '\r' );
+    getline( in, line, '\r' );
 #else
-       getline( in, line, '\n' );
+    getline( in, line, '\n' );
 #endif
-
-        // catch extraneous (DOS) line ending character
-        if ( line[line.length() - 1] < 32 ) {
-            line = line.substr( 0, line.length()-1 );
-        }
-
-       if ( in.eof() ) {
-           break;
-       }
-       parse_wp(line);
+    
+    // catch extraneous (DOS) line ending character
+    if ( line[line.length() - 1] < 32 ) {
+      line = line.substr( 0, line.length()-1 );
     }
-
-    return true;
+    
+    if ( in.eof() ) {
+      break;
+    }
+    waypoints->push_back(line);
+  }
+  globals->set_initial_waypoints(waypoints);
+  return true;
 }
 
 static int
@@ -899,15 +855,31 @@ fgOptStartDateGmt( const char *arg )
     return FG_OPTIONS_OK;
 }
 
-#ifdef FG_NETWORK_OLK
 static int
-fgOptNetHud( const char *arg )
+fgSetupProxy( const char *arg )
 {
-    fgSetBool("/sim/hud/net-display", true);
-    net_hud_display = 1;       // FIXME
+    string options = arg;
+    string host, port, auth;
+    unsigned int pos;
+
+    host = port = auth = "";
+    if ((pos = options.find("@")) != string::npos) 
+        auth = options.substr(0, pos++);
+    else
+        pos = 0;
+
+    host = options.substr(pos, options.size());
+    if ((pos = host.find(":")) != string::npos) {
+        port = host.substr(++pos, host.size());
+        host.erase(--pos, host.size());
+    }
+
+    fgSetString("/sim/presets/proxy/host", host.c_str());
+    fgSetString("/sim/presets/proxy/port", port.c_str());
+    fgSetString("/sim/presets/proxy/authentication", auth.c_str());
+
     return FG_OPTIONS_OK;
 }
-#endif
 
 static int
 fgOptTraceRead( const char *arg )
@@ -919,6 +891,33 @@ fgOptTraceRead( const char *arg )
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptLogLevel( const char *arg )
+{
+    fgSetString("/sim/logging/classes", "all");
+    fgSetString("/sim/logging/priority", arg);
+
+    string priority = arg;
+    logbuf::set_log_classes(SG_ALL);
+    if (priority == "bulk") {
+      logbuf::set_log_priority(SG_BULK);
+    } else if (priority == "debug") {
+      logbuf::set_log_priority(SG_DEBUG);
+    } else if (priority == "info") {
+      logbuf::set_log_priority(SG_INFO);
+    } else if (priority == "warn") {
+      logbuf::set_log_priority(SG_WARN);
+    } else if (priority == "alert") {
+      logbuf::set_log_priority(SG_ALERT);
+    } else {
+      SG_LOG(SG_GENERAL, SG_WARN, "Unknown logging priority " << priority);
+    }
+    SG_LOG(SG_GENERAL, SG_DEBUG, "Logging priority is " << priority);
+
+    return FG_OPTIONS_OK;
+}
+
+
 static int
 fgOptTraceWrite( const char *arg )
 {
@@ -955,11 +954,19 @@ fgOptViewOffset( const char *arg )
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptVisibilityMeters( const char *arg )
+{
+    double visibility = atof( arg );
+    fgDefaultWeatherValue("visibility-m", visibility);
+    return FG_OPTIONS_OK;
+}
+
 static int
 fgOptVisibilityMiles( const char *arg )
 {
     double visibility = atof( arg ) * 5280.0 * SG_FEET_TO_METER;
-    fgSetDouble("/environment/visibility-m", visibility);
+    fgDefaultWeatherValue("visibility-m", visibility);
     return FG_OPTIONS_OK;
 }
 
@@ -968,9 +975,9 @@ fgOptRandomWind( const char *arg )
 {
     double min_hdg = sg_random() * 360.0;
     double max_hdg = min_hdg + (20 - sqrt(sg_random() * 400));
-    double speed = 40 - sqrt(sg_random() * 1600.0);
+    double speed = sg_random() * sg_random() * 40;
     double gust = speed + (10 - sqrt(sg_random() * 100));
-    setup_wind(min_hdg, max_hdg, speed, gust);
+    fgSetupWind(min_hdg, max_hdg, speed, gust);
     return FG_OPTIONS_OK;
 }
 
@@ -982,7 +989,33 @@ fgOptWind( const char *arg )
        SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg );
        return FG_OPTIONS_ERROR;
     }
-    setup_wind(min_hdg, max_hdg, speed, gust);
+    fgSetupWind(min_hdg, max_hdg, speed, gust);
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptTurbulence( const char *arg )
+{
+    fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg));
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptCeiling( const char *arg )
+{
+    double elevation, thickness;
+    string spec = arg;
+    string::size_type pos = spec.find(':');
+    if (pos == string::npos) {
+        elevation = atof(spec.c_str());
+        thickness = 2000;
+    } else {
+        elevation = atof(spec.substr(0, pos).c_str());
+        thickness = atof(spec.substr(pos + 1).c_str());
+    }
+    fgSetDouble("/environment/clouds/layer[0]/elevation-ft", elevation);
+    fgSetDouble("/environment/clouds/layer[0]/thickness-ft", thickness);
+    fgSetString("/environment/clouds/layer[0]/coverage", "overcast");
     return FG_OPTIONS_OK;
 }
 
@@ -1015,6 +1048,93 @@ fgOptConfig( const char *arg )
     return FG_OPTIONS_OK;
 }
 
+static bool
+parse_colon (const string &s, double * val1, double * val2)
+{
+    string::size_type pos = s.find(':');
+    if (pos == string::npos) {
+        *val2 = atof(s);
+        return false;
+    } else {
+        *val1 = atof(s.substr(0, pos).c_str());
+        *val2 = atof(s.substr(pos+1).c_str());
+        return true;
+    }
+}
+
+
+static int
+fgOptFailure( const char * arg )
+{
+    string a = arg;
+    if (a == "pitot") {
+        fgSetBool("/systems/pitot/serviceable", false);
+    } else if (a == "static") {
+        fgSetBool("/systems/static/serviceable", false);
+    } else if (a == "vacuum") {
+        fgSetBool("/systems/vacuum/serviceable", false);
+    } else if (a == "electrical") {
+        fgSetBool("/systems/electrical/serviceable", false);
+    } else {
+        SG_LOG(SG_INPUT, SG_ALERT, "Unknown failure mode: " << a);
+        return FG_OPTIONS_ERROR;
+    }
+
+    return FG_OPTIONS_OK;
+}
+
+
+static int
+fgOptNAV1( const char * arg )
+{
+    double radial, freq;
+    if (parse_colon(arg, &radial, &freq))
+        fgSetDouble("/radios/nav[0]/radials/selected-deg", radial);
+    fgSetDouble("/radios/nav[0]/frequencies/selected-mhz", freq);
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptNAV2( const char * arg )
+{
+    double radial, freq;
+    if (parse_colon(arg, &radial, &freq))
+        fgSetDouble("/radios/nav[1]/radials/selected-deg", radial);
+    fgSetDouble("/radios/nav[1]/frequencies/selected-mhz", freq);
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptADF( const char * arg )
+{
+    double rot, freq;
+    if (parse_colon(arg, &rot, &freq))
+        fgSetDouble("/instrumentation/adf/rotation-deg", rot);
+    fgSetDouble("/instrumentation/adf/frequencies/selected-khz", freq);
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptDME( const char *arg )
+{
+    string opt = arg;
+    if (opt == "nav1") {
+        fgSetInt("/instrumentation/dme/switch-position", 1);
+        fgSetString("/instrumentation/dme/frequencies/source",
+                    "/radios/nav[0]/frequencies/selected-mhz");
+    } else if (opt == "nav2") {
+        fgSetInt("/instrumentation/dme/switch-position", 3);
+        fgSetString("/instrumentation/dme/frequencies/source",
+                    "/radios/nav[1]/frequencies/selected-mhz");
+    } else {
+        fgSetInt("/instrumentation/dme/switch-position", 2);
+        fgSetString("/instrumentation/dme/frequencies/source",
+                    "/instrumentation/dme/frequencies/selected-mhz");
+        fgSetString("/instrumentation/dme/frequencies/selected-mhz", arg);
+    }
+    return FG_OPTIONS_OK;
+}
+
 static map<string,size_t> fgOptionMap;
 
 /*
@@ -1072,6 +1192,8 @@ struct OptionDesc {
     {"enable-fuel-freeze",           false, OPTION_BOOL,   "/sim/freeze/fuel", true, "", 0 },
     {"disable-clock-freeze",         false, OPTION_BOOL,   "/sim/freeze/clock", false, "", 0 },
     {"enable-clock-freeze",          false, OPTION_BOOL,   "/sim/freeze/clock", true, "", 0 },
+    {"disable-hud-3d",               false, OPTION_BOOL,   "/sim/hud/enable3d", false, "", 0 },
+    {"enable-hud-3d",                false, OPTION_BOOL,   "/sim/hud/enable3d", true, "", 0 },
     {"disable-anti-alias-hud",       false, OPTION_BOOL,   "/sim/hud/antialiased", false, "", 0 },
     {"enable-anti-alias-hud",        false, OPTION_BOOL,   "/sim/hud/antialiased", true, "", 0 },
     {"control",                      true,  OPTION_STRING, "/sim/control-mode", false, "", 0 },
@@ -1121,9 +1243,15 @@ struct OptionDesc {
     {"in-air",                       false, OPTION_BOOL,   "/sim/presets/onground", false, "", 0 },
     {"fog-disable",                  false, OPTION_STRING, "/sim/rendering/fog", false, "disabled", 0 },
     {"fog-fastest",                  false, OPTION_STRING, "/sim/rendering/fog", false, "fastest", 0 },
-    {"fog-nicest",                   false, OPTION_STRING, "/sim/fog", false, "nicest", 0 },
-    {"disable-distance-attenuation", false, OPTION_BOOL,   "/environment/distance-attenuation", false, "", 0 },
-    {"enable-distance-attenuation",  false, OPTION_BOOL,   "/environment/distance-attenuation", true, "", 0 },
+    {"fog-nicest",                   false, OPTION_STRING, "/sim/rendering/fog", false, "nicest", 0 },
+    {"disable-horizon-effect",       false, OPTION_BOOL,   "/sim/rendering/horizon-effect", false, "", 0 },
+    {"enable-horizon-effect",        false, OPTION_BOOL,   "/sim/rendering/horizon-effect", true, "", 0 },
+    {"disable-enhanced-lighting",    false, OPTION_BOOL,   "/sim/rendering/enhanced-lighting", false, "", 0 },
+    {"enable-enhanced-lighting",     false, OPTION_BOOL,   "/sim/rendering/enhanced-lighting", true, "", 0 },
+    {"disable-distance-attenuation", false, OPTION_BOOL,   "/sim/rendering/distance-attenuation", false, "", 0 },
+    {"enable-distance-attenuation",  false, OPTION_BOOL,   "/sim/rendering/distance-attenuation", true, "", 0 },
+    {"disable-specular-highlight",   false, OPTION_BOOL,   "/sim/rendering/specular-highlight", false, "", 0 },
+    {"enable-specular-highlight",    false, OPTION_BOOL,   "/sim/rendering/specular-highlight", true, "", 0 },
     {"disable-clouds",               false, OPTION_BOOL,   "/environment/clouds/status", false, "", 0 },
     {"enable-clouds",                false, OPTION_BOOL,   "/environment/clouds/status", true, "", 0 },
 #ifdef FG_USE_CLOUDS_3D
@@ -1145,6 +1273,7 @@ struct OptionDesc {
     {"bpp",                          true,  OPTION_FUNC,   "", false, "", fgOptBpp },
     {"units-feet",                   false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 },
     {"units-meters",                 false, OPTION_STRING, "/sim/startup/units", false, "meters", 0 },
+    {"timeofday",                    true,  OPTION_STRING, "/sim/startup/time-offset-type", false, "noon", 0 },
     {"time-offset",                  true,  OPTION_FUNC,   "", false, "", fgOptTimeOffset },
     {"time-match-real",              false, OPTION_STRING, "/sim/startup/time-offset-type", false, "system-offset", 0 },
     {"time-match-local",             false, OPTION_STRING, "/sim/startup/time-offset-type", false, "latitude-offset", 0 },
@@ -1173,29 +1302,33 @@ struct OptionDesc {
     {"ray",                          true,  OPTION_CHANNEL, "", false, "", 0 },
     {"rul",                          true,  OPTION_CHANNEL, "", false, "", 0 },
     {"joyclient",                    true,  OPTION_CHANNEL, "", false, "", 0 },
-#ifdef FG_NETWORK_OLK
-    {"disable-network-olk",          false, OPTION_BOOL,   "/sim/networking/olk", false, "", 0 },
-    {"enable-network-olk",           false, OPTION_BOOL,   "/sim/networking/olk", true, "", 0 },
-    {"net-hud",                      false, OPTION_FUNC,   "", false, "", fgOptNetHud },
-    {"net-id",                       true,  OPTION_STRING, "sim/networking/call-sign", false, "", 0 },
-#endif
+    {"jsclient",                     true,  OPTION_CHANNEL, "", false, "", 0 },
+    {"proxy",                        true,  OPTION_FUNC,    "", false, "", fgSetupProxy },
 #ifdef FG_MPLAYER_AS
     {"callsign",                     true, OPTION_STRING,  "sim/multiplay/callsign", false, "", 0 },
     {"multiplay",                    true,  OPTION_CHANNEL, "", false, "", 0 },
 #endif
     {"trace-read",                   true,  OPTION_FUNC,   "", false, "", fgOptTraceRead },
     {"trace-write",                  true,  OPTION_FUNC,   "", false, "", fgOptTraceWrite },
-    {"log-level",                    true,  OPTION_INT,    "/sim/log-level", false, "", 0 },
+    {"log-level",                    true,  OPTION_FUNC,   "", false, "", fgOptLogLevel },
     {"view-offset",                  true,  OPTION_FUNC,   "", false, "", fgOptViewOffset },
-    {"visibility",                   true,  OPTION_DOUBLE, "/environment/visibility-m", false, "", 0 },
+    {"visibility",                   true,  OPTION_FUNC,   "", false, "", fgOptVisibilityMeters },
     {"visibility-miles",             true,  OPTION_FUNC,   "", false, "", fgOptVisibilityMiles },
     {"random-wind",                  false, OPTION_FUNC,   "", false, "", fgOptRandomWind },
     {"wind",                         true,  OPTION_FUNC,   "", false, "", fgOptWind },
-    {"turbulence",                   true,  OPTION_DOUBLE,  "/environment/turbulence-norm", false, "", 0 },
+    {"turbulence",                   true,  OPTION_FUNC,   "", false, "", fgOptTurbulence },
+    {"ceiling",                      true,  OPTION_FUNC,   "", false, "", fgOptCeiling },
     {"wp",                           true,  OPTION_FUNC,   "", false, "", fgOptWp },
     {"flight-plan",                  true,  OPTION_FUNC,   "", false, "", fgOptFlightPlan },
     {"config",                       true,  OPTION_FUNC,   "", false, "", fgOptConfig },
     {"aircraft",                     true,  OPTION_STRING, "/sim/aircraft", false, "", 0 },
+    {"failure",                      true,  OPTION_FUNC,   "", false, "", fgOptFailure },
+    {"com1",                         true,  OPTION_DOUBLE, "/radios/comm[0]/frequencies/selected-mhz", false, "", 0 },
+    {"com2",                         true,  OPTION_DOUBLE, "/radios/comm[1]/frequencies/selected-mhz", false, "", 0 },
+    {"nav1",                         true,  OPTION_FUNC,   "", false, "", fgOptNAV1 },
+    {"nav2",                         true,  OPTION_FUNC,   "", false, "", fgOptNAV2 },
+    {"adf",                          true,  OPTION_FUNC,   "", false, "", fgOptADF },
+    {"dme",                          true,  OPTION_FUNC,   "", false, "", fgOptDME },
     {0}
 };
 
@@ -1344,7 +1477,10 @@ fgParseArgs (int argc, char **argv)
               verbose = true;
 
             else if (result == FG_OPTIONS_SHOW_AIRCRAFT) {
-               fgShowAircraft();
+               fgOptLogLevel( "alert" );
+               SGPath path( globals->get_fg_root() );
+               path.append("Aircraft");
+               fgShowAircraft(path, true);
                exit(0);
             }
          }
@@ -1357,6 +1493,7 @@ fgParseArgs (int argc, char **argv)
     }
 
     if (help) {
+       fgOptLogLevel( "alert" );
        fgUsage(verbose);
        exit(0);
     }
@@ -1415,6 +1552,7 @@ fgUsage (bool verbose)
 
     SGPropertyNode options_root;
 
+    SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on Windows
     cout << endl;
 
     try {
@@ -1535,19 +1673,17 @@ fgUsage (bool verbose)
         cout << endl;
         cout << "For a complete list of options use --help --verbose" << endl;
     }
+#ifdef _MSC_VER
+    cout << "Hit a key to continue..." << endl;
+    cin.get();
+#endif
 }
 
-// Show available aircraft types
-void fgShowAircraft(void) {
-   vector<string> aircraft;
-
-   SGPath path( globals->get_fg_root() );
-   path.append("Aircraft");
-
+static void fgSearchAircraft(const SGPath &path, string_list &aircraft,
+                             bool recursive)
+{
    ulDirEnt* dire;
-   ulDir *dirp;
-
-   dirp = ulOpenDir(path.c_str());
+   ulDir *dirp = ulOpenDir(path.str().c_str());
    if (dirp == NULL) {
       cerr << "Unable to open aircraft directory." << endl;
       exit(-1);
@@ -1556,7 +1692,17 @@ void fgShowAircraft(void) {
    while ((dire = ulReadDir(dirp)) != NULL) {
       char *ptr;
 
-      if ((ptr = strstr(dire->d_name, "-set.xml")) && ptr[8] == '\0' ) {
+      if (dire->d_isdir) {
+          if (recursive && strcmp("CVS", dire->d_name)
+              && strcmp(".", dire->d_name) && strcmp("..", dire->d_name))
+          {
+              SGPath next = path;
+              next.append(dire->d_name);
+
+              fgSearchAircraft(next, aircraft, true);
+          }
+      } else if ((ptr = strstr(dire->d_name, "-set.xml")) && (ptr[8] == '\0')) {
+
           SGPath afile = path;
           afile.append(dire->d_name);
 
@@ -1576,24 +1722,44 @@ void fgShowAircraft(void) {
           }
 
           char cstr[96];
-          if (strlen(dire->d_name) <= 27)
+          if (strlen(dire->d_name) <= 27) {
              snprintf(cstr, 96, "   %-27s  %s", dire->d_name,
                       (desc) ? desc->getStringValue() : "" );
 
-          else
+          } else {
              snprintf(cstr, 96, "   %-27s\n%32c%s", dire->d_name, ' ',
                       (desc) ? desc->getStringValue() : "" );
+          }
 
           aircraft.push_back(cstr);
       }
    }
 
-   sort(aircraft.begin(), aircraft.end());
-   cout << "Available aircraft:" << endl;
-   for ( unsigned int i = 0; i < aircraft.size(); i++ ) {
-       cout << aircraft[i] << endl;
-   }
-
-   aircraft.clear();
    ulCloseDir(dirp);
 }
+
+
+/*
+ * Search in the current directory, and in on directory deeper
+ * for <aircraft>-set.xml configuration files and show the aircaft name
+ * and the contents of the<description> tag in a sorted manner.
+ *
+ * @parampath the directory to search for configuration files
+ * @param recursive defines whether the directory should be searched recursively
+ */
+void fgShowAircraft(const SGPath &path, bool recursive) {
+    string_list aircraft;
+
+    fgSearchAircraft( path, aircraft, recursive );
+
+    sort(aircraft.begin(), aircraft.end());
+    SG_LOG( SG_GENERAL, SG_ALERT, "" ); // To popup the console on Windows
+    cout << "Available aircraft:" << endl;
+    for ( unsigned int i = 0; i < aircraft.size(); i++ ) {
+        cout << aircraft[i] << endl;
+    }
+#ifdef _MSC_VER
+    cout << "Hit a key to continue..." << endl;
+    cin.get();
+#endif
+}