]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/options.cxx
Merge commit 'refs/merge-requests/1552' of git@gitorious.org:fg/flightgear into next
[flightgear.git] / src / Main / options.cxx
index 518b1babf265bac95b4b86d6c8b401bacffdcfb7..e572ebf84c660b2c1e1a7913506270e7bb052655 100644 (file)
@@ -28,6 +28,8 @@
 #include <simgear/compiler.h>
 #include <simgear/structure/exception.hxx>
 #include <simgear/debug/logstream.hxx>
+#include <simgear/timing/sg_time.hxx>
+#include <simgear/misc/sg_dir.hxx>
 
 #include <math.h>              // rint()
 #include <stdio.h>
 #include <string.h>            // strcmp()
 #include <algorithm>
 
-#include STL_STRING
-
-#include <plib/ul.h>
+#include <iostream>
+#include <string>
 
 #include <simgear/math/sg_random.h>
+#include <simgear/props/props_io.hxx>
 #include <simgear/misc/sgstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/material/mat.hxx>
-
-// #include <Include/general.hxx>
-// #include <Airports/simple.hxx>
-// #include <Cockpit/cockpit.hxx>
-// #include <FDM/flight.hxx>
-
+#include <simgear/sound/soundmgr_openal.hxx>
 #include <Autopilot/route_mgr.hxx>
 #include <GUI/gui.h>
 
 #include "options.hxx"
 #include "util.hxx"
 #include "viewmgr.hxx"
+#include <Main/viewer.hxx>
+#include <simgear/version.h>
 
+using std::string;
+using std::sort;
+using std::cout;
+using std::cerr;
+using std::endl;
 
-SG_USING_STD(string);
-SG_USING_STD(sort);
-SG_USING_NAMESPACE(std);
-
+#ifndef VERSION
+#define VERSION "CVS "__DATE__
+#endif
 
 #define NEW_DEFAULT_MODEL_HZ 120
 
@@ -72,31 +75,22 @@ enum
     FG_OPTIONS_OK = 0,
     FG_OPTIONS_HELP = 1,
     FG_OPTIONS_ERROR = 2,
-    FG_OPTIONS_VERBOSE_HELP = 3,
-    FG_OPTIONS_SHOW_AIRCRAFT = 4
+    FG_OPTIONS_EXIT = 3,
+    FG_OPTIONS_VERBOSE_HELP = 4,
+    FG_OPTIONS_SHOW_AIRCRAFT = 5,
+    FG_OPTIONS_SHOW_SOUND_DEVICES = 6
 };
 
 static double
 atof( const string& str )
 {
-
-#ifdef __MWERKS__
-    // -dw- if ::atof is called, then we get an infinite loop
-    return std::atof( str.c_str() );
-#else
     return ::atof( str.c_str() );
-#endif
 }
 
 static int
 atoi( const string& str )
 {
-#ifdef __MWERKS__
-    // -dw- if ::atoi is called, then we get an infinite loop
-    return std::atoi( str.c_str() );
-#else
     return ::atoi( str.c_str() );
-#endif
 }
 
 /**
@@ -110,7 +104,7 @@ void
 fgSetDefaults ()
 {
     // set a possibly independent location for scenery data
-    char *envp = ::getenv( "FG_SCENERY" );
+    const char *envp = ::getenv( "FG_SCENERY" );
 
     if ( envp != NULL ) {
        // fg_root could be anywhere, so default to environmental
@@ -120,14 +114,15 @@ fgSetDefaults ()
        // Otherwise, default to Scenery being in $FG_ROOT/Scenery
        globals->set_fg_scenery("");
     }
+        
                                // Position (deliberately out of range)
     fgSetDouble("/position/longitude-deg", 9999.0);
     fgSetDouble("/position/latitude-deg", 9999.0);
     fgSetDouble("/position/altitude-ft", -9999.0);
 
                                // Orientation
-    fgSetDouble("/orientation/heading-deg", 270);
-    fgSetDouble("/orientation/roll-deg", 0);
+    fgSetDouble("/orientation/heading-deg", 9999.0);
+    fgSetDouble("/orientation/roll-deg", 0.0);
     fgSetDouble("/orientation/pitch-deg", 0.424);
 
                                // Velocities
@@ -145,8 +140,8 @@ fgSetDefaults ()
     fgSetDouble("/sim/presets/latitude-deg", 9999.0);
     fgSetDouble("/sim/presets/altitude-ft", -9999.0);
 
-    fgSetDouble("/sim/presets/heading-deg", 270);
-    fgSetDouble("/sim/presets/roll-deg", 0);
+    fgSetDouble("/sim/presets/heading-deg", 9999.0);
+    fgSetDouble("/sim/presets/roll-deg", 0.0);
     fgSetDouble("/sim/presets/pitch-deg", 0.424);
 
     fgSetString("/sim/presets/speed-set", "knots");
@@ -189,7 +184,8 @@ fgSetDefaults ()
     fgSetBool("/sim/hud/enable3d", true);
     fgSetBool("/sim/hud/visibility", false);
     fgSetBool("/sim/panel/visibility", true);
-    fgSetBool("/sim/sound/pause", false);
+    fgSetBool("/sim/sound/enabled", true);
+    fgSetBool("/sim/sound/working", true);
 
                                // Flight Model options
     fgSetString("/sim/flight-model", "jsb");
@@ -204,7 +200,7 @@ fgSetDefaults ()
     fgSetBool("/sim/rendering/shading", true);
     fgSetBool("/sim/rendering/skyblend", true);
     fgSetBool("/sim/rendering/textures", true);
-       fgTie( "/sim/rendering/filtering", SGGetTextureFilter, SGSetTextureFilter, false);
+    fgTie( "/sim/rendering/filtering", SGGetTextureFilter, SGSetTextureFilter, false);
     fgSetInt("/sim/rendering/filtering", 1);
     fgSetBool("/sim/rendering/wireframe", false);
     fgSetBool("/sim/rendering/horizon-effect", false);
@@ -494,7 +490,7 @@ parse_fov( const string& arg ) {
     if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
     if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
 
-    fgSetDouble("/sim/current-view/field-of-view", fov);
+    fgSetDouble("/sim/view[0]/config/default-field-of-view-deg", fov);
 
     // printf("parse_fov(): result = %.4f\n", fov);
 
@@ -506,7 +502,7 @@ parse_fov( const string& arg ) {
 //
 // Format is "--protocol=medium,direction,hz,medium_options,..."
 //
-//   protocol = { native, nmea, garmin, AV400, fgfs, rul, pve, etc. }
+//   protocol = { native, nmea, garmin, AV400, AV400Sim, fgfs, rul, pve, etc. }
 //   medium = { serial, socket, file, etc. }
 //   direction = { in, out, bi }
 //   hz = number of times to process channel per second (floating
@@ -529,6 +525,14 @@ parse_fov( const string& arg ) {
 
 static bool
 add_channel( const string& type, const string& channel_str ) {
+    // This check is neccessary to prevent fgviewer from segfaulting when given
+    // weird options. (It doesn't run the full initailization)
+    if(!globals->get_channel_options_list())
+    {
+        SG_LOG(SG_GENERAL, SG_ALERT, "Option " << type << "=" << channel_str
+                                     << " ignored.");
+        return false;
+    }
     SG_LOG(SG_GENERAL, SG_INFO, "Channel string = " << channel_str );
     globals->get_channel_options_list()->push_back( type + "," + channel_str );
     return true;
@@ -567,12 +571,8 @@ parse_flightplan(const string& arg)
 
     while ( true ) {
         string line;
-
-#if defined( macintosh )
-        getline( in, line, '\r' );
-#else
         getline( in, line, '\n' );
-#endif
+
         // catch extraneous (DOS) line ending character
         if ( line[line.length() - 1] < 32 )
             line = line.substr( 0, line.length()-1 );
@@ -773,7 +773,7 @@ fgOptRoc( const char *arg )
 static int
 fgOptFgRoot( const char *arg )
 {
-    globals->set_fg_root(arg);
+    // this option is dealt with by fgInitFGRoot
     return FG_OPTIONS_OK;
 }
 
@@ -784,6 +784,13 @@ fgOptFgScenery( const char *arg )
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptFgAircraft(const char* arg)
+{
+  // this option is dealt with by fgInitFGAircraft
+  return FG_OPTIONS_OK;
+}
+
 static int
 fgOptFov( const char *arg )
 {
@@ -1003,7 +1010,7 @@ fgOptRandomWind( const char *arg )
 static int
 fgOptWind( const char *arg )
 {
-    double min_hdg, max_hdg, speed, gust;
+    double min_hdg = 0.0, max_hdg = 0.0, speed = 0.0, gust = 0.0;
     if (!parse_wind( arg, &min_hdg, &max_hdg, &speed, &gust)) {
        SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg );
        return FG_OPTIONS_ERROR;
@@ -1189,6 +1196,53 @@ fgOptRunway( const char *arg )
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptParking( const char *arg )
+{
+    cerr << "Processing argument " << arg << endl;
+    fgSetString("/sim/presets/parking", arg );
+    fgSetBool  ("/sim/presets/parking-requested", true );
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptVersion( const char *arg )
+{
+    cerr << "FlightGear version: " << VERSION << endl;
+    cerr << "FG_ROOT=" << globals->get_fg_root() << endl;
+    cerr << "FG_HOME=" << fgGetString("/sim/fg-home") << endl;
+    cerr << "FG_SCENERY=";
+
+    int didsome = 0;
+    string_list scn = globals->get_fg_scenery();
+    for (string_list::const_iterator it = scn.begin(); it != scn.end(); it++)
+    {
+        if (didsome) cerr << ":";
+        didsome++;
+        cerr << *it;
+    }
+    cerr << endl;
+    cerr << "SimGear version: " << SG_STRINGIZE(SIMGEAR_VERSION) << endl;
+    cerr << "PLIB version: " << PLIB_VERSION << endl;
+    return FG_OPTIONS_EXIT;
+}
+
+static int
+fgOptFpe(const char* arg)
+{
+    // Actually handled in bootstrap.cxx
+    return FG_OPTIONS_OK;
+}
+
+static int
+fgOptFgviewer(const char* arg)
+{
+    // Actually handled in bootstrap.cxx
+    return FG_OPTIONS_OK;
+}
+
+
+
 static map<string,size_t> fgOptionMap;
 
 /*
@@ -1209,7 +1263,7 @@ where:
              value set to the property if has_param is false
  func      : function called if type==OPTION_FUNC. if has_param is true,
              the value is passed to the function as a string, otherwise,
-             0 is passed. 
+             s_param is passed.
 
     For OPTION_DOUBLE and OPTION_INT, the parameter value is converted into a
     double or an integer and set to the property.
@@ -1220,12 +1274,12 @@ where:
 
 enum OptionType { OPTION_BOOL, OPTION_STRING, OPTION_DOUBLE, OPTION_INT, OPTION_CHANNEL, OPTION_FUNC };
 struct OptionDesc {
-    char *option;
+    const char *option;
     bool has_param;
     enum OptionType type;
-    char *property;
+    const char *property;
     bool b_param;
-    char *s_param;
+    const char *s_param;
     int (*func)( const char * );
     } fgOptionArray[] = {
        
@@ -1241,7 +1295,8 @@ struct OptionDesc {
     {"disable-random-objects",       false, OPTION_BOOL,   "/sim/rendering/random-objects", false, "", 0 },
     {"enable-random-objects",        false, OPTION_BOOL,   "/sim/rendering/random-objects", true, "", 0 },
     {"disable-real-weather-fetch",   false, OPTION_BOOL,   "/environment/params/real-world-weather-fetch", false, "", 0 },
-    {"enable-real-weather-fetch",    false, OPTION_BOOL,   "/environment/params/real-world-weather-fetch", true, "", 0 },
+    {"enable-real-weather-fetch",    false, OPTION_BOOL,   "/environment/params/real-world-weather-fetch", true,  "", 0 },
+    {"metar",                        true,  OPTION_STRING, "/environment/metar/data", false, "", 0 },
     {"disable-ai-models",            false, OPTION_BOOL,   "/sim/ai/enabled", false, "", 0 },
     {"enable-ai-models",             false, OPTION_BOOL,   "/sim/ai/enabled", true, "", 0 },
     {"disable-freeze",               false, OPTION_BOOL,   "/sim/freeze/master", false, "", 0 },
@@ -1262,18 +1317,18 @@ struct OptionDesc {
     {"enable-hud",                   false, OPTION_BOOL,   "/sim/hud/visibility", true, "", 0 },
     {"disable-panel",                false, OPTION_BOOL,   "/sim/panel/visibility", false, "", 0 },
     {"enable-panel",                 false, OPTION_BOOL,   "/sim/panel/visibility", true, "", 0 },
-    {"disable-sound",                false, OPTION_BOOL,   "/sim/sound/pause", true, "", 0 },
-    {"enable-sound",                 false, OPTION_BOOL,   "/sim/sound/pause", false, "", 0 },
+    {"disable-sound",                false, OPTION_BOOL,   "/sim/sound/working", false, "", 0 },
+    {"enable-sound",                 false, OPTION_BOOL,   "/sim/sound/working", true, "", 0 },
+    {"sound-device",                 true,  OPTION_STRING, "/sim/sound/device-name", false, "", 0 },
     {"airport",                      true,  OPTION_STRING, "/sim/presets/airport-id", false, "", 0 },
-    {"airport-id",                   true,  OPTION_STRING, "/sim/presets/airport-id", false, "", 0 },
     {"runway",                       true,  OPTION_FUNC,   "", false, "", fgOptRunway },
     {"vor",                          true,  OPTION_FUNC,   "", false, "", fgOptVOR },
     {"ndb",                          true,  OPTION_FUNC,   "", false, "", fgOptNDB },
     {"carrier",                      true,  OPTION_FUNC,   "", false, "", fgOptCarrier },
     {"parkpos",                      true,  OPTION_FUNC,   "", false, "", fgOptParkpos },
     {"fix",                          true,  OPTION_FUNC,   "", false, "", fgOptFIX },
-    {"offset-distance",              true,  OPTION_DOUBLE, "/sim/presets/offset-distance", false, "", 0 },
-    {"offset-azimuth",               true,  OPTION_DOUBLE, "/sim/presets/offset-azimuth", false, "", 0 },
+    {"offset-distance",              true,  OPTION_DOUBLE, "/sim/presets/offset-distance-nm", false, "", 0 },
+    {"offset-azimuth",               true,  OPTION_DOUBLE, "/sim/presets/offset-azimuth-deg", false, "", 0 },
     {"lon",                          true,  OPTION_FUNC,   "", false, "", fgOptLon },
     {"lat",                          true,  OPTION_FUNC,   "", false, "", fgOptLat },
     {"altitude",                     true,  OPTION_FUNC,   "", false, "", fgOptAltitude },
@@ -1292,6 +1347,7 @@ struct OptionDesc {
     {"roc",                          true,  OPTION_FUNC,   "", false, "", fgOptRoc },
     {"fg-root",                      true,  OPTION_FUNC,   "", false, "", fgOptFgRoot },
     {"fg-scenery",                   true,  OPTION_FUNC,   "", false, "", fgOptFgScenery },
+    {"fg-aircraft",                  true,  OPTION_FUNC,   "", false, "", fgOptFgAircraft },
     {"fdm",                          true,  OPTION_STRING, "/sim/flight-model", false, "", 0 },
     {"aero",                         true,  OPTION_STRING, "/sim/aero", false, "", 0 },
     {"aircraft-dir",                 true,  OPTION_STRING, "/sim/aircraft-dir", false, "", 0 },
@@ -1357,6 +1413,7 @@ struct OptionDesc {
     {"native-gui",                   true,  OPTION_CHANNEL, "", false, "", 0 },
     {"opengc",                       true,  OPTION_CHANNEL, "", false, "", 0 },
     {"AV400",                        true,  OPTION_CHANNEL, "", false, "", 0 },
+    {"AV400Sim",                     true,  OPTION_CHANNEL, "", false, "", 0 },
     {"garmin",                       true,  OPTION_CHANNEL, "", false, "", 0 },
     {"nmea",                         true,  OPTION_CHANNEL, "", false, "", 0 },
     {"generic",                      true,  OPTION_CHANNEL, "", false, "", 0 },
@@ -1384,6 +1441,7 @@ struct OptionDesc {
     {"flight-plan",                  true,  OPTION_FUNC,   "", false, "", fgOptFlightPlan },
     {"config",                       true,  OPTION_FUNC,   "", false, "", fgOptConfig },
     {"aircraft",                     true,  OPTION_STRING, "/sim/aircraft", false, "", 0 },
+    {"vehicle",                      true,  OPTION_STRING, "/sim/aircraft", false, "", 0 },
     {"failure",                      true,  OPTION_FUNC,   "", false, "", fgOptFailure },
     {"com1",                         true,  OPTION_DOUBLE, "/instrumentation/comm[0]/frequencies/selected-mhz", false, "", 0 },
     {"com2",                         true,  OPTION_DOUBLE, "/instrumentation/comm[1]/frequencies/selected-mhz", false, "", 0 },
@@ -1394,6 +1452,10 @@ struct OptionDesc {
     {"min-status",                   true,  OPTION_STRING,  "/sim/aircraft-min-status", false, "all", 0 },
     {"livery",                       true,  OPTION_FUNC,   "", false, "", fgOptLivery },
     {"ai-scenario",                  true,  OPTION_FUNC,   "", false, "", fgOptScenario },
+    {"parking-id",                   true,  OPTION_FUNC,   "", false, "", fgOptParking  },
+    {"version",                      false, OPTION_FUNC,   "", false, "", fgOptVersion },
+    {"enable-fpe",                  false, OPTION_FUNC,   "", false, "", fgOptFpe},
+    {"fgviewer",                    false, OPTION_FUNC,   "", false, "", fgOptFgviewer},
     {0}
 };
 
@@ -1419,22 +1481,29 @@ set_property(const string& arg)
     }
     SGPropertyNode *n = fgGetNode(name.c_str(), true);
 
+    bool writable = n->getAttribute(SGPropertyNode::WRITE);
+    if (!writable)
+        n->setAttribute(SGPropertyNode::WRITE, true);
+
+    bool ret = false;
     if (type.empty())
-        return n->setUnspecifiedValue(value.c_str());
+        ret = n->setUnspecifiedValue(value.c_str());
     else if (type == "s" || type == "string")
-        return n->setStringValue(value.c_str());
+        ret = n->setStringValue(value.c_str());
     else if (type == "d" || type == "double")
-        return n->setDoubleValue(strtod(value.c_str(), 0));
+        ret = n->setDoubleValue(strtod(value.c_str(), 0));
     else if (type == "f" || type == "float")
-        return n->setFloatValue(atof(value.c_str()));
+        ret = n->setFloatValue(atof(value.c_str()));
     else if (type == "l" || type == "long")
-        return n->setLongValue(strtol(value.c_str(), 0, 0));
+        ret =  n->setLongValue(strtol(value.c_str(), 0, 0));
     else if (type == "i" || type == "int")
-        return n->setIntValue(atoi(value.c_str()));
+        ret =  n->setIntValue(atoi(value.c_str()));
     else if (type == "b" || type == "bool")
-        return n->setBoolValue(value == "true" || atoi(value.c_str()) != 0);
+        ret =  n->setBoolValue(value == "true" || atoi(value.c_str()) != 0);
 
-    return false;
+    if (!writable)
+        n->setAttribute(SGPropertyNode::WRITE, false);
+    return ret;
 }
 
 
@@ -1461,6 +1530,8 @@ parse_option (const string& arg)
         return(FG_OPTIONS_VERBOSE_HELP);
     } else if ( arg.find( "--show-aircraft") == 0) {
         return(FG_OPTIONS_SHOW_AIRCRAFT);
+    } else if ( arg.find( "--show-sound-devices") == 0) {
+        return(FG_OPTIONS_SHOW_SOUND_DEVICES);
     } else if ( arg.find( "--prop:" ) == 0 ) {
         if (!set_property(arg.substr(7))) {
             SG_LOG( SG_GENERAL, SG_ALERT, "Bad property assignment: " << arg );
@@ -1468,11 +1539,12 @@ parse_option (const string& arg)
         }
     } else if ( arg.find( "--" ) == 0 ) {
         size_t pos = arg.find( '=' );
-        string arg_name;
+        string arg_name, arg_value;
         if ( pos == string::npos ) {
             arg_name = arg.substr( 2 );
         } else {
             arg_name = arg.substr( 2, pos - 2 );
+            arg_value = arg.substr( pos + 1);
         }
         map<string,size_t>::iterator it = fgOptionMap.find( arg_name );
         if ( it != fgOptionMap.end() ) {
@@ -1482,9 +1554,9 @@ parse_option (const string& arg)
                     fgSetBool( pt->property, pt->b_param );
                     break;
                 case OPTION_STRING:
-                    if ( pt->has_param && pos != string::npos && pos + 1 < arg.size() ) {
-                        fgSetString( pt->property, arg.substr( pos + 1 ).c_str() );
-                    } else if ( !pt->has_param && pos == string::npos ) {
+                    if ( pt->has_param && !arg_value.empty() ) {
+                        fgSetString( pt->property, arg_value.c_str() );
+                    } else if ( !pt->has_param && arg_value.empty() ) {
                         fgSetString( pt->property, pt->s_param );
                     } else if ( pt->has_param ) {
                         SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
@@ -1495,25 +1567,26 @@ parse_option (const string& arg)
                     }
                     break;
                 case OPTION_DOUBLE:
-                    if ( pos != string::npos && pos + 1 < arg.size() ) {
-                        fgSetDouble( pt->property, atof( arg.substr( pos + 1 ) ) );
+                    if ( !arg_value.empty() ) {
+                        fgSetDouble( pt->property, atof( arg_value ) );
                     } else {
                         SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
                         return FG_OPTIONS_ERROR;
                     }
                     break;
                 case OPTION_INT:
-                    if ( pos != string::npos && pos + 1 < arg.size() ) {
-                        fgSetInt( pt->property, atoi( arg.substr( pos + 1 ) ) );
+                    if ( !arg_value.empty() ) {
+                        fgSetInt( pt->property, atoi( arg_value ) );
                     } else {
                         SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
                         return FG_OPTIONS_ERROR;
                     }
                     break;
                 case OPTION_CHANNEL:
-                    if ( pt->has_param && pos != string::npos && pos + 1 < arg.size() ) {
-                        add_channel( pt->option, arg.substr( pos + 1 ) );
-                    } else if ( !pt->has_param && pos == string::npos ) {
+                    // XXX return value of add_channel should be checked?
+                    if ( pt->has_param && !arg_value.empty() ) {
+                        add_channel( pt->option, arg_value );
+                    } else if ( !pt->has_param && arg_value.empty() ) {
                         add_channel( pt->option, pt->s_param );
                     } else if ( pt->has_param ) {
                         SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
@@ -1524,10 +1597,10 @@ parse_option (const string& arg)
                     }
                     break;
                 case OPTION_FUNC:
-                    if ( pt->has_param && pos != string::npos && pos + 1 < arg.size() ) {
-                        return pt->func( arg.substr( pos + 1 ).c_str() );
-                    } else if ( !pt->has_param && pos == string::npos ) {
-                        return pt->func( 0 );
+                    if ( pt->has_param && !arg_value.empty() ) {
+                        return pt->func( arg_value.c_str() );
+                    } else if ( !pt->has_param && arg_value.empty() ) {
+                        return pt->func( pt->s_param );
                     } else if ( pt->has_param ) {
                         SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
                         return FG_OPTIONS_ERROR;
@@ -1558,7 +1631,7 @@ fgParseArgs (int argc, char **argv)
     bool verbose = false;
     bool help = false;
 
-    SG_LOG(SG_GENERAL, SG_INFO, "Processing command line arguments");
+    SG_LOG(SG_GENERAL, SG_ALERT, "Processing command line arguments");
 
     for (int i = 1; i < argc; i++) {
         string arg = argv[i];
@@ -1575,12 +1648,31 @@ fgParseArgs (int argc, char **argv)
               verbose = true;
 
             else if (result == FG_OPTIONS_SHOW_AIRCRAFT) {
-               fgOptLogLevel( "alert" );
-               SGPath path( globals->get_fg_root() );
-               path.append("Aircraft");
-               fgShowAircraft(path, true);
-               exit(0);
+              fgOptLogLevel( "alert" );
+              SGPath path( globals->get_fg_root() );
+              path.append("Aircraft");
+              fgShowAircraft(path);
+              exit(0);
+
+            } else if (result == FG_OPTIONS_SHOW_SOUND_DEVICES) {
+              SGSoundMgr smgr;
+
+              smgr.init();
+              string vendor = smgr.get_vendor();
+              string renderer = smgr.get_renderer();
+              cout << renderer << " provided by " << vendor << endl;
+              cout << endl << "No. Device" << endl;
+
+              vector <const char*>devices = smgr.get_available_devices();
+              for (vector <const char*>::size_type i=0; i<devices.size(); i++) {
+                cout << i << ".  \"" << devices[i] << "\"" << endl;
+              }
+              devices.clear();
+              exit(0);
             }
+
+            else if (result == FG_OPTIONS_EXIT)
+               exit(0);
          }
        } else {
          in_options = false;
@@ -1611,20 +1703,9 @@ fgParseOptions (const string& path) {
     SG_LOG( SG_GENERAL, SG_INFO, "Processing config file: " << path );
 
     in >> skipcomment;
-#ifndef __MWERKS__
     while ( ! in.eof() ) {
-#else
-    char c = '\0';
-    while ( in.get(c) && c != '\0' ) {
-       in.putback(c);
-#endif
        string line;
-
-#if defined( macintosh )
-        getline( in, line, '\r' );
-#else
        getline( in, line, '\n' );
-#endif
 
         // catch extraneous (DOS) line ending character
         int i;
@@ -1775,135 +1856,3 @@ fgUsage (bool verbose)
     cin.get();
 #endif
 }
-
-// A simple function to return an integer depending on the position
-// of the status string within the array in order to determine the hierarchy.
-unsigned int getNumMaturity(const char * str) 
-{
-  // changes should also be reflected in $FG_ROOT/data/options.xml & 
-  // $FG_ROOT/data/Translations/string-default.xml
-  const char levels[][20]= {"alpha","beta","early-production","production",0}; 
-
-  for (unsigned int i=0; i<(sizeof(levels)/sizeof(levels[0])-1);i++) 
-    if (strcmp(str,levels[i])==0)
-      return i;
-
-  return 0;
-};
-
-
-static void fgSearchAircraft(const SGPath &path, string_list &aircraft,
-                             bool recursive)
-{   
-   
-   ulDirEnt* dire;
-   ulDir *dirp = ulOpenDir(path.str().c_str());
-   if (dirp == NULL) {
-      cerr << "Unable to open aircraft directory '" << path.str() << '\'' << endl;
-      exit(-1);
-   }
-
-   while ((dire = ulReadDir(dirp)) != NULL) {
-      char *ptr;
-
-      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);
-
-          *ptr = '\0';
-
-          SGPropertyNode root;
-          try {
-             readProperties(afile.str(), &root);
-          } catch (...) {
-             continue;
-          }
-
-          SGPropertyNode *desc = NULL;
-         SGPropertyNode *status = NULL;
-         
-          SGPropertyNode *node = root.getNode("sim");
-          if (node) {
-             desc = node->getNode("description");
-            // if a status tag is found, read it in
-            if (node->hasValue("status"))
-               status = node->getNode("status");
-          }
-
-          //additionally display status information where it is available
-
-          string descStr("   ");
-          descStr += dire->d_name;
-          if (desc) {
-              if (descStr.size() <= 27+3) {
-                descStr.append(29+3-descStr.size(), ' ');
-              } else {
-                descStr += '\n';
-                descStr.append( 32, ' ');
-              }
-              descStr += desc->getStringValue();
-          }
-  
-          SGPropertyNode * required_status
-                             = fgGetNode ("/sim/aircraft-min-status", true);
-         
-         // If the node holds the value "all", then there wasn't any status 
-         // level specified, so we simply go ahead and output ALL aircraft
-         if (strcmp(required_status->getStringValue(),"all")==0) {        
-                 aircraft.push_back(descStr);
-                 }
-         else
-         {
-         // If the node doesn't hold "all" as its value, then we are supposed
-         // to show only aircraft meeting specific status (development status)
-          // requirements:
-     if (node->hasValue("status"))     {
-         //Compare (minimally) required status level with actual aircraft status:
-          if ( getNumMaturity(status->getStringValue() ) >= 
-               getNumMaturity(required_status->getStringValue() ) )
-                                 aircraft.push_back(descStr); }
-                                                 
-         }
-      
-   
-   }
-   }
-
-   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
-}