]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_init.cxx
adding changed files for previous commit.
[flightgear.git] / src / Main / fg_init.cxx
index bddcc69f1d00c2c3f8410336a057d577a1a9e5f2..7d3e6ce2859a96c804ab3501dfd246bc73ce06dc 100644 (file)
 #include <simgear/structure/exception.hxx>
 #include <simgear/structure/event_mgr.hxx>
 #include <simgear/misc/sg_path.hxx>
+#include <simgear/misc/sg_dir.hxx>
+#include <simgear/misc/sgstream.hxx>
+
 #include <simgear/misc/interpolator.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/model/particles.hxx>
 #include <simgear/sound/soundmgr_openal.hxx>
-#include <simgear/timing/sg_time.hxx>
-#include <simgear/timing/lowleveltime.h>
 
-#include <Aircraft/aircraft.hxx>
 #include <Aircraft/controls.hxx>
 #include <Aircraft/replay.hxx>
 #include <Airports/apt_loader.hxx>
 
 #include <AIModel/AIManager.hxx>
 
-#if ENABLE_ATCDCL
-#   include <ATCDCL/ATCmgr.hxx>
-#   include <ATCDCL/AIMgr.hxx>
-#   include "ATCDCL/commlist.hxx"
-#else
-#   include "ATC/atcutils.hxx"
-#endif
+#include <ATCDCL/ATCmgr.hxx>
+#include <ATCDCL/commlist.hxx>
+#include <ATC/atis_mgr.hxx>
+#include <ATC/atc_mgr.hxx>
 
 #include <Autopilot/route_mgr.hxx>
-#include <Autopilot/xmlauto.hxx>
-#include <Autopilot/autobrake.hxx>
+#include <Autopilot/autopilotgroup.hxx>
 
-#include <Cockpit/cockpit.hxx>
 #include <Cockpit/panel.hxx>
 #include <Cockpit/panel_io.hxx>
 
-#if ENABLE_SP_FDM
-#include <FDM/SP/ADA.hxx>
-#include <FDM/SP/ACMS.hxx>
-#include <FDM/SP/MagicCarpet.hxx>
-#include <FDM/SP/Balloon.h>
-#endif
-#include <FDM/ExternalNet/ExternalNet.hxx>
-#include <FDM/ExternalPipe/ExternalPipe.hxx>
-#include <FDM/JSBSim/JSBSim.hxx>
-#include <FDM/LaRCsim/LaRCsim.hxx>
-#include <FDM/UFO.hxx>
-#include <FDM/NullFDM.hxx>
-#include <FDM/YASim/YASim.hxx>
 #include <GUI/new_gui.hxx>
-#include <Include/general.hxx>
 #include <Input/input.hxx>
 #include <Instrumentation/instrument_mgr.hxx>
 #include <Model/acmodel.hxx>
+#include <Model/modelmgr.hxx>
 #include <AIModel/submodel.hxx>
 #include <AIModel/AIManager.hxx>
 #include <Navaids/navdb.hxx>
 #include <Navaids/navlist.hxx>
 #include <Navaids/fix.hxx>
 #include <Navaids/fixlist.hxx>
+#include <Navaids/airways.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
 #include <Scripting/NasalSys.hxx>
 #include <Sound/voice.hxx>
 #include <Systems/system_mgr.hxx>
 #include <Time/light.hxx>
-#include <Time/sunsolver.hxx>
-#include <Time/tmp.hxx>
 #include <Traffic/TrafficMgr.hxx>
 #include <MultiPlayer/multiplaymgr.hxx>
+#include <FDM/fdm_shell.hxx>
 
 #include <Environment/environment_mgr.hxx>
-#include <Environment/ridge_lift.hxx>
 
 #include "fg_init.hxx"
 #include "fg_io.hxx"
@@ -158,9 +139,10 @@ static string fgScanForOption( const string& option, int argc, char **argv ) {
     if (hostname == NULL)
     {
         char _hostname[256];
-        gethostname(_hostname, 256);
-        hostname = strdup(_hostname);
-        free_hostname = true;
+        if( gethostname(_hostname, 256) >= 0 ) {
+            hostname = strdup(_hostname);
+            free_hostname = true;
+        }
     }
 
     SG_LOG(SG_GENERAL, SG_INFO, "Scanning command line for: " << option );
@@ -219,10 +201,10 @@ static string fgScanForOption( const string& option, const string& path ) {
 static string fgScanForOption( const string& option ) {
     string arg("");
 
-#if defined( unix ) || defined( __CYGWIN__ )
+#if defined( unix ) || defined( __CYGWIN__ ) || defined(_MSC_VER)
     // Next check home directory for .fgfsrc.hostname file
     if ( arg.empty() ) {
-        if ( homedir != NULL ) {
+        if ( homedir != NULL && hostname != NULL && strlen(hostname) > 0) {
             SGPath config( homedir );
             config.append( ".fgfsrc" );
             config.concat( "." );
@@ -253,7 +235,9 @@ static string fgScanForOption( const string& option ) {
 
 
 // Read in configuration (files and command line options) but only set
-// fg_root
+// fg_root and aircraft_paths, which are needed *before* do_options() is called
+// in fgInitConfig
+
 bool fgInitFGRoot ( int argc, char **argv ) {
     string root;
 
@@ -304,7 +288,7 @@ bool fgInitFGRoot ( int argc, char **argv ) {
 
     SG_LOG(SG_INPUT, SG_INFO, "fg_root = " << root );
     globals->set_fg_root(root);
-
+    
     return true;
 }
 
@@ -312,6 +296,21 @@ bool fgInitFGRoot ( int argc, char **argv ) {
 // Read in configuration (files and command line options) but only set
 // aircraft
 bool fgInitFGAircraft ( int argc, char **argv ) {
+    
+    string aircraftDir = fgScanForOption("--fg-aircraft=", argc, argv);
+    if (aircraftDir.empty()) {
+      aircraftDir =  fgScanForOption("--fg-aircraft="); 
+    }
+
+    const char* envp = ::getenv("FG_AIRCRAFT");
+    if (aircraftDir.empty() && envp) {
+      globals->append_aircraft_paths(envp);
+    }
+    
+    if (!aircraftDir.empty()) {
+      globals->append_aircraft_paths(aircraftDir);
+    }
+    
     string aircraft;
 
     // First parse command line options looking for --aircraft=, this
@@ -488,10 +487,12 @@ do_options (int argc, char ** argv)
     config.append( "system.fgfsrc" );
     fgParseOptions(config.str());
 
-#if defined( unix ) || defined( __CYGWIN__ )
-    config.concat( "." );
-    config.concat( hostname );
-    fgParseOptions(config.str());
+#if defined( unix ) || defined( __CYGWIN__ ) || defined(_MSC_VER)
+    if( hostname != NULL && strlen(hostname) > 0 ) {
+        config.concat( "." );
+        config.concat( hostname );
+        fgParseOptions(config.str());
+    }
 #endif
 
     // Check for ~/.fgfsrc
@@ -501,11 +502,13 @@ do_options (int argc, char ** argv)
         fgParseOptions(config.str());
     }
 
-#if defined( unix ) || defined( __CYGWIN__ )
-    // Check for ~/.fgfsrc.hostname
-    config.concat( "." );
-    config.concat( hostname );
-    fgParseOptions(config.str());
+#if defined( unix ) || defined( __CYGWIN__ ) || defined(_MSC_VER)
+    if( hostname != NULL && strlen(hostname) > 0 ) {
+        // Check for ~/.fgfsrc.hostname
+        config.concat( "." );
+        config.concat( hostname );
+        fgParseOptions(config.str());
+    }
 #endif
 
     // Parse remaining command line options
@@ -513,68 +516,195 @@ do_options (int argc, char ** argv)
     fgParseArgs(argc, argv);
 }
 
-
-static string fgFindAircraftPath( const SGPath &path, const string &aircraft,
-                                  SGPropertyNode *cache, int depth = 0 )
+template <class T>
+bool fgFindAircraftInDir(const SGPath& dirPath, T* obj, bool (T::*pred)(const SGPath& p))
 {
-    const int MAXDEPTH = 1;
+  if (!dirPath.exists()) {
+    SG_LOG(SG_GENERAL, SG_WARN, "fgFindAircraftInDir: no such path:" << dirPath.str());
+    return false;
+  }
+    
+  bool recurse = true;
+  simgear::Dir dir(dirPath);
+  simgear::PathList setFiles(dir.children(simgear::Dir::TYPE_FILE, "-set.xml"));
+  simgear::PathList::iterator p;
+  for (p = setFiles.begin(); p != setFiles.end(); ++p) {
+    // check file name ends with -set.xml
+    
+    // if we found a -set.xml at this level, don't recurse any deeper
+    recurse = false;
+    
+    bool done = (obj->*pred)(*p);
+    if (done) {
+      return true;
+    }
+  } // of -set.xml iteration
+  
+  if (!recurse) {
+    return false;
+  }
+  
+  simgear::PathList subdirs(dir.children(simgear::Dir::TYPE_DIR | simgear::Dir::NO_DOT_OR_DOTDOT));
+  for (p = subdirs.begin(); p != subdirs.end(); ++p) {
+    if (p->file() == "CVS") {
+      continue;
+    }
+    
+    if (fgFindAircraftInDir(*p, obj, pred)) {
+      return true;
+    }
+  } // of subdirs iteration
+  
+  return false;
+}
 
-    ulDirEnt* dire;
-    ulDir *dirp = ulOpenDir(path.str().c_str());
-    if (dirp == NULL) {
-        cerr << "Unable to open aircraft directory '" << path.str() << '\'' << endl;
-        exit(-1);
+template <class T>
+void fgFindAircraft(T* obj, bool (T::*pred)(const SGPath& p))
+{
+  const string_list& paths(globals->get_aircraft_paths());
+  string_list::const_iterator it = paths.begin();
+  for (; it != paths.end(); ++it) {
+    bool done = fgFindAircraftInDir(SGPath(*it), obj, pred);
+    if (done) {
+      return;
     }
+  } // of aircraft paths iteration
+  
+  // if we reach this point, search the default location (always last)
+  SGPath rootAircraft(globals->get_fg_root());
+  rootAircraft.append("Aircraft");
+  fgFindAircraftInDir(rootAircraft, obj, pred);
+}
 
-    string result;
-    while ((dire = ulReadDir(dirp)) != NULL) {
-        if (dire->d_isdir) {
-            if (depth > MAXDEPTH)
-                continue;
+class FindAndCacheAircraft
+{
+public:
+  FindAndCacheAircraft(SGPropertyNode* autoSave)
+  {
+    _cache = autoSave->getNode("sim/startup/path-cache", true);
+  }
+  
+  bool loadAircraft()
+  {
+    std::string aircraft = fgGetString( "/sim/aircraft", "");
+    if (aircraft.empty()) {
+      SG_LOG(SG_GENERAL, SG_ALERT, "no aircraft specified");
+      return false;
+    }
+    
+    _searchAircraft = aircraft + "-set.xml";
+    if (!checkCache()) {
+      // prepare cache for re-scan
+      SGPropertyNode *n = _cache->getNode("fg-root", true);
+      n->setStringValue(globals->get_fg_root().c_str());
+      n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+      n = _cache->getNode("fg-aircraft", true);
+      n->setStringValue(getAircraftPaths().c_str());
+      n->setAttribute(SGPropertyNode::USERARCHIVE, true);
+      _cache->removeChildren("aircraft");
+  
+      fgFindAircraft(this, &FindAndCacheAircraft::checkAircraft);
+    }
+    
+    if (_foundPath.str().empty()) {
+      SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find specified aircraft: " << aircraft );
+      return false;
+    }
+    
+    SG_LOG(SG_GENERAL, SG_INFO, "Loading aircraft -set file from:" << _foundPath.str());
+    fgSetString( "/sim/aircraft-dir", _foundPath.dir().c_str());
+    if (!_foundPath.exists()) {
+      SG_LOG(SG_GENERAL, SG_ALERT, "Unable to find -set file:" << _foundPath.str());
+      return false;
+    }
+    
+    try {
+      readProperties(_foundPath.str(), globals->get_props());
+    } catch ( const sg_exception &e ) {
+      SG_LOG(SG_INPUT, SG_ALERT, "Error reading aircraft: " << e.getFormattedMessage());
+      return false;
+    }
+    
+    return true;
+  }
+  
+private:
+  SGPath getAircraftPaths() {
+    string_list pathList = globals->get_aircraft_paths();
+    SGPath aircraftPaths;
+    string_list::const_iterator it = pathList.begin();
+    if (it != pathList.end()) {
+        aircraftPaths.set(*it);
+        it++;
+    }
+    for (; it != pathList.end(); ++it) {
+        aircraftPaths.add(*it);
+    }
+    return aircraftPaths;
+  }
+  
+  bool checkCache()
+  {
+    if (globals->get_fg_root() != _cache->getStringValue("fg-root", "")) {
+      return false; // cache mismatch
+    }
 
-            if (!strcmp("CVS", dire->d_name) || !strcmp(".", dire->d_name)
-                    || !strcmp("..", dire->d_name) || !strcmp("AI", dire->d_name))
-                continue;
+    if (getAircraftPaths().str() != _cache->getStringValue("fg-aircraft", "")) {
+      return false; // cache mismatch
+    }
+    
+    vector<SGPropertyNode_ptr> cache = _cache->getChildren("aircraft");
+    for (unsigned int i = 0; i < cache.size(); i++) {
+      const char *name = cache[i]->getStringValue("file", "");
+      if (!boost::equals(_searchAircraft, name, is_iequal())) {
+        continue;
+      }
+      
+      SGPath xml(cache[i]->getStringValue("path", ""));
+      xml.append(name);
+      if (xml.exists()) {
+        _foundPath = xml;
+        return true;
+      } 
+      
+      return false;
+    } // of aircraft in cache iteration
+    
+    return false;
+  }
+  
+  bool checkAircraft(const SGPath& p)
+  {
+    // create cache node
+    int i = 0;
+    while (1) {
+        if (!_cache->getChild("aircraft", i++, false))
+            break;
+    }
+    
+    SGPropertyNode *n, *entry = _cache->getChild("aircraft", --i, true);
 
-            SGPath next = path;
-            next.append(dire->d_name);
+    std::string fileName(p.file());
+    n = entry->getNode("file", true);
+    n->setStringValue(fileName);
+    n->setAttribute(SGPropertyNode::USERARCHIVE, true);
 
-            result = fgFindAircraftPath( next, aircraft, cache, depth + 1 );
-            if ( ! result.empty() )
-                break;
+    n = entry->getNode("path", true);
+    n->setStringValue(p.dir());
+    n->setAttribute(SGPropertyNode::USERARCHIVE, true);
 
-        } else {
-            int len = strlen(dire->d_name);
-            if (len < 9 || strcmp(dire->d_name + len - 8, "-set.xml"))
-                continue;
-
-            // create cache node
-            int i = 0;
-            while (1)
-                if (!cache->getChild("aircraft", i++, false))
-                    break;
-
-            SGPropertyNode *n, *entry = cache->getChild("aircraft", --i, true);
-
-            n = entry->getNode("file", true);
-            n->setStringValue(dire->d_name);
-            n->setAttribute(SGPropertyNode::USERARCHIVE, true);
-
-            n = entry->getNode("path", true);
-            n->setStringValue(path.str().c_str());
-            n->setAttribute(SGPropertyNode::USERARCHIVE, true);
-
-            if ( boost::equals(dire->d_name, aircraft.c_str(), is_iequal()) ) {
-                result = path.str();
-                break;
-            }
-        }
+    if ( boost::equals(fileName, _searchAircraft.c_str(), is_iequal()) ) {
+        _foundPath = p;
+        return true;
     }
 
-    ulCloseDir(dirp);
-    return result;
-}
-
+    return false;
+  }
+  
+  std::string _searchAircraft;
+  SGPath _foundPath;
+  SGPropertyNode* _cache;
+};
 
 // Read in configuration (file and command line)
 bool fgInitConfig ( int argc, char **argv ) {
@@ -620,77 +750,22 @@ bool fgInitConfig ( int argc, char **argv ) {
         home->setAttribute(SGPropertyNode::WRITE, false);
 
         config.append( "autosave.xml" );
-        SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << config.str());
-        try {
-            readProperties(config.str(), &autosave, SGPropertyNode::USERARCHIVE);
-        } catch (...) {
-            SG_LOG(SG_INPUT, SG_DEBUG, "First time reading user settings");
+        if (config.exists()) {
+          SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from " << config.str());
+          try {
+              readProperties(config.str(), &autosave, SGPropertyNode::USERARCHIVE);
+          } catch (sg_exception& e) {
+              SG_LOG(SG_INPUT, SG_WARN, "failed to read user settings:" << e.getMessage()
+                << "(from " << e.getOrigin() << ")");
+          }
         }
-        SG_LOG(SG_INPUT, SG_DEBUG, "Finished Reading user settings");
     }
-    SGPropertyNode *cache_root = autosave.getNode("sim/startup/path-cache", true);
-
-
+    
     // Scan user config files and command line for a specified aircraft.
     fgInitFGAircraft(argc, argv);
-
-    string aircraft = fgGetString( "/sim/aircraft", "" );
-    if ( aircraft.size() > 0 ) {
-        SGPath aircraft_search( globals->get_fg_root() );
-        aircraft_search.append( "Aircraft" );
-
-        string aircraft_set = aircraft + "-set.xml";
-        string result;
-
-        // check if the *-set.xml file is already in the cache
-        if (globals->get_fg_root() == cache_root->getStringValue("fg-root", "")) {
-            vector<SGPropertyNode_ptr> cache = cache_root->getChildren("aircraft");
-            for (unsigned int i = 0; i < cache.size(); i++) {
-                const char *name = cache[i]->getStringValue("file", "");
-                if (boost::equals(aircraft_set, name, is_iequal())) {
-                    const char *path = cache[i]->getStringValue("path", "");
-                    SGPath xml(path);
-                    xml.append(name);
-                    if (xml.exists())
-                        result = path;
-                    break;
-                }
-            }
-        }
-
-        if (result.empty()) {
-            // prepare cache for rescan
-            SGPropertyNode *n = cache_root->getNode("fg-root", true);
-            n->setStringValue(globals->get_fg_root().c_str());
-            n->setAttribute(SGPropertyNode::USERARCHIVE, true);
-            cache_root->removeChildren("aircraft");
-
-            result = fgFindAircraftPath( aircraft_search, aircraft_set, cache_root );
-        }
-
-        if ( !result.empty() ) {
-            fgSetString( "/sim/aircraft-dir", result.c_str() );
-            SGPath full_name( result );
-            full_name.append( aircraft_set );
-
-            SG_LOG(SG_INPUT, SG_INFO, "Reading default aircraft: " << aircraft
-                   << " from " << full_name.str());
-            try {
-                readProperties( full_name.str(), globals->get_props() );
-            } catch ( const sg_exception &e ) {
-                string message = "Error reading default aircraft: ";
-                message += e.getFormattedMessage();
-                SG_LOG(SG_INPUT, SG_ALERT, message);
-                exit(2);
-            }
-        } else {
-            SG_LOG( SG_INPUT, SG_ALERT, "Cannot find specified aircraft: "
-                    << aircraft );
-            return false;
-        }
-
-    } else {
-        SG_LOG( SG_INPUT, SG_ALERT, "No default aircraft specified" );
+    FindAndCacheAircraft f(&autosave);
+    if (!f.loadAircraft()) {
+      return false;
     }
 
     copyProperties(&autosave, globals->get_props());
@@ -763,7 +838,7 @@ static void fgApplyStartOffset(const SGGeod& aStartPos, double aHeading, double
 }
 
 // Set current_options lon/lat given an airport id and heading (degrees)
-static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
+bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
     if ( id.empty() )
         return false;
 
@@ -1017,15 +1092,8 @@ fgInitNav ()
     fixlist.init( p_fix );  // adds fixes to the DB in positioned.cxx
 
     SG_LOG(SG_GENERAL, SG_INFO, "  Airways");
-    SGPath p_awy( globals->get_fg_root() );
-    p_awy.append( "Navaids/awy.dat" );
-    FGAirwayNetwork *awyNet = new FGAirwayNetwork;
-    //cerr << "Loading Airways" << endl;
-    awyNet->load (p_awy );
-    awyNet->init();
-    //cerr << "initializing airways" << endl;
-    globals->set_airwaynet( awyNet );
-
+    flightgear::Airway::load();
+    
     return true;
 }
 
@@ -1203,248 +1271,11 @@ bool fgInitGeneral() {
     curr->setStringValue(cwd ? cwd : "");
     curr->setAttribute(SGPropertyNode::WRITE, false);
 
-    fgSetBool("/sim/startup/stdout-to-terminal", isatty(1));
-    fgSetBool("/sim/startup/stderr-to-terminal", isatty(2));
+    fgSetBool("/sim/startup/stdout-to-terminal", isatty(1) != 0 );
+    fgSetBool("/sim/startup/stderr-to-terminal", isatty(2) != 0 );
     return true;
 }
 
-
-// Initialize the flight model subsystem.  This just creates the
-// object.  The actual fdm initialization is delayed until we get a
-// proper scenery elevation hit.  This is checked for in main.cxx
-
-void fgInitFDM() {
-
-    if ( cur_fdm_state ) {
-        delete cur_fdm_state;
-        cur_fdm_state = 0;
-    }
-
-    double dt = 1.0 / fgGetInt("/sim/model-hz");
-    string model = fgGetString("/sim/flight-model");
-
-    if ( model == "larcsim" ) {
-        cur_fdm_state = new FGLaRCsim( dt );
-    } else if ( model == "jsb" ) {
-        cur_fdm_state = new FGJSBsim( dt );
-#if ENABLE_SP_FDM
-    } else if ( model == "ada" ) {
-        cur_fdm_state = new FGADA( dt );
-    } else if ( model == "acms" ) {
-        cur_fdm_state = new FGACMS( dt );
-    } else if ( model == "balloon" ) {
-        cur_fdm_state = new FGBalloonSim( dt );
-    } else if ( model == "magic" ) {
-        cur_fdm_state = new FGMagicCarpet( dt );
-#endif
-    } else if ( model == "ufo" ) {
-        cur_fdm_state = new FGUFO( dt );
-    } else if ( model == "external" ) {
-        // external is a synonym for "--fdm=null" and is
-        // maintained here for backwards compatibility
-        cur_fdm_state = new FGNullFDM( dt );
-    } else if ( model.find("network") == 0 ) {
-        string host = "localhost";
-        int port1 = 5501;
-        int port2 = 5502;
-        int port3 = 5503;
-        string net_options = model.substr(8);
-        string::size_type begin, end;
-        begin = 0;
-        // host
-        end = net_options.find( ",", begin );
-        if ( end != string::npos ) {
-            host = net_options.substr(begin, end - begin);
-            begin = end + 1;
-        }
-        // port1
-        end = net_options.find( ",", begin );
-        if ( end != string::npos ) {
-            port1 = atoi( net_options.substr(begin, end - begin).c_str() );
-            begin = end + 1;
-        }
-        // port2
-        end = net_options.find( ",", begin );
-        if ( end != string::npos ) {
-            port2 = atoi( net_options.substr(begin, end - begin).c_str() );
-            begin = end + 1;
-        }
-        // port3
-        end = net_options.find( ",", begin );
-        if ( end != string::npos ) {
-            port3 = atoi( net_options.substr(begin, end - begin).c_str() );
-            begin = end + 1;
-        }
-        cur_fdm_state = new FGExternalNet( dt, host, port1, port2, port3 );
-    } else if ( model.find("pipe") == 0 ) {
-        // /* old */ string pipe_path = model.substr(5);
-        // /* old */ cur_fdm_state = new FGExternalPipe( dt, pipe_path );
-        string pipe_path = "";
-        string pipe_protocol = "";
-        string pipe_options = model.substr(5);
-        string::size_type begin, end;
-        begin = 0;
-        // pipe file path
-        end = pipe_options.find( ",", begin );
-        if ( end != string::npos ) {
-            pipe_path = pipe_options.substr(begin, end - begin);
-            begin = end + 1;
-        }
-        // protocol (last option)
-        pipe_protocol = pipe_options.substr(begin);
-        cur_fdm_state = new FGExternalPipe( dt, pipe_path, pipe_protocol );
-    } else if ( model == "null" ) {
-        cur_fdm_state = new FGNullFDM( dt );
-    } else if ( model == "yasim" ) {
-        cur_fdm_state = new YASim( dt );
-    } else {
-        throw sg_exception(string("Unrecognized flight model '") + model
-               + "', cannot init flight dynamics model.");
-    }
-}
-
-// Initialize view parameters
-void fgInitView() {
-  // force update of model so that viewer can get some data...
-  globals->get_aircraft_model()->update(0);
-  // run update for current view so that data is current...
-  globals->get_viewmgr()->update(0);
-}
-
-
-SGTime *fgInitTime() {
-    // Initialize time
-    static const SGPropertyNode *longitude
-        = fgGetNode("/position/longitude-deg");
-    static const SGPropertyNode *latitude
-        = fgGetNode("/position/latitude-deg");
-    static const SGPropertyNode *cur_time_override
-        = fgGetNode("/sim/time/cur-time-override", true);
-
-    SGPath zone( globals->get_fg_root() );
-    zone.append( "Timezone" );
-    SGTime *t = new SGTime( longitude->getDoubleValue()
-                              * SGD_DEGREES_TO_RADIANS,
-                            latitude->getDoubleValue()
-                              * SGD_DEGREES_TO_RADIANS,
-                            zone.str(),
-                            cur_time_override->getLongValue() );
-
-    globals->set_warp_delta( 0 );
-
-    t->update( 0.0, 0.0,
-               cur_time_override->getLongValue(),
-               globals->get_warp() );
-
-    return t;
-}
-
-
-// set up a time offset (aka warp) if one is specified
-void fgInitTimeOffset() {
-    static const SGPropertyNode *longitude
-        = fgGetNode("/position/longitude-deg");
-    static const SGPropertyNode *latitude
-        = fgGetNode("/position/latitude-deg");
-    static const SGPropertyNode *cur_time_override
-        = fgGetNode("/sim/time/cur-time-override", true);
-
-    // Handle potential user specified time offsets
-    int orig_warp = globals->get_warp();
-    SGTime *t = globals->get_time_params();
-    time_t cur_time = t->get_cur_time();
-    time_t currGMT = sgTimeGetGMT( gmtime(&cur_time) );
-    time_t systemLocalTime = sgTimeGetGMT( localtime(&cur_time) );
-    time_t aircraftLocalTime = 
-        sgTimeGetGMT( fgLocaltime(&cur_time, t->get_zonename() ) );
-    
-    // Okay, we now have several possible scenarios
-    int offset = fgGetInt("/sim/startup/time-offset");
-    string offset_type = fgGetString("/sim/startup/time-offset-type");
-
-    int warp = 0;
-    if ( offset_type == "real" ) {
-        warp = 0;
-    } else if ( offset_type == "dawn" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           90.0, true ); 
-    } else if ( offset_type == "morning" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           75.0, true ); 
-    } else if ( offset_type == "noon" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           0.0, true ); 
-    } else if ( offset_type == "afternoon" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           60.0, false ); 
-     } else if ( offset_type == "dusk" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           90.0, false ); 
-     } else if ( offset_type == "evening" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           100.0, false ); 
-    } else if ( offset_type == "midnight" ) {
-        warp = fgTimeSecondsUntilSunAngle( cur_time,
-                                           longitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           latitude->getDoubleValue()
-                                             * SGD_DEGREES_TO_RADIANS,
-                                           180.0, false ); 
-    } else if ( offset_type == "system-offset" ) {
-        warp = offset;
-       orig_warp = 0;
-    } else if ( offset_type == "gmt-offset" ) {
-        warp = offset - (currGMT - systemLocalTime);
-       orig_warp = 0;
-    } else if ( offset_type == "latitude-offset" ) {
-        warp = offset - (aircraftLocalTime - systemLocalTime);
-       orig_warp = 0;
-    } else if ( offset_type == "system" ) {
-      warp = offset - (systemLocalTime - currGMT) - cur_time;
-    } else if ( offset_type == "gmt" ) {
-        warp = offset - cur_time;
-    } else if ( offset_type == "latitude" ) {
-        warp = offset - (aircraftLocalTime - currGMT)- cur_time; 
-    } else {
-        SG_LOG( SG_GENERAL, SG_ALERT,
-                "FG_TIME::Unsupported offset type " << offset_type );
-        exit( -1 );
-    }
-    globals->set_warp( orig_warp + warp );
-    t->update( longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
-               latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS,
-               cur_time_override->getLongValue(),
-               globals->get_warp() );
-
-    SG_LOG( SG_GENERAL, SG_INFO, "After fgInitTimeOffset(): warp = " 
-            << globals->get_warp() );
-}
-
-
 // This is the top level init routine which calls all the other
 // initialization routines.  If you are adding a subsystem to flight
 // gear, its initialization call should located in this routine.
@@ -1496,16 +1327,6 @@ bool fgInitSubsystems() {
     // Initialize the scenery management subsystem.
     ////////////////////////////////////////////////////////////////////
 
-    if ( globals->get_tile_mgr()->init() ) {
-        // Load the local scenery data
-        double visibility_meters = fgGetDouble("/environment/visibility-m");
-                
-        globals->get_tile_mgr()->update( visibility_meters );
-    } else {
-        SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" );
-        exit(-1);
-    }
-
     globals->get_scenery()->get_scene_graph()
         ->addChild(simgear::Particles::getCommonRoot());
     simgear::GlobalParticleCallback::setSwitch(fgGetNode("/sim/rendering/particles", true));
@@ -1514,12 +1335,7 @@ bool fgInitSubsystems() {
     // Initialize the flight model subsystem.
     ////////////////////////////////////////////////////////////////////
 
-    fgInitFDM();
-        
-    // allocates structures so must happen before any of the flight
-    // model or control parameters are set
-    fgAircraftInit();   // In the future this might not be the case.
-
+    globals->add_subsystem("flight", new FDMShell, SGSubsystemMgr::FDM);
 
     ////////////////////////////////////////////////////////////////////
     // Initialize the weather subsystem.
@@ -1528,34 +1344,20 @@ bool fgInitSubsystems() {
     // Initialize the weather modeling subsystem
     globals->add_subsystem("environment", new FGEnvironmentMgr);
 
-    ////////////////////////////////////////////////////////////////////
-    // Initialize the ridge lift simulation.
-    ////////////////////////////////////////////////////////////////////
-
-    // Initialize the ridgelift subsystem
-    globals->add_subsystem("ridgelift", new FGRidgeLift);
-
     ////////////////////////////////////////////////////////////////////
     // Initialize the aircraft systems and instrumentation (before the
     // autopilot.)
     ////////////////////////////////////////////////////////////////////
 
-    globals->add_subsystem("instrumentation", new FGInstrumentMgr);
-    globals->add_subsystem("systems", new FGSystemMgr);
+    globals->add_subsystem("instrumentation", new FGInstrumentMgr, SGSubsystemMgr::FDM);
+    globals->add_subsystem("systems", new FGSystemMgr, SGSubsystemMgr::FDM);
 
     ////////////////////////////////////////////////////////////////////
     // Initialize the XML Autopilot subsystem.
     ////////////////////////////////////////////////////////////////////
 
-    globals->add_subsystem( "xml-autopilot", new FGXMLAutopilotGroup );
+    globals->add_subsystem( "xml-autopilot", FGXMLAutopilotGroup::createInstance(), SGSubsystemMgr::FDM );
     globals->add_subsystem( "route-manager", new FGRouteMgr );
-    globals->add_subsystem( "autobrake", new FGAutoBrake );
-    
-    ////////////////////////////////////////////////////////////////////
-    // Initialize the view manager subsystem.
-    ////////////////////////////////////////////////////////////////////
-
-    fgInitView();
 
     ////////////////////////////////////////////////////////////////////
     // Initialize the Input-Output subsystem
@@ -1574,95 +1376,72 @@ bool fgInitSubsystems() {
 
     globals->add_subsystem("gui", new NewGUI, SGSubsystemMgr::INIT);
 
-
-    ////////////////////////////////////////////////////////////////////
-    // Initialize the local time subsystem.
+    //////////////////////////////////////////////////////////////////////
+    // Initialize the 2D cloud subsystem.
     ////////////////////////////////////////////////////////////////////
+    fgGetBool("/sim/rendering/bump-mapping", false);
 
-    // update the current timezone each 30 minutes
-    globals->get_event_mgr()->addTask( "fgUpdateLocalTime()",
-                                       &fgUpdateLocalTime, 30*60 );
-    fgInitTimeOffset();                // the environment subsystem needs this
 
 
     ////////////////////////////////////////////////////////////////////
-    // Initialize the lighting subsystem.
+    // Initialise the ATC Manager
+    // Note that this is old stuff, but might be necessesary for the 
+    // current ATIS implementation. Therefore, leave it in here
+    // until the ATIS system is ported over to make use of the ATIS 
+    // sub system infrastructure.
     ////////////////////////////////////////////////////////////////////
 
-    globals->add_subsystem("lighting", new FGLight);
+    SG_LOG(SG_GENERAL, SG_INFO, "  ATC Manager");
+    globals->set_ATC_mgr(new FGATCMgr);
+    globals->get_ATC_mgr()->init(); 
 
-    //////////////////////////////////////////////////////////////////////
-    // Initialize the 2D cloud subsystem.
     ////////////////////////////////////////////////////////////////////
-    fgGetBool("/sim/rendering/bump-mapping", false);
-
-#ifdef ENABLE_AUDIO_SUPPORT
+   // Initialize the ATC subsystem
     ////////////////////////////////////////////////////////////////////
-    // Initialize the sound-effects subsystem.
+    globals->add_subsystem("ATC", new FGATCManager, SGSubsystemMgr::POST_FDM);
     ////////////////////////////////////////////////////////////////////
-    globals->add_subsystem("voice", new FGVoiceMgr);
-#endif
-
-    ////////////////////////////////////////////////////////////////////
-    // Initialise the ATC Manager 
+    // Initialise the ATIS Subsystem
     ////////////////////////////////////////////////////////////////////
+    globals->add_subsystem("atis", new FGAtisManager, SGSubsystemMgr::POST_FDM);
 
-#if ENABLE_ATCDCL
-    SG_LOG(SG_GENERAL, SG_INFO, "  ATC Manager");
-    globals->set_ATC_mgr(new FGATCMgr);
-    globals->get_ATC_mgr()->init(); 
 
     ////////////////////////////////////////////////////////////////////
-    // Initialise the AI Manager 
+    // Initialize multiplayer subsystem
     ////////////////////////////////////////////////////////////////////
 
-    SG_LOG(SG_GENERAL, SG_INFO, "  AI Manager");
-    globals->set_AI_mgr(new FGAIMgr);
-    globals->get_AI_mgr()->init();
-#endif
+    globals->add_subsystem("mp", new FGMultiplayMgr, SGSubsystemMgr::POST_FDM);
+
     ////////////////////////////////////////////////////////////////////
     // Initialise the AI Model Manager
     ////////////////////////////////////////////////////////////////////
     SG_LOG(SG_GENERAL, SG_INFO, "  AI Model Manager");
-    globals->add_subsystem("ai_model", new FGAIManager);
-    globals->add_subsystem("submodel_mgr", new FGSubmodelMgr);
+    globals->add_subsystem("ai_model", new FGAIManager, SGSubsystemMgr::POST_FDM);
+    globals->add_subsystem("submodel_mgr", new FGSubmodelMgr, SGSubsystemMgr::POST_FDM);
 
 
     // It's probably a good idea to initialize the top level traffic manager
     // After the AI and ATC systems have been initialized properly.
     // AI Traffic manager
-    globals->add_subsystem("Traffic Manager", new FGTrafficManager);
-
-
-    ////////////////////////////////////////////////////////////////////
-    // Initialize the cockpit subsystem
-    ////////////////////////////////////////////////////////////////////
-    if( fgCockpitInit( &current_aircraft )) {
-        // Cockpit initialized ok.
-    } else {
-        SG_LOG( SG_GENERAL, SG_ALERT, "Error in Cockpit initialization!" );
-        exit(-1);
-    }
-
+    globals->add_subsystem("Traffic Manager", new FGTrafficManager, SGSubsystemMgr::POST_FDM);
 
     ////////////////////////////////////////////////////////////////////
     // Add a new 2D panel.
     ////////////////////////////////////////////////////////////////////
 
-    string panel_path = fgGetString("/sim/panel/path",
-                                    "Panels/Default/default.xml");
-
-    globals->set_current_panel( fgReadPanel(panel_path) );
-    if (globals->get_current_panel() == 0) {
+    string panel_path(fgGetString("/sim/panel/path"));
+    if (!panel_path.empty()) {
+      FGPanel* p = fgReadPanel(panel_path);
+      if (p) {
+        globals->set_current_panel(p);
+        p->init();
+        p->bind();
+        SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
+      } else {
         SG_LOG( SG_INPUT, SG_ALERT,
                 "Error reading new panel from " << panel_path );
-    } else {
-        SG_LOG( SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path );
-        globals->get_current_panel()->init();
-        globals->get_current_panel()->bind();
+      }
     }
 
-
     ////////////////////////////////////////////////////////////////////
     // Initialize the controls subsystem.
     ////////////////////////////////////////////////////////////////////
@@ -1683,20 +1462,43 @@ bool fgInitSubsystems() {
     ////////////////////////////////////////////////////////////////////
     globals->add_subsystem("replay", new FGReplay);
 
+#ifdef ENABLE_AUDIO_SUPPORT
+    ////////////////////////////////////////////////////////////////////
+    // Initialize the sound-effects subsystem.
+    ////////////////////////////////////////////////////////////////////
+    globals->add_subsystem("voice", new FGVoiceMgr, SGSubsystemMgr::DISPLAY);
+#endif
 
     ////////////////////////////////////////////////////////////////////
-    // Bind and initialize subsystems.
+    // Initialize the lighting subsystem.
     ////////////////////////////////////////////////////////////////////
 
-    globals->get_subsystem_mgr()->bind();
-    globals->get_subsystem_mgr()->init();
+    globals->add_subsystem("lighting", new FGLight, SGSubsystemMgr::DISPLAY);
+    
+    // ordering here is important : Nasal (via events), then models, then views
+    globals->add_subsystem("events", globals->get_event_mgr(), SGSubsystemMgr::DISPLAY);
+    
+    FGAircraftModel* acm = new FGAircraftModel;
+    globals->set_aircraft_model(acm);
+    globals->add_subsystem("aircraft-model", acm, SGSubsystemMgr::DISPLAY);
+
+    FGModelMgr* mm = new FGModelMgr;
+    globals->set_model_mgr(mm);
+    globals->add_subsystem("model-manager", mm, SGSubsystemMgr::DISPLAY);
 
+    FGViewMgr *viewmgr = new FGViewMgr;
+    globals->set_viewmgr( viewmgr );
+    globals->add_subsystem("view-manager", viewmgr, SGSubsystemMgr::DISPLAY);
+
+    globals->add_subsystem("tile-manager", globals->get_tile_mgr(), 
+      SGSubsystemMgr::DISPLAY);
+      
     ////////////////////////////////////////////////////////////////////
-    // Initialize multiplayer subsystem
+    // Bind and initialize subsystems.
     ////////////////////////////////////////////////////////////////////
 
-    globals->set_multiplayer_mgr(new FGMultiplayMgr);
-    globals->get_multiplayer_mgr()->init();
+    globals->get_subsystem_mgr()->bind();
+    globals->get_subsystem_mgr()->init();
 
     ////////////////////////////////////////////////////////////////////////
     // Initialize the Nasal interpreter.
@@ -1713,6 +1515,8 @@ bool fgInitSubsystems() {
     // End of subsystem initialization.
     ////////////////////////////////////////////////////////////////////
 
+    fgSetBool("/sim/initialized", true);
+
     SG_LOG( SG_GENERAL, SG_INFO, endl);
 
                                 // Save the initial state for future
@@ -1722,51 +1526,55 @@ bool fgInitSubsystems() {
     return true;
 }
 
-
+// Reset: this is what the 'reset' command (and hence, GUI) is attached to
 void fgReInitSubsystems()
 {
-    // static const SGPropertyNode *longitude
-    //     = fgGetNode("/sim/presets/longitude-deg");
-    // static const SGPropertyNode *latitude
-    //     = fgGetNode("/sim/presets/latitude-deg");
-    static const SGPropertyNode *altitude
-        = fgGetNode("/sim/presets/altitude-ft");
     static const SGPropertyNode *master_freeze
         = fgGetNode("/sim/freeze/master");
 
-    SG_LOG( SG_GENERAL, SG_INFO,
-            "fgReInitSubsystems(): /position/altitude = "
-            << altitude->getDoubleValue() );
+    SG_LOG( SG_GENERAL, SG_INFO, "fgReInitSubsystems()");
 
+// setup state to begin re-init
     bool freeze = master_freeze->getBoolValue();
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", true);
     }
+    
+    fgSetBool("/sim/signals/reinit", true);
     fgSetBool("/sim/crashed", false);
 
+// do actual re-init steps
+    globals->get_subsystem("flight")->unbind();
+    
+  // reset control state, before restoring initial state; -set or config files
+  // may specify values for flaps, trim tabs, magnetos, etc
+    globals->get_controls()->reset_all();
+        
+    globals->restoreInitialState();
+
+    // update our position based on current presets
+    fgInitPosition();
+    
     // Force reupdating the positions of the ai 3d models. They are used for
     // initializing ground level for the FDM.
     globals->get_subsystem("ai_model")->reinit();
 
     // Initialize the FDM
-    fgInitFDM();
-    
-    // allocates structures so must happen before any of the flight
-    // model or control parameters are set
-    fgAircraftInit();   // In the future this might not be the case.
+    globals->get_subsystem("flight")->reinit();
 
+    // reset replay buffers
+    globals->get_subsystem("replay")->reinit();
+    
     // reload offsets from config defaults
     globals->get_viewmgr()->reinit();
 
-    fgInitView();
-
-    globals->get_controls()->reset_all();
+    globals->get_subsystem("time")->reinit();
 
-    fgUpdateLocalTime();
-
-    // re-init to proper time of day setting
-    fgInitTimeOffset();
+    // need to bind FDMshell again, since we manually unbound it above...
+    globals->get_subsystem("flight")->bind();
 
+// setup state to end re-init
+    fgSetBool("/sim/signals/reinit", false);
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
     }
@@ -1774,58 +1582,119 @@ void fgReInitSubsystems()
 }
 
 
-void reInit(void)  // from gui_local.cxx -- TODO merge with fgReInitSubsystems()
+///////////////////////////////////////////////////////////////////////////////
+// helper object to implement the --show-aircraft command.
+// resides here so we can share the fgFindAircraftInDir template above,
+// and hence ensure this command lists exectly the same aircraft as the normal
+// loading path.
+class ShowAircraft 
 {
-    static SGPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master", true);
-
-    bool freeze = master_freeze->getBoolValue();
-    if (!freeze)
-        master_freeze->setBoolValue(true);
-
-    fgSetBool("/sim/signals/reinit", true);
-    cur_fdm_state->unbind();
-
-    // in case user has changed window size as
-    // restoreInitialState() overwrites these
-    int xsize = fgGetInt("/sim/startup/xsize");
-    int ysize = fgGetInt("/sim/startup/ysize");
-
-    // viewports also needs to be saved/restored as
-    // restoreInitialState() overwrites these
-    SGPropertyNode *guiNode = new SGPropertyNode;
-    SGPropertyNode *cameraNode = new SGPropertyNode;
-    SGPropertyNode *cameraGroupNode = fgGetNode("/sim/rendering/camera-group");
-    copyProperties(cameraGroupNode->getChild("camera"), cameraNode);
-    copyProperties(cameraGroupNode->getChild("gui"), guiNode);
+public:
+  ShowAircraft()
+  {
+    _minStatus = getNumMaturity(fgGetString("/sim/aircraft-min-status", "all"));
+  }
+  
+  
+  void show(const SGPath& path)
+  {
+    fgFindAircraftInDir(path, this, &ShowAircraft::processAircraft);
+  
+    std::sort(_aircraft.begin(), _aircraft.end(), ciLessLibC());
+    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;
+    }
+  }
+  
+private:
+  bool processAircraft(const SGPath& path)
+  {
+    SGPropertyNode root;
+    try {
+       readProperties(path.str(), &root);
+    } catch (sg_exception& ) {
+       return false;
+    }
+  
+    int maturity = 0;
+    string descStr("   ");
+    descStr += path.file();
+  // trim common suffix from file names
+    int nPos = descStr.rfind("-set.xml");
+    if (nPos == (int)(descStr.size() - 8)) {
+      descStr.resize(nPos);
+    }
+    
+    SGPropertyNode *node = root.getNode("sim");
+    if (node) {
+      SGPropertyNode* desc = node->getNode("description");
+      // if a status tag is found, read it in
+      if (node->hasValue("status")) {
+        maturity = getNumMaturity(node->getStringValue("status"));
+      }
+      
+      if (desc) {
+        if (descStr.size() <= 27+3) {
+          descStr.append(29+3-descStr.size(), ' ');
+        } else {
+          descStr += '\n';
+          descStr.append( 32, ' ');
+        }
+        descStr += desc->getStringValue();
+      }
+    } // of have 'sim' node
+    
+    if (maturity < _minStatus) {
+      return false;
+    }
 
-    globals->restoreInitialState();
+    _aircraft.push_back(descStr);
+    return false;
+  }
 
-    // update our position based on current presets
-    fgInitPosition();
 
-    // We don't know how to resize the window, so keep the last values
-    //  for xsize and ysize, and don't use the one set initially
-    fgSetInt("/sim/startup/xsize", xsize);
-    fgSetInt("/sim/startup/ysize", ysize);
+  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[] = {"alpha","beta","early-production","production"}; 
 
-    copyProperties(cameraNode, cameraGroupNode->getChild("camera"));
-    copyProperties(guiNode, cameraGroupNode->getChild("gui"));
+    if (!strcmp(str, "all")) {
+      return 0;
+    }
 
-    delete guiNode;
-    delete cameraNode;
+    for (size_t i=0; i<(sizeof(levels)/sizeof(levels[0]));i++) 
+      if (strcmp(str,levels[i])==0)
+        return i;
 
-    SGTime *t = globals->get_time_params();
-    delete t;
-    t = fgInitTime();
-    globals->set_time_params(t);
+    return 0;
+  }
 
-    fgReInitSubsystems();
+  // recommended in Meyers, Effective STL when internationalization and embedded
+  // NULLs aren't an issue.  Much faster than the STL or Boost lex versions.
+  struct ciLessLibC : public std::binary_function<string, string, bool>
+  {
+    bool operator()(const std::string &lhs, const std::string &rhs) const
+    {
+      return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0;
+    }
+  };
 
-    globals->get_tile_mgr()->update(fgGetDouble("/environment/visibility-m"));
-    globals->get_renderer()->resize(xsize, ysize);
-    fgSetBool("/sim/signals/reinit", false);
+  int _minStatus;
+  string_list _aircraft;
+};
 
-    if (!freeze)
-        master_freeze->setBoolValue(false);
+void fgShowAircraft(const SGPath &path)
+{
+    ShowAircraft s;
+    s.show(path);
+        
+#ifdef _MSC_VER
+    cout << "Hit a key to continue..." << endl;
+    cin.get();
+#endif
 }
 
+