]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/positioninit.cxx
Remove confusing reference to SDL/GLUT
[flightgear.git] / src / Main / positioninit.cxx
index c904a48fa78f69957b6f4106e6fcd2234b8c4dc1..816e997831fcaee8cf0fa37668f94c77a36450c2 100644 (file)
 // simgear
 #include <simgear/props/props_io.hxx>
 #include <simgear/structure/exception.hxx>
+#include <simgear/structure/event_mgr.hxx>
 
 #include "globals.hxx"
 #include "fg_props.hxx"
 
 #include <Navaids/navlist.hxx>
 #include <Airports/runways.hxx>
-#include <Airports/simple.hxx>
+#include <Airports/airport.hxx>
 #include <Airports/dynamics.hxx>
 #include <AIModel/AIManager.hxx>
 
 using std::endl;
+using std::string;
 
 namespace flightgear
 {
@@ -44,6 +46,9 @@ namespace flightgear
 /// unresponsive, we need a timeout value. This value is reset on initPosition,
 /// and tracked through each call to finalizePosition.
 static SGTimeStamp global_finalizeTime;
+static bool global_callbackRegistered = false;
+
+static void finalizePosition();
   
 // Set current tower position lon/lat given an airport id
 static bool fgSetTowerPosFromAirportID( const string& id) {
@@ -147,11 +152,23 @@ static bool setPosFromAirportIDandHdg( const string& id, double 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);
+  SGGeod startPos;
+  double heading = tgt_hdg;
+  if (apt->type() == FGPositioned::HELIPORT) {
+    if (apt->numHelipads() > 0) {
+      startPos = apt->getHelipadByIndex(0)->geod();
+    } else {
+      startPos = apt->geod();
+    }
+  } else {
+    FGRunway* r = apt->findBestRunwayForHeading(tgt_hdg);
+    fgSetString("/sim/atc/runway", r->ident().c_str());
+    startPos = r->pointOnCenterline(fgGetDouble("/sim/airport/runways/start-offset-m", 5.0));
+    heading = r->headingDeg();
+  }
+
+  fgApplyStartOffset(startPos, heading, tgt_hdg);
   return true;
 }
 
@@ -312,7 +329,7 @@ static bool fgSetPosFromNAV( const string& id, const double& freq, FGPositioned:
   FGNavList::TypeFilter filter(type);
   const nav_list_type navlist = FGNavList::findByIdentAndFreq( id.c_str(), freq, &filter );
   
-  if (navlist.size() == 0 ) {
+  if (navlist.empty()) {
     SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
            << id << ":" << freq );
     return false;
@@ -401,7 +418,11 @@ static bool fgSetPosFromFix( const string& id )
 bool initPosition()
 {
   global_finalizeTime = SGTimeStamp(); // reset to invalid
-  
+  if (!global_callbackRegistered) {
+    globals->get_event_mgr()->addTask("finalizePosition", &finalizePosition, 0.1);
+    global_callbackRegistered = true;
+  }
+    
   double gs = fgGetDouble("/sim/presets/glideslope-deg")
   * SG_DEGREES_TO_RADIANS ;
   double od = fgGetDouble("/sim/presets/offset-distance-nm");
@@ -544,16 +565,52 @@ bool initPosition()
     fgSetBool("/sim/presets/onground", true);
   }
   
+  fgSetBool("/sim/position-finalized", false);
+    
+  return true;
+}
+  
+bool finalizeMetar()
+{
+  double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 );
+  string apt = fgGetString("/sim/presets/airport-id");
+  string rwy = fgGetString("/sim/presets/runway");
+  double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 );
+  string parkpos = fgGetString( "/sim/presets/parkpos" );
+  bool onground = fgGetBool( "/sim/presets/onground", false );
+  // this logic is taken from former startup.nas
+  bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) &&
+  rwy.empty() && onground && parkpos.empty();
+  
+  if (needMetar) {
+    // timeout so we don't spin forever if the network is down
+    if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 10000)) {
+      SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch");
+      return true;
+    }
+    
+    if (!fgGetBool( "/environment/metar/valid" )) {
+      return false;
+    }
+    
+    SG_LOG(SG_ENVIRONMENT, SG_INFO,
+           "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
+    setPosFromAirportIDandHdg( apt, hdg );
+    // fall through to return true
+  } // of need-metar case
+  
   return true;
 }
   
-bool finalizePosition()
+void finalizePosition()
 {
   // first call to finalize after an initPosition call
   if (global_finalizeTime.get_usec() == 0) {
     global_finalizeTime = SGTimeStamp::now();
   }
   
+  bool done = true;
+  
     /* 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.
@@ -569,42 +626,16 @@ bool finalizePosition()
         // clear preset location and re-trigger position setup
         fgSetDouble("/sim/presets/longitude-deg", 9999);
         fgSetDouble("/sim/presets/latitude-deg", 9999);
-        return initPosition();
+        initPosition();
+    } else {
+        done = finalizeMetar();
+    }
+  
+    fgSetBool("/sim/position-finalized", done);
+    if (done) {
+        globals->get_event_mgr()->removeTask("finalizePosition");
+        global_callbackRegistered = false;
     }
-
-    double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 );
-    string apt = fgGetString( "/sim/startup/options/airport" );
-    string rwy = fgGetString( "/sim/startup/options/runway" );
-    double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 );
-    string parkpos = fgGetString( "/sim/presets/parkpos" );
-    bool onground = fgGetBool( "/sim/presets/onground", false );
-// this logic is taken from former startup.nas
-    bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) &&
-        rwy.empty() && onground && parkpos.empty();
-    
-    if (needMetar) {
-      // timeout so we don't spin forever if the network is down
-      if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 5000)) {
-        SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch");
-        return true;
-      }
-    
-      if (!fgGetBool( "/environment/metar/valid" )) {
-        // bit hacky - run these two subsystems. We can't run the whole
-        // lot since some view things aren't initialised and hence FGLight
-        // crashes.
-        globals->get_subsystem("http")->update(0.0);
-        globals->get_subsystem("environment")->update(0.0);
-        return false;
-      }
-      
-      SG_LOG(SG_ENVIRONMENT, SG_INFO,
-             "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
-      setPosFromAirportIDandHdg( apt, hdg );
-        // fall through to return true
-    } // of need-metar case
-    
-    return true;
 }
     
 } // of namespace flightgear