From e9b492af4f65076cd87fbd47a1c182fb6529fcda Mon Sep 17 00:00:00 2001
From: curt <curt>
Date: Wed, 17 Jan 2001 23:30:35 +0000
Subject: [PATCH] More tweaking of position reset logic.

---
 src/GUI/apt_dlg.cxx     |  7 ++++---
 src/Main/fg_init.cxx    | 17 ++++++++++++++---
 src/Main/main.cxx       | 31 +++++++++++++++++++++++++++----
 src/Main/options.cxx    | 13 +++++++++++--
 src/Scenery/tilemgr.cxx | 27 ++++++++++++++++++++++++---
 5 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/src/GUI/apt_dlg.cxx b/src/GUI/apt_dlg.cxx
index 7636a0be7..1c7d7f3e2 100644
--- a/src/GUI/apt_dlg.cxx
+++ b/src/GUI/apt_dlg.cxx
@@ -79,10 +79,11 @@ void AptDialog_OK (puObject *)
 		if ( airports.search( AptId, &a ) )
 		{
 			fgSetString("/sim/startup/airport-id",  AptId.c_str() );
-			fgSetDouble("/position/altitude", -9999.0 );
-		// fgSetPosFromAirportID( AptId );
+			// fgSetDouble("/position/altitude", -9999.0 );
+			// fgSetPosFromAirportID( AptId );
 			fgSetPosFromAirportIDandHdg( AptId, 
-										 cur_fdm_state->get_Psi() * RAD_TO_DEG);
+						     cur_fdm_state->get_Psi() *
+						     RAD_TO_DEG);
 			BusyCursor(0);
 			fgReInitSubsystems();
 			BusyCursor(1);
diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index 881b225bf..3581a5818 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -358,10 +358,18 @@ bool fgInitPosition( void ) {
 
     FG_LOG( FG_GENERAL, FG_INFO,
 	    "scenery.cur_elev = " << scenery.cur_elev );
+    FG_LOG( FG_GENERAL, FG_INFO,
+	    "/position/altitude = " << fgGetDouble("/position/altitude") );
 
-    // if ( scenery.cur_elev > fgGetDouble("/position/altitude") - 1) {
-    fgSetDouble("/position/altitude", scenery.cur_elev + 1 );
-    // }
+    // if we requested on ground startups
+    if ( fgGetBool( "/sim/startup/onground" ) ) {
+	fgSetDouble("/position/altitude", scenery.cur_elev + 1 );
+    }
+
+    // if requested altitude is below ground level
+    if ( scenery.cur_elev > fgGetDouble("/position/altitude") - 1) {
+	fgSetDouble("/position/altitude", scenery.cur_elev + 1 );
+    }
 
     FG_LOG( FG_GENERAL, FG_INFO,
 	    "starting altitude is = " <<
@@ -776,6 +784,9 @@ bool fgInitSubsystems( void ) {
 
 void fgReInitSubsystems( void )
 {
+    FG_LOG( FG_GENERAL, FG_INFO,
+	    "/position/altitude = " << fgGetDouble("/position/altitude") );
+
     bool freeze = globals->get_freeze();
     if( !freeze )
         globals->set_freeze( true );
diff --git a/src/Main/main.cxx b/src/Main/main.cxx
index 703071fa7..1d4b266f6 100644
--- a/src/Main/main.cxx
+++ b/src/Main/main.cxx
@@ -135,7 +135,7 @@ FGGeneral general;
 // our initializations out of the glutIdleLoop() so that we can get a
 // splash screen up and running right away.
 static int idle_state = 0;
-static int global_multi_loop;
+static long global_multi_loop;
 
 // attempt to avoid a large bounce at startup
 static bool initial_freeze = true;
@@ -731,13 +731,21 @@ void fgRenderFrame( void ) {
 
 // Update internal time dependent calculations (i.e. flight model)
 void fgUpdateTimeDepCalcs() {
+    static bool inited = false;
+
     fgLIGHT *l = &cur_light_params;
     int i;
 
-    int multi_loop = 1;
+    long multi_loop = 1;
 
     if ( !globals->get_freeze() && !initial_freeze ) {
 	// conceptually, this could be done for each fdm instance ...
+
+	if ( !inited ) {
+	    cur_fdm_state->stamp();
+	    inited = true;
+	}
+
 	SGTimeStamp current;
 	current.stamp();
 	long elapsed = current - cur_fdm_state->get_time_stamp();
@@ -745,12 +753,20 @@ void fgUpdateTimeDepCalcs() {
 	elapsed += cur_fdm_state->get_remainder();
 	// cout << "elapsed = " << elapsed << endl;
 	// cout << "dt = " << cur_fdm_state->get_delta_t() << endl;
-	multi_loop = (int)(((double)elapsed * 0.000001) /
+	multi_loop = (long)(((double)elapsed * 0.000001) /
 			       cur_fdm_state->get_delta_t() );
 	cur_fdm_state->set_multi_loop( multi_loop );
 	long remainder = elapsed - ( (multi_loop*1000000) *
 				     cur_fdm_state->get_delta_t() );
 	cur_fdm_state->set_remainder( remainder );
+	// cout << "remainder = " << remainder << endl;
+
+	// chop max interations to something reasonable if the sim was
+	// delayed for an excesive amount of time
+	if ( multi_loop > 2.0 / cur_fdm_state->get_delta_t() ) {
+	    multi_loop = (int)(2.0 / cur_fdm_state->get_delta_t());
+	    cur_fdm_state->set_remainder( 0 );
+	}
 
 	// cout << "multi_loop = " << multi_loop << endl;
 	for ( i = 0; i < multi_loop; ++i ) {
@@ -979,7 +995,7 @@ static void fgMainLoop( void ) {
     // Calculate model iterations needed for next frame
     elapsed += remainder;
 
-    global_multi_loop = (int)(((double)elapsed * 0.000001) * 
+    global_multi_loop = (long)(((double)elapsed * 0.000001) * 
 			      fgGetInt("/sim/model-hz"));
     remainder = elapsed - ( (global_multi_loop*1000000) / 
 			    fgGetInt("/sim/model-hz") );
@@ -987,6 +1003,13 @@ static void fgMainLoop( void ) {
 	    "Model iterations needed = " << global_multi_loop
 	    << ", new remainder = " << remainder );
 	
+    // chop max interations to something reasonable if the sim was
+    // delayed for an excesive amount of time
+    if ( global_multi_loop > 2.0 * fgGetInt("/sim/model-hz") ) {
+	global_multi_loop = (int)(2.0 * fgGetInt("/sim/model-hz") );
+	remainder = 0;
+    }
+
     // flight model
     if ( global_multi_loop > 0 ) {
 	fgUpdateTimeDepCalcs();
diff --git a/src/Main/options.cxx b/src/Main/options.cxx
index 6b30f62ac..0cb6bebb2 100644
--- a/src/Main/options.cxx
+++ b/src/Main/options.cxx
@@ -149,6 +149,7 @@ fgSetDefaults ()
     fgSetInt("/sim/model-hz", NEW_DEFAULT_MODEL_HZ);
     fgSetInt("/sim/speed-up", 1);
     fgSetBool("/sim/startup/trim", false);
+    fgSetBool("/sim/startup/onground", true);
 
 				// Rendering options
     fgSetString("/sim/rendering/fog", "nicest");
@@ -566,6 +567,7 @@ parse_option (const string& arg)
 			      parse_degree(arg.substr(6)));
 	fgSetString("/position/airport-id", "");
     } else if ( arg.find( "--altitude=" ) != string::npos ) {
+	fgSetBool("/sim/startup/onground", false);
 	if ( fgGetString("/sim/startup/units") == "feet" )
 	    fgSetDouble("/position/altitude", atof(arg.substr(11)));
 	else
@@ -646,9 +648,13 @@ parse_option (const string& arg)
     } else if ( arg.find( "--speed=" ) != string::npos ) {
 	fgSetInt("/sim/speed-up", atoi(arg.substr(8)));
     } else if ( arg.find( "--trim") != string::npos) {
-        fgSetInt("/sim/startup/trim", true);
+        fgSetBool("/sim/startup/trim", true);
     } else if ( arg.find( "--notrim") != string::npos) {
-        fgSetInt("/sim/startup/trim", false);
+        fgSetBool("/sim/startup/trim", false);
+    } else if ( arg.find( "--on-ground") != string::npos) {
+        fgSetBool("/sim/startup/onground", true);
+    } else if ( arg.find( "--in-air") != string::npos) {
+        fgSetBool("/sim/startup/onground", false);
     } else if ( arg == "--fog-disable" ) {
 	fgSetString("/sim/rendering/fog", "disabled");
     } else if ( arg == "--fog-fastest" ) {
@@ -1031,6 +1037,9 @@ fgUsage ()
 	 << endl;
     cout << "\t--speed=n:  run the FDM this much faster than real time" << endl;
     cout << "\t--notrim:  Do NOT attempt to trim the model when initializing JSBsim" << endl;
+    cout << "\t--on-ground:  Start up at ground level (default)" << endl;
+    cout << "\t--in-air:  Start up in air (implied by specifying an initial"
+	 << " altitude above ground level." << endl;
     cout << "\t--wind=DIR@SPEED: specify wind coming from DIR (degrees) at SPEED (knots)" << endl;
     cout << endl;
 
diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx
index efc925ad6..314e3678b 100644
--- a/src/Scenery/tilemgr.cxx
+++ b/src/Scenery/tilemgr.cxx
@@ -228,11 +228,32 @@ void FGTileMgr::schedule_needed() {
 
     global_tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) );
 
+    SGBucket b;
+
+    // schedule center tile first so it can be loaded first
+    b = sgBucketOffset( longitude, latitude, 0, 0 );
+    sched_tile( b );
+
+    // schedule next ring of 8 tiles
+    for ( int x = -1; x <= 1; ++x ) {
+	for ( int y = -1; y <= 1; ++y ) {
+	    if ( x != 0 || y != 0 ) {
+		b = sgBucketOffset( longitude, latitude, x, y );
+		if ( ! global_tile_cache.exists( b ) ) {
+		    sched_tile( b );
+		}
+	    }
+	}
+    }
+    
+    // schedule remaining tiles
     for ( int x = -xrange; x <= xrange; ++x ) {
 	for ( int y = -yrange; y <= yrange; ++y ) {
-	    SGBucket b = sgBucketOffset( longitude, latitude, x, y );
-	    if ( ! global_tile_cache.exists( b ) ) {
-		sched_tile( b );
+	    if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
+		SGBucket b = sgBucketOffset( longitude, latitude, x, y );
+		if ( ! global_tile_cache.exists( b ) ) {
+		    sched_tile( b );
+		}
 	    }
 	}
     }