X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Ffg_init.cxx;h=10bded7bb6b9970fb9dba081d8c6fc3112ed33c6;hb=86f462933d0d7130e4e688183976620ed2ddb5ae;hp=338e3962d60dc3867ae385f3717af9f37b179ad6;hpb=98c03f95e15da580f1c1442f00198ac670779a18;p=flightgear.git diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 338e3962d..10bded7bb 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -25,11 +25,6 @@ # include #endif -// For BC 5.01 this must be included before OpenGL includes. -#ifdef SG_MATH_EXCEPTION_CLASH -# include -#endif - #include #include #include // strcmp() @@ -37,6 +32,12 @@ #if defined( unix ) || defined( __CYGWIN__ ) # include // for gethostname() #endif +#if defined( _MSC_VER) || defined(__MINGW32__) +# include // for getcwd() +# define getcwd _getcwd +# include // isatty() +# define isatty _isatty +#endif // work around a stdc++ lib bug in some versions of linux, but doesn't // seem to hurt to have this here for all versions of Linux. @@ -46,45 +47,45 @@ #include -#include STL_STRING +#include #include #include #include #include -#include -#include -#include #include #include #include +#include #include #include #include +#include #include #include #include #include +#include + #include -#include -#include -#include +#include +#include #include #include #include #include #include -#ifdef ENABLE_SP_FMDS +#ifdef ENABLE_SP_FDM #include #include +#include +#include #endif -#include #include #include #include #include -#include #include #include #include @@ -97,6 +98,8 @@ #include #include #include +#include +#include #include #include #include @@ -112,6 +115,7 @@ #include #include +#include #include "fg_init.hxx" #include "fg_io.hxx" @@ -120,17 +124,19 @@ #include "options.hxx" #include "globals.hxx" #include "logger.hxx" +#include "renderer.hxx" #include "viewmgr.hxx" #include "main.hxx" +#include "ATCDCL/commlist.hxx" -#if defined(FX) && defined(XMESA) -#include +#ifdef __APPLE__ +# include #endif -SG_USING_STD(string); - +using std::string; class Sound; +class SGSoundMgr; extern const char *default_root; float init_volume; @@ -180,20 +186,9 @@ static string fgScanForOption( const string& option, const string& path ) { int len = option.length(); 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 if ( line[line.length() - 1] < 32 ) { @@ -276,25 +271,21 @@ bool fgInitFGRoot ( int argc, char **argv ) { root = "/FlightGear"; #elif defined( WIN32 ) root = "\\FlightGear"; -#elif defined(OSX_BUNDLE) - /* the following code looks for the base package directly inside - the application bundle. This can be changed fairly easily by - fiddling with the code below. And yes, I know it's ugly and verbose. +#elif defined(__APPLE__) + /* + The following code looks for the base package inside the application + bundle, in the standard Contents/Resources location. */ - CFBundleRef appBundle = CFBundleGetMainBundle(); - CFURLRef appUrl = CFBundleCopyBundleURL(appBundle); - CFRelease(appBundle); + CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - // look for a 'data' subdir directly inside the bundle : is there - // a better place? maybe in Resources? I don't know ... - CFURLRef dataDir = CFURLCreateCopyAppendingPathComponent(NULL, appUrl, CFSTR("data"), true); + // look for a 'data' subdir + CFURLRef dataDir = CFURLCreateCopyAppendingPathComponent(NULL, resourcesUrl, CFSTR("data"), true); // now convert down to a path, and the a c-string CFStringRef path = CFURLCopyFileSystemPath(dataDir, kCFURLPOSIXPathStyle); root = CFStringGetCStringPtr(path, CFStringGetSystemEncoding()); - // tidy up. - CFRelease(appBundle); + CFRelease(resourcesUrl); CFRelease(dataDir); CFRelease(path); #else @@ -317,10 +308,18 @@ bool fgInitFGAircraft ( int argc, char **argv ) { // First parse command line options looking for --aircraft=, this // will override anything specified in a config file aircraft = fgScanForOption( "--aircraft=", argc, argv ); + if ( aircraft.empty() ) { + // check synonym option + aircraft = fgScanForOption( "--vehicle=", argc, argv ); + } // Check in one of the user configuration files. - if ( aircraft.empty() ) + if ( aircraft.empty() ) { aircraft = fgScanForOption( "--aircraft=" ); + } + if ( aircraft.empty() ) { + aircraft = fgScanForOption( "--vehicle=" ); + } // if an aircraft was specified, set the property name if ( !aircraft.empty() ) { @@ -404,18 +403,17 @@ SGPropertyNode *fgInitLocale(const char *language) { const char *d_path_str = d_node->getStringValue("strings"); if (!d_path_str) { - SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file."); + SG_LOG(SG_GENERAL, SG_ALERT, "No path in " << d_node->getPath() << "/strings."); return NULL; } d_path.append(d_path_str); - SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from " - << d_path.str()); + SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from " << d_path.str()); SGPropertyNode *strings = c_node->getNode("strings"); try { readProperties(d_path.str(), strings); - } catch (const sg_exception &e) { + } catch (const sg_exception &) { SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings"); return NULL; } @@ -428,18 +426,18 @@ SGPropertyNode *fgInitLocale(const char *language) { const char *c_path_str = c_node->getStringValue("strings"); if (!c_path_str) { - SG_LOG(SG_GENERAL, SG_ALERT, "Incorrect path in configuration file."); + SG_LOG(SG_GENERAL, SG_ALERT, "No path in " << c_node->getPath() << "/strings"); return NULL; } c_path.append(c_path_str); - SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from " - << c_path.str()); + SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings from " << c_path.str()); try { readProperties(c_path.str(), strings); - } catch (const sg_exception &e) { - SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings"); + } catch (const sg_exception &) { + SG_LOG(SG_GENERAL, SG_ALERT, + "Unable to read the localized strings from " << c_path.str()); return NULL; } } @@ -451,7 +449,7 @@ SGPropertyNode *fgInitLocale(const char *language) { // Initialize the localization routines bool fgDetectLanguage() { - char *language = ::getenv("LANG"); + const char *language = ::getenv("LANG"); if (language == NULL) { SG_LOG(SG_GENERAL, SG_INFO, "Unable to detect the language" ); @@ -507,7 +505,11 @@ do_options (int argc, char ** argv) } -static string fgFindAircraftPath( const SGPath &path, const string &aircraft ) { +static string fgFindAircraftPath( const SGPath &path, const string &aircraft, + SGPropertyNode *cache, int depth = 0 ) +{ + const int MAXDEPTH = 1; + ulDirEnt* dire; ulDir *dirp = ulOpenDir(path.str().c_str()); if (dirp == NULL) { @@ -518,20 +520,45 @@ static string fgFindAircraftPath( const SGPath &path, const string &aircraft ) { string result; while ((dire = ulReadDir(dirp)) != NULL) { if (dire->d_isdir) { - if ( strcmp("CVS", dire->d_name) && strcmp(".", dire->d_name) - && strcmp("..", dire->d_name) && strcmp("AI", dire->d_name)) - { - SGPath next = path; - next.append(dire->d_name); - - result = fgFindAircraftPath( next, aircraft ); - if ( ! result.empty() ) { + if (depth > MAXDEPTH) + continue; + + if (!strcmp("CVS", dire->d_name) || !strcmp(".", dire->d_name) + || !strcmp("..", dire->d_name) || !strcmp("AI", dire->d_name)) + continue; + + SGPath next = path; + next.append(dire->d_name); + + result = fgFindAircraftPath( next, aircraft, cache, depth + 1 ); + if ( ! result.empty() ) + break; + + } 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 ( !strcmp(dire->d_name, aircraft.c_str()) ) { + result = path.str(); + break; } - } else if ( !strcmp(dire->d_name, aircraft.c_str()) ) { - result = path.str(); - break; } } @@ -556,6 +583,45 @@ bool fgInitConfig ( int argc, char **argv ) { return false; } + SGPropertyNode autosave; +#if defined( _MSC_VER ) || defined( __MINGW32__ ) + char *envp = ::getenv( "APPDATA" ); + if (envp != NULL ) { + SGPath config( envp ); + config.append( "flightgear.org" ); +#else + if ( homedir != NULL ) { + SGPath config( homedir ); + config.append( ".fgfs" ); +#endif + const char *fg_home = getenv("FG_HOME"); + if (fg_home) + config = fg_home; + + SGPath home_export(config.str()); + home_export.append("Export/dummy"); + home_export.create_dir(0777); + + // Set /sim/fg-home and don't allow malign code to override it until + // Nasal security is set up. Use FG_HOME if necessary. + SGPropertyNode *home = fgGetNode("/sim", true); + home->removeChild("fg-home", 0, false); + home = home->getChild("fg-home", 0, true); + home->setStringValue(config.c_str()); + 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"); + } + 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); @@ -565,8 +631,34 @@ bool fgInitConfig ( int argc, char **argv ) { 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 cache = cache_root->getChildren("aircraft"); + for (unsigned int i = 0; i < cache.size(); i++) { + const char *name = cache[i]->getStringValue("file", ""); + if (aircraft_set == name) { + 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 ); + } - string result = fgFindAircraftPath( aircraft_search, aircraft_set ); if ( !result.empty() ) { fgSetString( "/sim/aircraft-dir", result.c_str() ); SGPath full_name( result ); @@ -592,27 +684,7 @@ bool fgInitConfig ( int argc, char **argv ) { SG_LOG( SG_INPUT, SG_ALERT, "No default aircraft specified" ); } -#ifdef _MSC_VER - char *envp = ::getenv( "APPDATA" ); - if (envp != NULL ) { - SGPath config( envp ); - config.append( "flightgear.org" ); -#else - if ( homedir != NULL ) { - SGPath config( homedir ); - config.append( ".fgfs" ); -#endif - fgSetString("/sim/fg-home", config.c_str()); - config.append( "autosave.xml" ); - SG_LOG(SG_INPUT, SG_INFO, "Reading user settings from autosave.xml"); - try { - fgLoadProps(config.str().c_str(), globals->get_props(), false, - SGPropertyNode::USERARCHIVE); - } catch (...) { - SG_LOG(SG_INPUT, SG_BULK, "First time reading user settings"); - } - SG_LOG(SG_INPUT, SG_BULK, "Finished Reading user settings"); - } + copyProperties(&autosave, globals->get_props()); // parse options after loading aircraft to ensure any user // overrides of defaults are honored. @@ -621,60 +693,14 @@ bool fgInitConfig ( int argc, char **argv ) { return true; } - - - - -#if 0 - // - // This function is never used, but maybe useful in the future ??? - // - -// Preset lon/lat given an airport id -static bool fgSetPosFromAirportID( const string& id ) { - FGAirport *a; - // double lon, lat; - - SG_LOG( SG_GENERAL, SG_INFO, - "Attempting to set starting position from airport code " << id ); - - if ( fgFindAirportID( id, &a ) ) { - // presets - fgSetDouble("/sim/presets/longitude-deg", a->longitude ); - fgSetDouble("/sim/presets/latitude-deg", a->latitude ); - - // other code depends on the actual postition being set so set - // that as well - fgSetDouble("/position/longitude-deg", a->longitude ); - fgSetDouble("/position/latitude-deg", a->latitude ); - - SG_LOG( SG_GENERAL, SG_INFO, - "Position for " << id << " is (" << a->longitude - << ", " << a->latitude << ")" ); - - return true; - } else { - return false; - } -} -#endif - - // Set current tower position lon/lat given an airport id -static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) { - - // tower height hard coded for now... - float towerheight=50.0f; - - // make a little off the heading for 1 runway airports... - float fudge_lon = fabs(sin(hdg)) * .003f; - float fudge_lat = .003f - fudge_lon; - +static bool fgSetTowerPosFromAirportID( const string& id) { const FGAirport *a = fgFindAirportID( id); - if ( a) { - fgSetDouble("/sim/tower/longitude-deg", a->getLongitude() + fudge_lon); - fgSetDouble("/sim/tower/latitude-deg", a->getLatitude() + fudge_lat); - fgSetDouble("/sim/tower/altitude-ft", a->getElevation() + towerheight); + if (a) { + SGGeod tower = a->getTowerLocation(); + fgSetDouble("/sim/tower/longitude-deg", tower.getLongitudeDeg()); + fgSetDouble("/sim/tower/latitude-deg", tower.getLatitudeDeg()); + fgSetDouble("/sim/tower/altitude-ft", tower.getElevationFt()); return true; } else { return false; @@ -684,155 +710,131 @@ static bool fgSetTowerPosFromAirportID( const string& id, double hdg ) { struct FGTowerLocationListener : SGPropertyChangeListener { void valueChanged(SGPropertyNode* node) { - const double hdg = fgGetDouble( "/orientation/heading-deg", 0); const string id(node->getStringValue()); - fgSetTowerPosFromAirportID(id, hdg); + fgSetTowerPosFromAirportID(id); } }; -static void fgInitTowerLocationListener() { +void fgInitTowerLocationListener() { fgGetNode("/sim/tower/airport-id", true) - ->addChangeListener( new FGTowerLocationListener() ); + ->addChangeListener( new FGTowerLocationListener(), true ); +} + +static void fgApplyStartOffset(const SGGeod& aStartPos, double aHeading, double aTargetHeading = HUGE_VAL) +{ + SGGeod startPos(aStartPos); + if (aTargetHeading == HUGE_VAL) { + aTargetHeading = aHeading; + } + + if ( fabs( fgGetDouble("/sim/presets/offset-distance-nm") ) > SG_EPSILON ) { + double offsetDistance = fgGetDouble("/sim/presets/offset-distance-nm"); + offsetDistance *= SG_NM_TO_METER; + double offsetAzimuth = aHeading; + if ( fabs(fgGetDouble("/sim/presets/offset-azimuth-deg")) > SG_EPSILON ) { + offsetAzimuth = fgGetDouble("/sim/presets/offset-azimuth-deg"); + aHeading = aTargetHeading; + } + + SGGeod offset; + double az2; // dummy + SGGeodesy::direct(startPos, offsetAzimuth + 180, offsetDistance, offset, az2); + startPos = offset; + } + + // presets + fgSetDouble("/sim/presets/longitude-deg", startPos.getLongitudeDeg() ); + fgSetDouble("/sim/presets/latitude-deg", startPos.getLatitudeDeg() ); + fgSetDouble("/sim/presets/heading-deg", aHeading ); + + // other code depends on the actual values being set ... + fgSetDouble("/position/longitude-deg", startPos.getLongitudeDeg() ); + fgSetDouble("/position/latitude-deg", startPos.getLatitudeDeg() ); + fgSetDouble("/orientation/heading-deg", aHeading ); } // Set current_options lon/lat given an airport id and heading (degrees) static bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { - FGRunway r; - - if ( id.length() ) { - // set initial position from runway and heading - - SG_LOG( SG_GENERAL, SG_INFO, - "Attempting to set starting position from airport code " - << id << " heading " << tgt_hdg ); - - if ( ! globals->get_runways()->search( id, (int)tgt_hdg, &r ) ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Failed to find a good runway for " << id << '\n' ); - return false; - } - } else { + if ( id.empty() ) return false; - } - - double lat2, lon2, az2; - double heading = r._heading; - double azimuth = heading + 180.0; - while ( azimuth >= 360.0 ) { azimuth -= 360.0; } + // set initial position from runway and heading SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r._lon << ", " << r._lat - << " length = " << r._length * SG_FEET_TO_METER - << " heading = " << azimuth ); - - geo_direct_wgs_84 ( 0, r._lat, r._lon, azimuth, - r._length * SG_FEET_TO_METER * 0.5 - 5.0, - &lat2, &lon2, &az2 ); - - if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) { - double olat, olon; - double odist = fgGetDouble("/sim/presets/offset-distance"); - odist *= SG_NM_TO_METER; - double oaz = azimuth; - if ( fabs(fgGetDouble("/sim/presets/offset-azimuth")) > SG_EPSILON ) { - oaz = fgGetDouble("/sim/presets/offset-azimuth") + 180; - heading = tgt_hdg; - } - while ( oaz >= 360.0 ) { oaz -= 360.0; } - geo_direct_wgs_84 ( 0, lat2, lon2, oaz, odist, &olat, &olon, &az2 ); - lat2=olat; - lon2=olon; - } + "Attempting to set starting position from airport code " + << id << " heading " << tgt_hdg ); - // presets - fgSetDouble("/sim/presets/longitude-deg", lon2 ); - fgSetDouble("/sim/presets/latitude-deg", lat2 ); - fgSetDouble("/sim/presets/heading-deg", heading ); + const FGAirport* apt = fgFindAirportID(id); + if (!apt) return false; + FGRunway* r = apt->findBestRunwayForHeading(tgt_hdg); + fgSetString("/sim/atc/runway", r->ident().c_str()); - // other code depends on the actual values being set ... - fgSetDouble("/position/longitude-deg", lon2 ); - fgSetDouble("/position/latitude-deg", lat2 ); - fgSetDouble("/orientation/heading-deg", heading ); + SGGeod startPos = r->pointOnCenterline(fgGetDouble("/sim/airport/runways/start-offset-m", 5.0)); + fgApplyStartOffset(startPos, r->headingDeg(), tgt_hdg); + return true; +} - SG_LOG( SG_GENERAL, SG_INFO, - "Position for " << id << " is (" - << lon2 << ", " - << lat2 << ") new heading is " - << heading ); - +// Set current_options lon/lat given an airport id and parkig position name +static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& parkpos ) { + if ( id.empty() ) + return false; + + // can't see an easy way around this const_cast at the moment + FGAirport* apt = const_cast(fgFindAirportID(id)); + if (!apt) { + SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find airport " << id ); + return false; + } + FGAirportDynamics* dcs = apt->getDynamics(); + if (!dcs) { + SG_LOG( SG_GENERAL, SG_ALERT, + "Failed to find parking position " << parkpos << + " at airport " << id ); + return false; + } + + int park_index = dcs->getNrOfParkings() - 1; + while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--; + if (park_index < 0) { + SG_LOG( SG_GENERAL, SG_ALERT, + "Failed to find parking position " << parkpos << + " at airport " << id ); + return false; + } + FGParking* parking = dcs->getParking(park_index); + fgApplyStartOffset( + SGGeod::fromDeg(parking->getLongitude(), parking->getLatitude()), + parking->getHeading()); return true; } // Set current_options lon/lat given an airport id and runway number static bool fgSetPosFromAirportIDandRwy( const string& id, const string& rwy, bool rwy_req ) { - FGRunway r; - - if ( id.length() ) { - // set initial position from airport and runway number - - SG_LOG( SG_GENERAL, SG_INFO, - "Attempting to set starting position for " - << id << ":" << rwy ); - - if ( ! globals->get_runways()->search( id, rwy, &r ) ) { - SG_LOG( SG_GENERAL, rwy_req ? SG_ALERT : SG_INFO, - "Failed to find runway " << rwy << - " at airport " << id ); - return false; - } - } else { + if ( id.empty() ) return false; - } - double lat2, lon2, az2; - double heading = r._heading; - double azimuth = heading + 180.0; - while ( azimuth >= 360.0 ) { azimuth -= 360.0; } - + // set initial position from airport and runway number SG_LOG( SG_GENERAL, SG_INFO, - "runway = " << r._lon << ", " << r._lat - << " length = " << r._length * SG_FEET_TO_METER - << " heading = " << azimuth ); - - geo_direct_wgs_84 ( 0, r._lat, r._lon, - azimuth, - r._length * SG_FEET_TO_METER * 0.5 - 5.0, - &lat2, &lon2, &az2 ); - - if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) - { - double olat, olon; - double odist = fgGetDouble("/sim/presets/offset-distance"); - odist *= SG_NM_TO_METER; - double oaz = azimuth; - if ( fabs(fgGetDouble("/sim/presets/offset-azimuth")) > SG_EPSILON ) - { - oaz = fgGetDouble("/sim/presets/offset-azimuth") + 180; - heading = fgGetDouble("/sim/presets/heading-deg"); - } - while ( oaz >= 360.0 ) { oaz -= 360.0; } - geo_direct_wgs_84 ( 0, lat2, lon2, oaz, odist, &olat, &olon, &az2 ); - lat2=olat; - lon2=olon; + "Attempting to set starting position for " + << id << ":" << rwy ); + + const FGAirport* apt = fgFindAirportID(id); + if (!apt) { + SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find airport:" << id); + return false; } - // presets - fgSetDouble("/sim/presets/longitude-deg", lon2 ); - fgSetDouble("/sim/presets/latitude-deg", lat2 ); - fgSetDouble("/sim/presets/heading-deg", heading ); - - // other code depends on the actual values being set ... - fgSetDouble("/position/longitude-deg", lon2 ); - fgSetDouble("/position/latitude-deg", lat2 ); - fgSetDouble("/orientation/heading-deg", heading ); - - SG_LOG( SG_GENERAL, SG_INFO, - "Position for " << id << " is (" - << lon2 << ", " - << lat2 << ") new heading is " - << heading ); + if (!apt->hasRunwayWithIdent(rwy)) { + SG_LOG( SG_GENERAL, rwy_req ? SG_ALERT : SG_INFO, + "Failed to find runway " << rwy << + " at airport " << id << ". Using default runway." ); + return false; + } + FGRunway* r(apt->getRunwayByIdent(rwy)); + fgSetString("/sim/atc/runway", r->ident().c_str()); + SGGeod startPos = r->pointOnCenterline( fgGetDouble("/sim/airport/runways/start-offset-m", 5.0)); + fgApplyStartOffset(startPos, r->headingDeg()); return true; } @@ -842,7 +844,7 @@ static void fgSetDistOrAltFromGlideSlope() { string apt_id = fgGetString("/sim/presets/airport-id"); double gs = fgGetDouble("/sim/presets/glideslope-deg") * SG_DEGREES_TO_RADIANS ; - double od = fgGetDouble("/sim/presets/offset-distance"); + double od = fgGetDouble("/sim/presets/offset-distance-nm"); double alt = fgGetDouble("/sim/presets/altitude-ft"); double apt_elev = 0.0; @@ -867,7 +869,7 @@ static void fgSetDistOrAltFromGlideSlope() { // set offset-distance from glideslope and altitude od = (alt - apt_elev) / tan(gs); od *= -1*SG_FEET_TO_METER * SG_METER_TO_NM; - fgSetDouble("/sim/presets/offset-distance", od); + fgSetDouble("/sim/presets/offset-distance-nm", od); fgSetBool("/sim/presets/onground", false); SG_LOG( SG_GENERAL, SG_INFO, "Calculated offset distance as: " << od << " nm" ); @@ -877,7 +879,7 @@ static void fgSetDistOrAltFromGlideSlope() { SG_LOG( SG_GENERAL, SG_ALERT, "Resetting glideslope to zero" ); fgSetDouble("/sim/presets/glideslope-deg", 0); fgSetBool("/sim/presets/onground", true); - } + } } @@ -886,48 +888,14 @@ static bool fgSetPosFromNAV( const string& id, const double& freq ) { FGNavRecord *nav = globals->get_navlist()->findByIdentAndFreq( id.c_str(), freq ); - // set initial position from runway and heading - if ( nav != NULL ) { - SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for " + if (!nav) { + SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = " << id << ":" << freq ); - - double lon = nav->get_lon(); - double lat = nav->get_lat(); - - if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) - { - double odist = fgGetDouble("/sim/presets/offset-distance") - * SG_NM_TO_METER; - double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth")) - + 180.0; - while ( oaz >= 360.0 ) { oaz -= 360.0; } - double olat, olon, az2; - geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 ); - - lat = olat; - lon = olon; - } - - // presets - fgSetDouble("/sim/presets/longitude-deg", lon ); - fgSetDouble("/sim/presets/latitude-deg", lat ); - - // other code depends on the actual values being set ... - fgSetDouble("/position/longitude-deg", lon ); - fgSetDouble("/position/latitude-deg", lat ); - fgSetDouble("/orientation/heading-deg", - fgGetDouble("/sim/presets/heading-deg") ); - - SG_LOG( SG_GENERAL, SG_INFO, - "Position for " << id << ":" << freq << " is (" - << lon << ", "<< lat << ")" ); - - return true; - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = " - << id << ":" << freq ); - return false; - } + return false; + } + + fgApplyStartOffset(nav->geod(), fgGetDouble("/sim/presets/heading-deg")); + return true; } // Set current_options lon/lat given an aircraft carrier id @@ -974,54 +942,19 @@ static bool fgSetPosFromCarrier( const string& carrier, const string& posid ) { } // Set current_options lon/lat given an airport id and heading (degrees) -static bool fgSetPosFromFix( const string& id ) { - FGFix fix; - - // set initial position from runway and heading - if ( globals->get_fixlist()->query( id.c_str(), &fix ) ) { - SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for " - << id ); - - double lon = fix.get_lon(); - double lat = fix.get_lat(); - - if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) - { - double odist = fgGetDouble("/sim/presets/offset-distance") - * SG_NM_TO_METER; - double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth")) - + 180.0; - while ( oaz >= 360.0 ) { oaz -= 360.0; } - double olat, olon, az2; - geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 ); - - lat = olat; - lon = olon; - } - - // presets - fgSetDouble("/sim/presets/longitude-deg", lon ); - fgSetDouble("/sim/presets/latitude-deg", lat ); - - // other code depends on the actual values being set ... - fgSetDouble("/position/longitude-deg", lon ); - fgSetDouble("/position/latitude-deg", lat ); - fgSetDouble("/orientation/heading-deg", - fgGetDouble("/sim/presets/heading-deg") ); - - SG_LOG( SG_GENERAL, SG_INFO, - "Position for " << id << " is (" - << lon << ", "<< lat << ")" ); - - return true; - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = " - << id ); - return false; - } +static bool fgSetPosFromFix( const string& id ) +{ + FGPositioned::TypeFilter fixFilter(FGPositioned::FIX); + FGPositioned* fix = FGPositioned::findNextWithPartialId(NULL, id, &fixFilter); + if (!fix) { + SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate fix = " << id ); + return false; + } + + fgApplyStartOffset(fix->geod(), fgGetDouble("/sim/presets/heading-deg")); + return true; } - /** * Initialize vor/ndb/ils/fix list management and query systems (as * well as simple airport db list) @@ -1037,18 +970,16 @@ fgInitNav () SGPath p_metar( globals->get_fg_root() ); p_metar.append( "Airports/metar.dat" ); - FGAirportList *airports = new FGAirportList(); - globals->set_airports( airports ); - FGRunwayList *runways = new FGRunwayList(); - globals->set_runways( runways ); - - fgAirportDBLoad( airports, runways, aptdb.str(), p_metar.str() ); +// Initialise the frequency search map BEFORE reading +// the airport database: + current_commlist = new FGCommList; + current_commlist->init( globals->get_fg_root() ); + fgAirportDBLoad( aptdb.str(), current_commlist, p_metar.str() ); FGNavList *navlist = new FGNavList; FGNavList *loclist = new FGNavList; FGNavList *gslist = new FGNavList; FGNavList *dmelist = new FGNavList; - FGNavList *mkrlist = new FGNavList; FGNavList *tacanlist = new FGNavList; FGNavList *carrierlist = new FGNavList; FGTACANList *channellist = new FGTACANList; @@ -1057,33 +988,30 @@ fgInitNav () globals->set_loclist( loclist ); globals->set_gslist( gslist ); globals->set_dmelist( dmelist ); - globals->set_mkrlist( mkrlist ); globals->set_tacanlist( tacanlist ); globals->set_carrierlist( carrierlist ); globals->set_channellist( channellist ); - if ( !fgNavDBInit(airports, navlist, loclist, gslist, dmelist, mkrlist, tacanlist, carrierlist, channellist) ) { + if ( !fgNavDBInit(navlist, loclist, gslist, dmelist, tacanlist, carrierlist, channellist) ) { SG_LOG( SG_GENERAL, SG_ALERT, "Problems loading one or more navigational database" ); } - - if ( fgGetBool("/sim/navdb/localizers/auto-align", true) ) { - // align all the localizers with their corresponding runways - // since data sources are good for cockpit navigation - // purposes, but not always to the error tolerances needed to - // exactly place these items. - double threshold - = fgGetDouble( "/sim/navdb/localizers/auto-align-threshold-deg", - 5.0 ); - fgNavDBAlignLOCwithRunway( runways, loclist, threshold ); - } - + SG_LOG(SG_GENERAL, SG_INFO, " Fixes"); SGPath p_fix( globals->get_fg_root() ); p_fix.append( "Navaids/fix.dat" ); - FGFixList *fixlist = new FGFixList; - fixlist->init( p_fix ); - globals->set_fixlist( fixlist ); + FGFixList fixlist; + 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 ); return true; } @@ -1094,7 +1022,7 @@ bool fgInitPosition() { // cout << "fgInitPosition()" << endl; double gs = fgGetDouble("/sim/presets/glideslope-deg") * SG_DEGREES_TO_RADIANS ; - double od = fgGetDouble("/sim/presets/offset-distance"); + double od = fgGetDouble("/sim/presets/offset-distance-nm"); double alt = fgGetDouble("/sim/presets/altitude-ft"); bool set_pos = false; @@ -1124,7 +1052,6 @@ bool fgInitPosition() { string apt = fgGetString("/sim/presets/airport-id"); string rwy_no = fgGetString("/sim/presets/runway"); bool rwy_req = fgGetBool("/sim/presets/runway-requested"); - double hdg = fgGetDouble("/sim/presets/heading-deg"); string vor = fgGetString("/sim/presets/vor-id"); double vor_freq = fgGetDouble("/sim/presets/vor-freq"); string ndb = fgGetString("/sim/presets/ndb-id"); @@ -1132,9 +1059,34 @@ bool fgInitPosition() { string carrier = fgGetString("/sim/presets/carrier"); string parkpos = fgGetString("/sim/presets/parkpos"); string fix = fgGetString("/sim/presets/fix"); + SGPropertyNode *hdg_preset = fgGetNode("/sim/presets/heading-deg", true); + double hdg = hdg_preset->getDoubleValue(); + + // save some start parameters, so that we can later say what the + // user really requested. TODO generalize that and move it to options.cxx + static bool start_options_saved = false; + if (!start_options_saved) { + start_options_saved = true; + SGPropertyNode *opt = fgGetNode("/sim/startup/options", true); + + opt->setDoubleValue("latitude-deg", lat_deg); + opt->setDoubleValue("longitude-deg", lon_deg); + opt->setDoubleValue("heading-deg", hdg); + opt->setStringValue("airport", apt.c_str()); + opt->setStringValue("runway", rwy_no.c_str()); + } - fgSetDouble( "/orientation/heading-deg", hdg ); - fgInitTowerLocationListener(); + if (hdg > 9990.0) + hdg = fgGetDouble("/environment/config/boundary/entry/wind-from-heading-deg", 270); + + if ( !set_pos && !apt.empty() && !parkpos.empty() ) { + // An airport + parking position is requested + if ( fgSetPosFromAirportIDandParkpos( apt, parkpos ) ) { + // set tower position + fgSetString("/sim/tower/airport-id", apt.c_str()); + set_pos = true; + } + } if ( !set_pos && !apt.empty() && !rwy_no.empty() ) { // An airport + runway is requested @@ -1156,6 +1108,9 @@ bool fgInitPosition() { } } + if (hdg_preset->getDoubleValue() > 9990.0) + hdg_preset->setDoubleValue(hdg); + if ( !set_pos && !vor.empty() ) { // a VOR is requested if ( fgSetPosFromNAV( vor, vor_freq ) ) { @@ -1195,13 +1150,14 @@ bool fgInitPosition() { fgGetDouble("/sim/presets/longitude-deg") ); fgSetDouble( "/position/latitude-deg", fgGetDouble("/sim/presets/latitude-deg") ); + fgSetDouble( "/orientation/heading-deg", hdg_preset->getDoubleValue()); // determine if this should be an on-ground or in-air start if ((fabs(gs) > 0.01 || fabs(od) > 0.1 || alt > 0.1) && carrier.empty()) { fgSetBool("/sim/presets/onground", false); } else { fgSetBool("/sim/presets/onground", true); - } + } return true; } @@ -1211,10 +1167,6 @@ bool fgInitPosition() { bool fgInitGeneral() { string root; -#if defined(FX) && defined(XMESA) - char *mesa_win_state; -#endif - SG_LOG( SG_GENERAL, SG_INFO, "General Initialization" ); SG_LOG( SG_GENERAL, SG_INFO, "======= ==============" ); @@ -1228,21 +1180,18 @@ bool fgInitGeneral() { } SG_LOG( SG_GENERAL, SG_INFO, "FG_ROOT = " << '"' << root << '"' << endl ); -#if defined(FX) && defined(XMESA) - // initialize full screen flag - globals->set_fullscreen(false); - if ( strstr ( general.get_glRenderer(), "Glide" ) ) { - // Test for the MESA_GLX_FX env variable - if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) { - // test if we are fullscreen mesa/glide - if ( (mesa_win_state[0] == 'f') || - (mesa_win_state[0] == 'F') ) { - globals->set_fullscreen(true); - } - } - } -#endif + globals->set_browser(fgGetString("/sim/startup/browser-app", "firefox %u")); + + char buf[512], *cwd = getcwd(buf, 511); + buf[511] = '\0'; + SGPropertyNode *curr = fgGetNode("/sim", true); + curr->removeChild("fg-current", 0, false); + curr = curr->getChild("fg-current", 0, true); + 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)); return true; } @@ -1261,100 +1210,83 @@ void fgInitFDM() { double dt = 1.0 / fgGetInt("/sim/model-hz"); string model = fgGetString("/sim/flight-model"); - try { - if ( model == "larcsim" ) { - cur_fdm_state = new FGLaRCsim( dt ); - } else if ( model == "jsb" ) { - cur_fdm_state = new FGJSBsim( dt ); -#if ENABLE_SP_FDMS - } else if ( model == "ada" ) { - cur_fdm_state = new FGADA( dt ); - } else if ( model == "acms" ) { - cur_fdm_state = new FGACMS( dt ); + 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 == "balloon" ) { - cur_fdm_state = new FGBalloonSim( dt ); - } else if ( model == "magic" ) { - cur_fdm_state = new FGMagicCarpet( dt ); - } 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 { - SG_LOG(SG_GENERAL, SG_ALERT, - "Unrecognized flight model '" << model - << "', cannot init flight dynamics model."); - exit(-1); + } 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; } - } catch ( ... ) { - SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n"); - exit(-1); - } -} - -static void printMat(const sgVec4 *mat, char *name="") -{ - int i; - SG_LOG(SG_GENERAL, SG_BULK, name ); - for(i=0; i<4; i++) { - SG_LOG(SG_GENERAL, SG_BULK, " " << mat[i][0] << " " << mat[i][1] - << " " << mat[i][2] << " " << mat[i][3] ); + // 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."); } } @@ -1364,11 +1296,6 @@ void fgInitView() { globals->get_aircraft_model()->update(0); // run update for current view so that data is current... globals->get_viewmgr()->update(0); - - printMat(globals->get_current_view()->get_VIEW(),"VIEW"); - printMat(globals->get_current_view()->get_UP(),"UP"); - // printMat(globals->get_current_view()->get_LOCAL(),"LOCAL"); - } @@ -1417,7 +1344,7 @@ void fgInitTimeOffset() { 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"); @@ -1476,16 +1403,19 @@ void fgInitTimeOffset() { 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 - cur_time; + warp = offset - (systemLocalTime - currGMT) - cur_time; } else if ( offset_type == "gmt" ) { - warp = offset - currGMT; + warp = offset - cur_time; } else if ( offset_type == "latitude" ) { - warp = offset - (aircraftLocalTime - systemLocalTime) - cur_time; + warp = offset - (aircraftLocalTime - currGMT)- cur_time; } else { SG_LOG( SG_GENERAL, SG_ALERT, "FG_TIME::Unsupported offset type " << offset_type ); @@ -1524,9 +1454,10 @@ bool fgInitSubsystems() { globals->get_event_mgr()->setRealtimeProperty(fgGetNode("/sim/time/delta-realtime-sec", true)); //////////////////////////////////////////////////////////////////// - // Initialize the property interpolator subsystem + // Initialize the property interpolator subsystem. Put into the INIT + // group because the "nasal" subsystem may need it at GENERAL take-down. //////////////////////////////////////////////////////////////////// - globals->add_subsystem("interpolator", new SGInterpolator); + globals->add_subsystem("interpolator", new SGInterpolator, SGSubsystemMgr::INIT); //////////////////////////////////////////////////////////////////// @@ -1540,8 +1471,8 @@ bool fgInitSubsystems() { SGPath mpath( globals->get_fg_root() ); mpath.append( "materials.xml" ); - string season = fgGetString("/sim/startup/season", "summer"); - if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), season.c_str()) ) { + if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), + globals->get_props()) ) { SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" ); exit(-1); } @@ -1561,12 +1492,9 @@ bool fgInitSubsystems() { exit(-1); } - // cause refresh of viewer scenery timestamps every 15 seconds... - globals->get_event_mgr()->addTask( "FGTileMgr::refresh_view_timestamps()", - globals->get_tile_mgr(), - &FGTileMgr::refresh_view_timestamps, - 15 ); - + globals->get_scenery()->get_scene_graph() + ->addChild(simgear::Particles::getCommonRoot()); + simgear::GlobalParticleCallback::setSwitch(fgGetNode("/sim/rendering/particles", true)); //////////////////////////////////////////////////////////////////// // Initialize the flight model subsystem. @@ -1578,6 +1506,21 @@ bool fgInitSubsystems() { // model or control parameters are set fgAircraftInit(); // In the future this might not be the case. + + //////////////////////////////////////////////////////////////////// + // Initialize the weather subsystem. + //////////////////////////////////////////////////////////////////// + + // 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.) @@ -1593,13 +1536,17 @@ bool fgInitSubsystems() { globals->add_subsystem( "xml-autopilot", new FGXMLAutopilot ); globals->add_subsystem( "route-manager", new FGRouteMgr ); - //////////////////////////////////////////////////////////////////// // Initialize the view manager subsystem. //////////////////////////////////////////////////////////////////// fgInitView(); + //////////////////////////////////////////////////////////////////// + // Initialize the Input-Output subsystem + //////////////////////////////////////////////////////////////////// + globals->add_subsystem( "io", new FGIO ); + //////////////////////////////////////////////////////////////////// // Create and register the logger. //////////////////////////////////////////////////////////////////// @@ -1623,14 +1570,6 @@ bool fgInitSubsystems() { fgInitTimeOffset(); // the environment subsystem needs this - //////////////////////////////////////////////////////////////////// - // Initialize the weather subsystem. - //////////////////////////////////////////////////////////////////// - - // Initialize the weather modeling subsystem - globals->add_subsystem("environment", new FGEnvironmentMgr); - - //////////////////////////////////////////////////////////////////// // Initialize the lighting subsystem. //////////////////////////////////////////////////////////////////// @@ -1643,33 +1582,12 @@ bool fgInitSubsystems() { fgGetBool("/sim/rendering/bump-mapping", false); #ifdef ENABLE_AUDIO_SUPPORT - //////////////////////////////////////////////////////////////////// - // Initialize the sound subsystem. - //////////////////////////////////////////////////////////////////// - - init_volume = fgGetFloat("/sim/sound/volume"); - fgSetFloat("/sim/sound/volume", 0.0f); - globals->set_soundmgr(new SGSoundMgr); - globals->get_soundmgr()->init(); - globals->get_soundmgr()->bind(); - - //////////////////////////////////////////////////////////////////// // Initialize the sound-effects subsystem. //////////////////////////////////////////////////////////////////// - - globals->add_subsystem("fx", new FGFX); globals->add_subsystem("voice", new FGVoiceMgr); #endif - //////////////////////////////////////////////////////////////////// - // Initialise ATC display system - //////////////////////////////////////////////////////////////////// - - SG_LOG(SG_GENERAL, SG_INFO, " ATC Display"); - globals->set_ATC_display(new FGATCDisplay); - globals->get_ATC_display()->init(); - //////////////////////////////////////////////////////////////////// // Initialise the ATC Manager //////////////////////////////////////////////////////////////////// @@ -1694,17 +1612,10 @@ bool fgInitSubsystems() { globals->add_subsystem("submodel_mgr", new FGSubmodelMgr); - // 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); - FGTrafficManager *dispatcher = - (FGTrafficManager*) globals->get_subsystem("Traffic Manager"); - SGPath path = globals->get_fg_root(); - path.append("/Traffic/fgtraffic.xml"); - readXML(path.str(), - *dispatcher); - //globals->get_subsystem("Traffic Manager")->init(); + // 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); //////////////////////////////////////////////////////////////////// @@ -1718,14 +1629,6 @@ bool fgInitSubsystems() { } - //////////////////////////////////////////////////////////////////// - // Initialize I/O subsystem. - //////////////////////////////////////////////////////////////////// - - globals->get_io()->init(); - globals->get_io()->bind(); - - //////////////////////////////////////////////////////////////////// // Add a new 2D panel. //////////////////////////////////////////////////////////////////// @@ -1764,6 +1667,19 @@ bool fgInitSubsystems() { //////////////////////////////////////////////////////////////////// globals->add_subsystem("replay", new FGReplay); + + //////////////////////////////////////////////////////////////////// + // Add Sound Manager. + // Put the sound manager last so it can use the CPU while the GPU + // is processing the scenery (doubled the frame-rate for me) -EMH- + //////////////////////////////////////////////////////////////////// +#ifdef ENABLE_AUDIO_SUPPORT + init_volume = fgGetFloat("/sim/sound/volume"); + fgSetFloat("/sim/sound/volume", 0.0f); + + globals->add_subsystem("soundmgr", new SGSoundMgr); +#endif + //////////////////////////////////////////////////////////////////// // Bind and initialize subsystems. //////////////////////////////////////////////////////////////////// @@ -1853,3 +1769,59 @@ void fgReInitSubsystems() fgSetBool("/sim/sceneryloaded",false); } + +void reInit(void) // from gui_local.cxx -- TODO merge with fgReInitSubsystems() +{ + 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); + + globals->restoreInitialState(); + + // 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); + + copyProperties(cameraNode, cameraGroupNode->getChild("camera")); + copyProperties(guiNode, cameraGroupNode->getChild("gui")); + + delete guiNode; + delete cameraNode; + + SGTime *t = globals->get_time_params(); + delete t; + t = fgInitTime(); + globals->set_time_params(t); + + fgReInitSubsystems(); + + globals->get_tile_mgr()->update(fgGetDouble("/environment/visibility-m")); + globals->get_renderer()->resize(xsize, ysize); + fgSetBool("/sim/signals/reinit", false); + + if (!freeze) + master_freeze->setBoolValue(false); +} +