X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Ffg_init.cxx;h=f7c591d397dc3e17d66307259293b54a2bc4cf66;hb=a704a6208131cad4f12123a72acdb1fb3dc6658f;hp=82793ac2bbb13af1a544aed4affa779b3d36be61;hpb=7415696492c588b6cce408e930f1fa88f389c373;p=flightgear.git diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 82793ac2b..f7c591d39 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -34,12 +34,6 @@ # 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. -#ifdef linux -# define _G_NO_EXTERN_TEMPLATES -#endif - #include #include @@ -63,7 +57,6 @@ #include #include -#include #include #include #include @@ -90,9 +83,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -107,6 +97,9 @@ #include #include #include +#include +#include +#include #include "fg_init.hxx" #include "fg_io.hxx" @@ -116,7 +109,7 @@ #include "globals.hxx" #include "logger.hxx" #include "main.hxx" - +#include "positioninit.hxx" using std::string; using namespace boost::algorithm; @@ -422,25 +415,30 @@ bool fgInitConfig ( int argc, char **argv ) home->setStringValue(dataPath.c_str()); home->setAttribute(SGPropertyNode::WRITE, false); - flightgear::Options::sharedInstance()->init(argc, argv, dataPath); + flightgear::Options* options = flightgear::Options::sharedInstance(); + options->init(argc, argv, dataPath); + bool loadDefaults = flightgear::Options::sharedInstance()->shouldLoadDefaultConfig(); + if (loadDefaults) { + // Read global preferences from $FG_ROOT/preferences.xml + SG_LOG(SG_INPUT, SG_INFO, "Reading global preferences"); + fgLoadProps("preferences.xml", globals->get_props()); + SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences"); + + // do not load user settings when reset to default is requested + if (flightgear::Options::sharedInstance()->isOptionSet("restore-defaults")) + { + SG_LOG(SG_ALL, SG_ALERT, "Ignoring user settings. Restoring defaults."); + } + else + { + globals->loadUserSettings(dataPath); + } + } else { + SG_LOG(SG_GENERAL, SG_INFO, "not reading default configuration files"); + }// of no-default-config selected - // Read global preferences from $FG_ROOT/preferences.xml - SG_LOG(SG_INPUT, SG_INFO, "Reading global preferences"); - fgLoadProps("preferences.xml", globals->get_props()); - SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences"); - - // do not load user settings when reset to default is requested - if (flightgear::Options::sharedInstance()->isOptionSet("restore-defaults")) - { - SG_LOG(SG_ALL, SG_ALERT, "Ignoring user settings. Restoring defaults."); - } - else - { - globals->loadUserSettings(dataPath); - } - // Scan user config files and command line for a specified aircraft. - flightgear::Options::sharedInstance()->initAircraft(); + options->initAircraft(); FindAndCacheAircraft f(globals->get_props()); if (!f.loadAircraft()) { @@ -449,570 +447,45 @@ bool fgInitConfig ( int argc, char **argv ) // parse options after loading aircraft to ensure any user // overrides of defaults are honored. - flightgear::Options::sharedInstance()->processOptions(); + options->processOptions(); return true; } -// Set current tower position lon/lat given an airport id -static bool fgSetTowerPosFromAirportID( const string& id) { - const FGAirport *a = fgFindAirportID( id); - 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; - } - -} - -struct FGTowerLocationListener : SGPropertyChangeListener { - void valueChanged(SGPropertyNode* node) { - string id(node->getStringValue()); - if (fgGetBool("/sim/tower/auto-position",true)) - { - // enforce using closest airport when auto-positioning is enabled - const char* closest_airport = fgGetString("/sim/airport/closest-airport-id", ""); - if (closest_airport && (id != closest_airport)) - { - id = closest_airport; - node->setStringValue(id); - } - } - fgSetTowerPosFromAirportID(id); - } -}; - -struct FGClosestTowerLocationListener : SGPropertyChangeListener -{ - void valueChanged(SGPropertyNode* ) - { - // closest airport has changed - if (fgGetBool("/sim/tower/auto-position",true)) - { - // update tower position - const char* id = fgGetString("/sim/airport/closest-airport-id", ""); - if (id && *id!=0) - fgSetString("/sim/tower/airport-id", id); - } - } -}; - -void fgInitTowerLocationListener() { - fgGetNode("/sim/tower/airport-id", true) - ->addChangeListener( new FGTowerLocationListener(), true ); - FGClosestTowerLocationListener* ntcl = new FGClosestTowerLocationListener(); - fgGetNode("/sim/airport/closest-airport-id", true) - ->addChangeListener(ntcl , true ); - fgGetNode("/sim/tower/auto-position", true) - ->addChangeListener(ntcl, 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) -bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { - if ( id.empty() ) - return false; - - // 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 ); - - const FGAirport* apt = fgFindAirportID(id); - if (!apt) return false; - FGRunway* r = apt->findBestRunwayForHeading(tgt_hdg); - 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(), tgt_hdg); - return true; -} - -// 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, - "Airport " << id << "does not appear to have parking information available"); - return false; - } - - int park_index = dcs->getNrOfParkings() - 1; - bool succes; - double radius = fgGetDouble("/sim/dimensions/radius-m"); - if ((parkpos == string("AVAILABLE")) && (radius > 0)) { - double lat, lon, heading; - string fltType; - string acOperator; - SGPath acData; - try { - acData = globals->get_fg_home(); - acData.append("aircraft-data"); - string acfile = fgGetString("/sim/aircraft") + string(".xml"); - acData.append(acfile); - SGPropertyNode root; - readProperties(acData.str(), &root); - SGPropertyNode * node = root.getNode("sim"); - fltType = node->getStringValue("aircraft-class", "NONE" ); - acOperator = node->getStringValue("aircraft-operator", "NONE" ); - } catch (const sg_exception &) { - SG_LOG(SG_GENERAL, SG_INFO, - "Could not load aircraft aircrat type and operator information from: " << acData.str() << ". Using defaults"); - - // cout << path.str() << endl; - } - if (fltType.empty() || fltType == "NONE") { - SG_LOG(SG_GENERAL, SG_INFO, - "Aircraft type information not found in: " << acData.str() << ". Using default value"); - fltType = fgGetString("/sim/aircraft-class" ); - } - if (acOperator.empty() || fltType == "NONE") { - SG_LOG(SG_GENERAL, SG_INFO, - "Aircraft operator information not found in: " << acData.str() << ". Using default value"); - acOperator = fgGetString("/sim/aircraft-operator" ); - } - - cerr << "Running aircraft " << fltType << " of livery " << acOperator << endl; - string acType; // Currently not used by findAvailable parking, so safe to leave empty. - succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, acOperator); - if (succes) { - fgGetString("/sim/presets/parkpos"); - fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName()); - } else { - SG_LOG( SG_GENERAL, SG_ALERT, - "Failed to find a suitable parking at airport " << id ); - return false; - } - } else { - //cerr << "We shouldn't get here when AVAILABLE" << endl; - 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); - parking->setAvailable(false); - 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 ) { - if ( id.empty() ) - return false; - - // set initial position from airport and runway number - SG_LOG( SG_GENERAL, SG_INFO, - "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; - } - - 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; -} -static void fgSetDistOrAltFromGlideSlope() { - // cout << "fgSetDistOrAltFromGlideSlope()" << endl; - 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-nm"); - double alt = fgGetDouble("/sim/presets/altitude-ft"); - - double apt_elev = 0.0; - if ( ! apt_id.empty() ) { - apt_elev = fgGetAirportElev( apt_id ); - if ( apt_elev < -9990.0 ) { - apt_elev = 0.0; - } - } else { - apt_elev = 0.0; - } - - if( fabs(gs) > 0.01 && fabs(od) > 0.1 && alt < -9990 ) { - // set altitude from glideslope and offset-distance - od *= SG_NM_TO_METER * SG_METER_TO_FEET; - alt = fabs(od*tan(gs)) + apt_elev; - fgSetDouble("/sim/presets/altitude-ft", alt); - fgSetBool("/sim/presets/onground", false); - SG_LOG( SG_GENERAL, SG_INFO, "Calculated altitude as: " - << alt << " ft" ); - } else if( fabs(gs) > 0.01 && alt > 0 && fabs(od) < 0.1) { - // 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-nm", od); - fgSetBool("/sim/presets/onground", false); - SG_LOG( SG_GENERAL, SG_INFO, "Calculated offset distance as: " - << od << " nm" ); - } else if( fabs(gs) > 0.01 ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Glideslope given but not altitude or offset-distance." ); - SG_LOG( SG_GENERAL, SG_ALERT, "Resetting glideslope to zero" ); - fgSetDouble("/sim/presets/glideslope-deg", 0); - fgSetBool("/sim/presets/onground", true); - } -} - - -// Set current_options lon/lat given an airport id and heading (degrees) -static bool fgSetPosFromNAV( const string& id, const double& freq, FGPositioned::Type type ) { - - const nav_list_type navlist - = globals->get_navlist()->findByIdentAndFreq( id.c_str(), freq, type ); - - if (navlist.size() == 0 ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = " - << id << ":" << freq ); - return false; - } - - if( navlist.size() > 1 ) { - ostringstream buf; - buf << "Ambigous NAV-ID: '" << id << "'. Specify id and frequency. Available stations:" << endl; - for( nav_list_type::const_iterator it = navlist.begin(); it != navlist.end(); ++it ) { - // NDB stored in kHz, VOR stored in MHz * 100 :-P - double factor = (*it)->type() == FGPositioned::NDB ? 1.0 : 1/100.0; - string unit = (*it)->type() == FGPositioned::NDB ? "kHz" : "MHz"; - buf << (*it)->ident() << " " - << setprecision(5) << (double)((*it)->get_freq() * factor) << " " - << (*it)->get_lat() << "/" << (*it)->get_lon() - << endl; - } - - SG_LOG( SG_GENERAL, SG_ALERT, buf.str() ); - return false; - } - - FGNavRecord *nav = navlist[0]; - fgApplyStartOffset(nav->geod(), fgGetDouble("/sim/presets/heading-deg")); - return true; -} - -// Set current_options lon/lat given an aircraft carrier id -static bool fgSetPosFromCarrier( const string& carrier, const string& posid ) { - - // set initial position from runway and heading - SGGeod geodPos; - double heading; - SGVec3d uvw; - if (FGAIManager::getStartPosition(carrier, posid, geodPos, heading, uvw)) { - double lon = geodPos.getLongitudeDeg(); - double lat = geodPos.getLatitudeDeg(); - double alt = geodPos.getElevationFt(); - - SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for " - << carrier << " at lat = " << lat << ", lon = " << lon - << ", alt = " << alt << ", heading = " << heading); - - fgSetDouble("/sim/presets/longitude-deg", lon); - fgSetDouble("/sim/presets/latitude-deg", lat); - fgSetDouble("/sim/presets/altitude-ft", alt); - fgSetDouble("/sim/presets/heading-deg", heading); - fgSetDouble("/position/longitude-deg", lon); - fgSetDouble("/position/latitude-deg", lat); - fgSetDouble("/position/altitude-ft", alt); - fgSetDouble("/orientation/heading-deg", heading); - - fgSetString("/sim/presets/speed-set", "UVW"); - fgSetDouble("/velocities/uBody-fps", uvw(0)); - fgSetDouble("/velocities/vBody-fps", uvw(1)); - fgSetDouble("/velocities/wBody-fps", uvw(2)); - fgSetDouble("/sim/presets/uBody-fps", uvw(0)); - fgSetDouble("/sim/presets/vBody-fps", uvw(1)); - fgSetDouble("/sim/presets/wBody-fps", uvw(2)); - - fgSetBool("/sim/presets/onground", true); - - return true; - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate aircraft carrier = " - << carrier ); - return false; - } -} - -// Set current_options lon/lat given an airport id and heading (degrees) -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) + * This is called multiple times in the case of a cache rebuild, + * to allow length caching to take place in the background, without + * blocking the main/UI thread. */ bool fgInitNav () { - SG_LOG(SG_GENERAL, SG_INFO, "Loading Airport Database ..."); - - SGPath aptdb( globals->get_fg_root() ); - aptdb.append( "Airports/apt.dat" ); - - SGPath p_metar( globals->get_fg_root() ); - p_metar.append( "Airports/metar.dat" ); - - fgAirportDBLoad( aptdb.str(), p_metar.str() ); - - FGNavList *navlist = new FGNavList; - FGNavList *loclist = new FGNavList; - FGNavList *gslist = new FGNavList; - FGNavList *dmelist = new FGNavList; - FGNavList *tacanlist = new FGNavList; - FGNavList *carrierlist = new FGNavList; - FGTACANList *channellist = new FGTACANList; - - globals->set_navlist( navlist ); - globals->set_loclist( loclist ); - globals->set_gslist( gslist ); - globals->set_dmelist( dmelist ); - globals->set_tacanlist( tacanlist ); - globals->set_carrierlist( carrierlist ); - globals->set_channellist( channellist ); - - if ( !fgNavDBInit(navlist, loclist, gslist, dmelist, tacanlist, carrierlist, channellist) ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Problems loading one or more navigational database" ); - } - - SG_LOG(SG_GENERAL, SG_INFO, " Fixes"); - SGPath p_fix( globals->get_fg_root() ); - p_fix.append( "Navaids/fix.dat" ); - FGFixList fixlist; - fixlist.init( p_fix ); // adds fixes to the DB in positioned.cxx - - SG_LOG(SG_GENERAL, SG_INFO, " Airways"); - flightgear::Airway::load(); - - return true; -} - - -// Set the initial position based on presets (or defaults) -bool fgInitPosition() { - // cout << "fgInitPosition()" << endl; - double gs = fgGetDouble("/sim/presets/glideslope-deg") - * SG_DEGREES_TO_RADIANS ; - double od = fgGetDouble("/sim/presets/offset-distance-nm"); - double alt = fgGetDouble("/sim/presets/altitude-ft"); - - bool set_pos = false; - - // If glideslope is specified, then calculate offset-distance or - // altitude relative to glide slope if either of those was not - // specified. - if ( fabs( gs ) > 0.01 ) { - fgSetDistOrAltFromGlideSlope(); - } - - - // If we have an explicit, in-range lon/lat, don't change it, just use it. - // If not, check for an airport-id and use that. - // If not, default to the middle of the KSFO field. - // The default values for lon/lat are deliberately out of range - // so that the airport-id can take effect; valid lon/lat will - // override airport-id, however. - double lon_deg = fgGetDouble("/sim/presets/longitude-deg"); - double lat_deg = fgGetDouble("/sim/presets/latitude-deg"); - if ( lon_deg >= -180.0 && lon_deg <= 180.0 - && lat_deg >= -90.0 && lat_deg <= 90.0 ) - { - set_pos = true; - } - - string apt = fgGetString("/sim/presets/airport-id"); - string rwy_no = fgGetString("/sim/presets/runway"); - bool rwy_req = fgGetBool("/sim/presets/runway-requested"); - string vor = fgGetString("/sim/presets/vor-id"); - double vor_freq = fgGetDouble("/sim/presets/vor-freq"); - string ndb = fgGetString("/sim/presets/ndb-id"); - double ndb_freq = fgGetDouble("/sim/presets/ndb-freq"); - 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()); - } - - 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/airport/closest-airport-id", apt.c_str()); - fgSetString("/sim/tower/airport-id", apt.c_str()); - set_pos = true; - } - } - - if ( !set_pos && !apt.empty() && !rwy_no.empty() ) { - // An airport + runway is requested - if ( fgSetPosFromAirportIDandRwy( apt, rwy_no, rwy_req ) ) { - // set tower position (a little off the heading for single - // runway airports) - fgSetString("/sim/airport/closest-airport-id", apt.c_str()); - fgSetString("/sim/tower/airport-id", apt.c_str()); - set_pos = true; - } - } - - if ( !set_pos && !apt.empty() ) { - // An airport is requested (find runway closest to hdg) - if ( fgSetPosFromAirportIDandHdg( apt, hdg ) ) { - // set tower position (a little off the heading for single - // runway airports) - fgSetString("/sim/airport/closest-airport-id", apt.c_str()); - fgSetString("/sim/tower/airport-id", apt.c_str()); - set_pos = true; - } - } - - if (hdg_preset->getDoubleValue() > 9990.0) - hdg_preset->setDoubleValue(hdg); - - if ( !set_pos && !vor.empty() ) { - // a VOR is requested - if ( fgSetPosFromNAV( vor, vor_freq, FGPositioned::VOR ) ) { - set_pos = true; - } - } - - if ( !set_pos && !ndb.empty() ) { - // an NDB is requested - if ( fgSetPosFromNAV( ndb, ndb_freq, FGPositioned::NDB ) ) { - set_pos = true; - } - } - - if ( !set_pos && !carrier.empty() ) { - // an aircraft carrier is requested - if ( fgSetPosFromCarrier( carrier, parkpos ) ) { - set_pos = true; - } - } - - if ( !set_pos && !fix.empty() ) { - // a Fix is requested - if ( fgSetPosFromFix( fix ) ) { - set_pos = true; - } - } - - if ( !set_pos ) { - // No lon/lat specified, no airport specified, default to - // middle of KSFO field. - fgSetDouble("/sim/presets/longitude-deg", -122.374843); - fgSetDouble("/sim/presets/latitude-deg", 37.619002); - } - - fgSetDouble( "/position/longitude-deg", - 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); + flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); + static bool doingRebuild = false; + if (doingRebuild || cache->isRebuildRequired()) { + doingRebuild = true; + bool finished = cache->rebuild(); + if (!finished) { + // sleep to give the rebuild thread more time + SGTimeStamp::sleepForMSec(50); + return false; } - - return true; + } + + FGTACANList *channellist = new FGTACANList; + globals->set_channellist( channellist ); + + SGPath path(globals->get_fg_root()); + path.append( "Navaids/TACAN_freq.dat" ); + flightgear::loadTacan(path, channellist); + + return true; } - // General house keeping initializations bool fgInitGeneral() { string root; @@ -1050,9 +523,9 @@ bool fgInitGeneral() { // initialization routines. If you are adding a subsystem to flight // gear, its initialization call should located in this routine. // Returns non-zero if a problem encountered. -bool fgInitSubsystems() { +void fgCreateSubsystems() { - SG_LOG( SG_GENERAL, SG_INFO, "Initialize Subsystems"); + SG_LOG( SG_GENERAL, SG_INFO, "Creating Subsystems"); SG_LOG( SG_GENERAL, SG_INFO, "========== =========="); //////////////////////////////////////////////////////////////////// @@ -1132,9 +605,11 @@ bool fgInitSubsystems() { // autopilot.) //////////////////////////////////////////////////////////////////// - globals->add_subsystem("instrumentation", new FGInstrumentMgr, SGSubsystemMgr::FDM); globals->add_subsystem("systems", new FGSystemMgr, SGSubsystemMgr::FDM); - + globals->add_subsystem("instrumentation", new FGInstrumentMgr, SGSubsystemMgr::FDM); + globals->add_subsystem("hud", new HUD, SGSubsystemMgr::DISPLAY); + globals->add_subsystem("cockpit-displays", new flightgear::CockpitDisplayManager, SGSubsystemMgr::DISPLAY); + //////////////////////////////////////////////////////////////////// // Initialize the XML Autopilot subsystem. //////////////////////////////////////////////////////////////////// @@ -1217,16 +692,14 @@ bool fgInitSubsystems() { //////////////////////////////////////////////////////////////////// // Initialize the controls subsystem. //////////////////////////////////////////////////////////////////// - - globals->get_controls()->init(); - globals->get_controls()->bind(); - + + globals->add_subsystem("controls", new FGControls, SGSubsystemMgr::GENERAL); //////////////////////////////////////////////////////////////////// // Initialize the input subsystem. //////////////////////////////////////////////////////////////////// - globals->add_subsystem("input", new FGInput); + globals->add_subsystem("input", new FGInput, SGSubsystemMgr::GENERAL); //////////////////////////////////////////////////////////////////// @@ -1249,14 +722,9 @@ bool fgInitSubsystems() { // 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); + globals->add_subsystem("aircraft-model", new FGAircraftModel, SGSubsystemMgr::DISPLAY); + globals->add_subsystem("model-manager", new FGModelMgr, SGSubsystemMgr::DISPLAY); FGViewMgr *viewmgr = new FGViewMgr; globals->set_viewmgr( viewmgr ); @@ -1264,14 +732,13 @@ bool fgInitSubsystems() { globals->add_subsystem("tile-manager", globals->get_tile_mgr(), SGSubsystemMgr::DISPLAY); - - //////////////////////////////////////////////////////////////////// - // Bind and initialize subsystems. - //////////////////////////////////////////////////////////////////// - - globals->get_subsystem_mgr()->bind(); - globals->get_subsystem_mgr()->init(); +} +void fgPostInitSubsystems() +{ + SGTimeStamp st; + st.stamp(); + //////////////////////////////////////////////////////////////////////// // Initialize the Nasal interpreter. // Do this last, so that the loaded scripts see initialized state @@ -1279,10 +746,13 @@ bool fgInitSubsystems() { FGNasalSys* nasal = new FGNasalSys(); globals->add_subsystem("nasal", nasal, SGSubsystemMgr::INIT); nasal->init(); - + SG_LOG(SG_GENERAL, SG_INFO, "Nasal init took:" << st.elapsedMSec()); + // initialize methods that depend on other subsystems. + st.stamp(); globals->get_subsystem_mgr()->postinit(); - + SG_LOG(SG_GENERAL, SG_INFO, "Subsystems postinit took:" << st.elapsedMSec()); + //////////////////////////////////////////////////////////////////// // TODO FIXME! UGLY KLUDGE! //////////////////////////////////////////////////////////////////// @@ -1290,7 +760,7 @@ bool fgInitSubsystems() { /* Scenarios require Nasal, so FGAIManager loads the scenarios, * including its models such as a/c carriers, in its 'postinit', * which is the very last thing we do. - * fgInitPosition is called very early in main.cxx/fgIdleFunction, + * flightgear::initPosition is called very early in main.cxx/fgIdleFunction, * one of the first things we do, long before scenarios/carriers are * loaded. => When requested "initial preset position" relates to a * carrier, recalculate the 'initial' position here (how have things @@ -1302,7 +772,7 @@ bool fgInitSubsystems() { // clear preset location and re-trigger position setup fgSetDouble("/sim/presets/longitude-deg", 9999); fgSetDouble("/sim/presets/latitude-deg", 9999); - fgInitPosition(); + flightgear::initPosition(); } } @@ -1318,8 +788,6 @@ bool fgInitSubsystems() { // Save the initial state for future // reference. globals->saveInitialState(); - - return true; } // Reset: this is what the 'reset' command (and hence, GUI) is attached to @@ -1349,7 +817,7 @@ void fgReInitSubsystems() globals->restoreInitialState(); // update our position based on current presets - fgInitPosition(); + flightgear::initPosition(); // Force reupdating the positions of the ai 3d models. They are used for // initializing ground level for the FDM. @@ -1369,6 +837,12 @@ void fgReInitSubsystems() // need to bind FDMshell again, since we manually unbound it above... globals->get_subsystem("flight")->bind(); + // need to reset aircraft (systems/instruments) so they can adapt to current environment + globals->get_subsystem("systems")->reinit(); + globals->get_subsystem("instrumentation")->reinit(); + + globals->get_subsystem("ATIS")->reinit(); + // setup state to end re-init fgSetBool("/sim/signals/reinit", false); if ( !freeze ) {