From c2a3d24ef3c77f4c1457f69c21ef7fc5091494b8 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Fri, 14 Jan 2011 20:04:20 +0000
Subject: [PATCH 01/25] Make the Nasal NaN check less aggressive - still
 SG_ALERT, but return nil instead of terminating the Nasal script completely.

---
 src/Scripting/NasalSys.cxx    | 2 +-
 src/Scripting/nasal-props.cxx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx
index 158d852e5..1f952b325 100644
--- a/src/Scripting/NasalSys.cxx
+++ b/src/Scripting/NasalSys.cxx
@@ -190,7 +190,7 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args)
         double dv = p->getDoubleValue();
         if (osg::isNaN(dv)) {
           SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN");
-          naRuntimeError(c, "getprop() would have read NaN");
+          return naNil();
         }
         
         return naNum(dv);
diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx
index 0ea341b08..214cc5c9a 100644
--- a/src/Scripting/nasal-props.cxx
+++ b/src/Scripting/nasal-props.cxx
@@ -173,7 +173,7 @@ static naRef f_getValue(naContext c, naRef me, int argc, naRef* args)
         double dv = (*node)->getDoubleValue();
         if (osg::isNaN(dv)) {
           SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getValue: property " << (*node)->getPath() << " is NaN");
-          naRuntimeError(c, "props.getValue() would have read NaN");
+          return naNil();
         }
         
         return naNum(dv);

From 4043e797744a9ebc4e143c3160f0755c3ef46c6e Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Mon, 10 Jan 2011 20:53:46 +0100
Subject: [PATCH 02/25] AI traffic performance boost for busy airports Stop
 ground elevation (scenery) checks for stationary AI aircraft.

---
 src/AIModel/AIAircraft.cxx | 18 ++++++++++++++++--
 src/AIModel/AIAircraft.hxx |  3 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
index 52459a9cf..addfba9f7 100644
--- a/src/AIModel/AIAircraft.cxx
+++ b/src/AIModel/AIAircraft.cxx
@@ -84,6 +84,7 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : FGAIBase(otAircraft) {
 
     holdPos = false;
     needsTaxiClearance = false;
+    _needsGroundElevation = true;
 
     _performance = 0; //TODO initialize to JET_TRANSPORT from PerformanceDB
     dt = 0;
@@ -179,6 +180,8 @@ void FGAIAircraft::checkVisibility()
 
 void FGAIAircraft::AccelTo(double speed) {
     tgt_speed = speed;
+    if (!isStationary())
+        _needsGroundElevation = true;
 }
 
 
@@ -334,7 +337,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
                 use_perf_vs = true;
             }
         }
-        tgt_speed = prev->speed;
+        AccelTo(prev->speed);
         hdg_lock = alt_lock = true;
         no_roll = prev->on_ground;
     }
@@ -403,6 +406,8 @@ bool FGAIAircraft::loadNextLeg(double distance) {
 void FGAIAircraft::getGroundElev(double dt) {
     dt_elev_count += dt;
 
+    if (!needGroundElevation())
+        return;
     // Update minimally every three secs, but add some randomness
     // to prevent all AI objects doing this in synchrony
     if (dt_elev_count < (3.0) + (rand() % 10))
@@ -424,14 +429,22 @@ void FGAIAircraft::getGroundElev(double dt) {
         {
             double alt;
             if (getGroundElevationM(SGGeod::fromGeodM(pos, 20000), alt, 0))
+            {
                 tgt_altitude_ft = alt * SG_METER_TO_FEET;
+                if (isStationary())
+                {
+                    // aircraft is stationary and we obtained altitude for this spot - we're done.
+                    _needsGroundElevation = false;
+                }
+            }
         }
     }
 }
 
 
 void FGAIAircraft::doGroundAltitude() {
-    if (fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)
+    if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
+        (fabs(speed)<0.0001))
         altitude_ft = (tgt_altitude_ft + groundOffset);
     else
         altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);
@@ -601,6 +614,7 @@ void FGAIAircraft::handleFirstWaypoint() {
         Transform();             // make sure aip is initialized.
         getGroundElev(60.1);     // make sure it's executed first time around, so force a large dt value
         doGroundAltitude();
+        _needsGroundElevation = true; // check ground elevation again (maybe scenery wasn't available yet)
     }
     // Make sure to announce the aircraft's position
     announcePositionToController();
diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx
index 26ceb5120..1d8103726 100644
--- a/src/AIModel/AIAircraft.hxx
+++ b/src/AIModel/AIAircraft.hxx
@@ -141,6 +141,8 @@ private:
     void updateActualState();
     void handleATCRequests();
     void checkVisibility();
+    inline bool isStationary() { return ((fabs(speed)<=0.0001)&&(fabs(tgt_speed)<=0.0001));}
+    inline bool needGroundElevation() { if (!isStationary()) _needsGroundElevation=true;return _needsGroundElevation;}
 
     double sign(double x);
 
@@ -160,6 +162,7 @@ private:
 
     bool reachedWaypoint;
     bool needsTaxiClearance;
+    bool _needsGroundElevation;
     time_t timeElapsed;
 
     PerformanceData* _performance; // the performance data for this aircraft

From 5ec5c34255d2488d5a7b255cf9c95520eccf3ac5 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Mon, 10 Jan 2011 21:19:51 +0100
Subject: [PATCH 03/25] Minor update Missed this place during code clean-up

---
 src/AIModel/AIAircraft.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx
index addfba9f7..8d7df9225 100644
--- a/src/AIModel/AIAircraft.cxx
+++ b/src/AIModel/AIAircraft.cxx
@@ -444,7 +444,7 @@ void FGAIAircraft::getGroundElev(double dt) {
 
 void FGAIAircraft::doGroundAltitude() {
     if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
-        (fabs(speed)<0.0001))
+        (isStationary()))
         altitude_ft = (tgt_altitude_ft + groundOffset);
     else
         altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);

From f025c65c60ba34c2fd91bc52f201463d992cf613 Mon Sep 17 00:00:00 2001
From: John Denker <jsd@av8n.com>
Date: Mon, 30 Nov 2009 03:19:17 -0700
Subject: [PATCH 04/25] Fix ADF bugs ... including still driving the needle
 when power off.

ADF bug fixes from John Denker.  Changes from current behaviour are:
* Include the power button in the electrical checks
* Raise the required input voltage from 1V to 8V
* Don't reset the heading to 90 degrees when out of range or no power
  (heading is now only reset to 90 in ANT or TEST mode)
---
 src/Instrumentation/adf.cxx | 23 ++++++++++++++---------
 src/Instrumentation/adf.hxx |  1 +
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx
index 6da2a2ed4..41ee7700e 100644
--- a/src/Instrumentation/adf.cxx
+++ b/src/Instrumentation/adf.cxx
@@ -101,6 +101,10 @@ ADF::init ()
     _bearing_node = node->getChild("indicated-bearing-deg", 0, true);
     _ident_node = node->getChild("ident", 0, true);
     _ident_audible_node = node->getChild("ident-audible", 0, true);
+    _power_btn_node = node->getChild("power-btn", 0, true);
+
+    if (_power_btn_node->getType() == simgear::props::NONE) 
+      _power_btn_node->setBoolValue(true); // front end didn't implement a power button
 
     SGSoundMgr *smgr = globals->get_soundmgr();
     _sgr = smgr->find("avionics", true);
@@ -117,13 +121,19 @@ void
 ADF::update (double delta_time_sec)
 {
                                 // If it's off, don't waste any time.
-    if (_electrical_node->getDoubleValue() < 1.0
-            || !_serviceable_node->getBoolValue()) {
-        set_bearing(delta_time_sec, 90);
+    if (_electrical_node->getDoubleValue() < 8.0
+            || !_serviceable_node->getBoolValue()
+            || !_power_btn_node->getBoolValue()     ) {
         _ident_node->setStringValue("");
         return;
     }
 
+    string mode = _mode_node->getStringValue();
+    if (mode == "ant" || mode == "test") set_bearing(delta_time_sec, 90);
+    if (mode != "bfo" && mode != "adf") {
+        _ident_node->setStringValue("");
+        return;
+    }
                                 // Get the frequency
     int frequency_khz = _frequency_node->getIntValue();
     if (frequency_khz != _last_frequency_khz) {
@@ -144,11 +154,7 @@ ADF::update (double delta_time_sec)
     if (_time_before_search_sec < 0)
         search(frequency_khz, longitude_rad, latitude_rad, altitude_m);
 
-                                // If it's off, don't bother.
-    string mode = _mode_node->getStringValue();
-    if (!_transmitter_valid || (mode != "bfo" && mode != "adf"))
-    {
-        set_bearing(delta_time_sec, 90);
+    if (!_transmitter_valid) {
         _ident_node->setStringValue("");
         return;
     }
@@ -208,7 +214,6 @@ ADF::update (double delta_time_sec)
         }
     } else {
         _in_range_node->setBoolValue(false);
-        set_bearing(delta_time_sec, 90);
         _ident_node->setStringValue("");
         _sgr->stop( _adf_ident );
     }
diff --git a/src/Instrumentation/adf.hxx b/src/Instrumentation/adf.hxx
index f2c2bdeb8..88817a8ee 100644
--- a/src/Instrumentation/adf.hxx
+++ b/src/Instrumentation/adf.hxx
@@ -82,6 +82,7 @@ private:
     SGPropertyNode_ptr _ident_node;
     SGPropertyNode_ptr _ident_audible_node;
     SGPropertyNode_ptr _volume_node;
+    SGPropertyNode_ptr _power_btn_node;
 
     double _time_before_search_sec;
 

From 5fc0be88202264eee65cea8f7db64bdba3ae59ee Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Wed, 19 Jan 2011 19:36:04 +0100
Subject: [PATCH 05/25] Fix bug #253, at least partially

make options
--wind=nnn@mm
--visibility
--visibility-miles
--ceiling
--turbulence
work again. These options now write properties in the
/environment/config/presets
branch. The values will be applied in the property-rules
in FGDATA/Environment/interpolator.xml
---
 projects/VC90/FlightGear/FlightGear.vcproj |   8 ++
 src/Environment/CMakeLists.txt             |   3 +-
 src/Environment/Makefile.am                |   3 +-
 src/Environment/metarproperties.cxx        |  54 +++++++--
 src/Environment/metarproperties.hxx        |   8 ++
 src/Environment/presets.cxx                | 132 +++++++++++++++++++++
 src/Environment/presets.hxx                |  94 +++++++++++++++
 src/Main/fg_commands.cxx                   |  27 ++---
 src/Main/options.cxx                       |  19 ++-
 src/Main/util.cxx                          |  74 +-----------
 src/Main/util.hxx                          |  23 ----
 11 files changed, 317 insertions(+), 128 deletions(-)
 create mode 100755 src/Environment/presets.cxx
 create mode 100755 src/Environment/presets.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index fc364e851..a5df20be7 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3413,6 +3413,14 @@
 				RelativePath="..\..\..\src\Environment\terrainsampler.hxx"
 				>
 			</File>
+			<File
+				RelativePath="..\..\..\src\Environment\presets.cxx"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\src\Environment\presets.hxx"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="Lib_Model"
diff --git a/src/Environment/CMakeLists.txt b/src/Environment/CMakeLists.txt
index 8d9c64d44..69fa003ed 100644
--- a/src/Environment/CMakeLists.txt
+++ b/src/Environment/CMakeLists.txt
@@ -15,6 +15,7 @@ set(SOURCES
 	realwx_ctrl.cxx
 	ridge_lift.cxx
 	terrainsampler.cxx
+	presets.cxx
 	)
 	
-flightgear_component(Environment "${SOURCES}")
\ No newline at end of file
+flightgear_component(Environment "${SOURCES}")
diff --git a/src/Environment/Makefile.am b/src/Environment/Makefile.am
index 5e9bcc463..90b732315 100644
--- a/src/Environment/Makefile.am
+++ b/src/Environment/Makefile.am
@@ -16,6 +16,7 @@ libEnvironment_a_SOURCES = \
 	precipitation_mgr.cxx precipitation_mgr.hxx \
 	ridge_lift.cxx ridge_lift.hxx \
 	ephemeris.cxx ephemeris.hxx \
-	terrainsampler.cxx terrainsampler.cxx
+	terrainsampler.cxx terrainsampler.cxx \
+	presets.cxx presets.cxx
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx
index 63071d02c..6d8c1c51a 100644
--- a/src/Environment/metarproperties.cxx
+++ b/src/Environment/metarproperties.cxx
@@ -158,10 +158,10 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
   _tiedProperties.Tie("max-visibility-m", &_max_visibility );
   _tiedProperties.Tie("base-wind-range-from", &_base_wind_range_from );
   _tiedProperties.Tie("base-wind-range-to", &_base_wind_range_to );
-  _tiedProperties.Tie("base-wind-speed-kt", &_wind_speed );
-  _tiedProperties.Tie("base-wind-dir-deg", &_base_wind_dir );
-  _tiedProperties.Tie("base-wind-from-north-fps", &_wind_from_north_fps );
-  _tiedProperties.Tie("base-wind-from-east-fps", &_wind_from_east_fps );
+  _tiedProperties.Tie("base-wind-speed-kt", this, &MetarProperties::get_wind_speed, &MetarProperties::set_wind_speed );
+  _tiedProperties.Tie("base-wind-dir-deg", this, &MetarProperties::get_base_wind_dir, &MetarProperties::set_base_wind_dir );
+  _tiedProperties.Tie("base-wind-from-north-fps", this, &MetarProperties::get_wind_from_north_fps, &MetarProperties::set_wind_from_north_fps );
+  _tiedProperties.Tie("base-wind-from-east-fps",this, &MetarProperties::get_wind_from_east_fps, &MetarProperties::set_wind_from_east_fps );
   _tiedProperties.Tie("gust-wind-speed-kt", &_gusts );
   _tiedProperties.Tie("temperature-degc", &_temperature );
   _tiedProperties.Tie("dewpoint-degc", &_dewpoint );
@@ -218,14 +218,11 @@ void MetarProperties::set_metar( const char * metar )
         vis->setDoubleValue("max-m", v);
     }
 
-    _base_wind_dir = m->getWindDir();
+    set_base_wind_dir(m->getWindDir());
     _base_wind_range_from = m->getWindRangeFrom();
     _base_wind_range_to = m->getWindRangeTo();
-    _wind_speed = m->getWindSpeed_kt();
+    set_wind_speed(m->getWindSpeed_kt());
 
-    double speed_fps = _wind_speed * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
-    _wind_from_north_fps = speed_fps * cos((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS);
-    _wind_from_east_fps = speed_fps * sin((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS);
     _gusts = m->getGustSpeed_kt();
     _temperature = m->getTemperature_C();
     _dewpoint = m->getDewpoint_C();
@@ -408,4 +405,43 @@ double MetarProperties::get_magnetic_dip_deg() const
   return _magneticVariation->get_dip_deg( _station_longitude, _station_latitude, _station_elevation );
 }
 
+static inline void calc_wind_hs( double north_fps, double east_fps, int & heading_deg, double & speed_kt )
+{
+    speed_kt = sqrt((north_fps)*(north_fps)+(east_fps)*(east_fps)) * 3600.0 / (SG_NM_TO_METER * SG_METER_TO_FEET);
+    heading_deg = SGMiscd::roundToInt( 
+        SGMiscd::normalizeAngle2( atan2( east_fps, north_fps ) ) * SGD_RADIANS_TO_DEGREES );
+}
+
+void MetarProperties::set_wind_from_north_fps( double value )
+{
+    _wind_from_north_fps = value;
+    calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed );
+}
+
+void MetarProperties::set_wind_from_east_fps( double value )
+{
+    _wind_from_east_fps = value;
+    calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed );
+}
+
+static inline void calc_wind_ne( double heading_deg, double speed_kt, double & north_fps, double & east_fps )
+{
+    double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
+    north_fps = speed_fps * cos(heading_deg * SGD_DEGREES_TO_RADIANS);
+    east_fps = speed_fps * sin(heading_deg * SGD_DEGREES_TO_RADIANS);
+}
+
+void MetarProperties::set_base_wind_dir( double value )
+{
+    _base_wind_dir = value;
+    calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps );
+}
+
+void MetarProperties::set_wind_speed( double value )
+{
+    _wind_speed = value;
+    calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps );
+}
+
+
 } // namespace Environment
diff --git a/src/Environment/metarproperties.hxx b/src/Environment/metarproperties.hxx
index bec445b15..0e157169e 100644
--- a/src/Environment/metarproperties.hxx
+++ b/src/Environment/metarproperties.hxx
@@ -51,6 +51,14 @@ private:
     const char * get_decoded() const { return _decoded.c_str(); }
     double get_magnetic_variation_deg() const;
     double get_magnetic_dip_deg() const;
+    double get_wind_from_north_fps() const { return _wind_from_north_fps; }
+    double get_wind_from_east_fps() const { return _wind_from_east_fps; }
+    double get_base_wind_dir() const { return _base_wind_dir; }
+    double get_wind_speed() const { return _wind_speed; }
+    void set_wind_from_north_fps( double value );
+    void set_wind_from_east_fps( double value );
+    void set_base_wind_dir( double value );
+    void set_wind_speed( double value );
 
     SGPropertyNode_ptr _rootNode;
     SGPropertyNode_ptr _metarValidNode;
diff --git a/src/Environment/presets.cxx b/src/Environment/presets.cxx
new file mode 100755
index 000000000..55da64630
--- /dev/null
+++ b/src/Environment/presets.cxx
@@ -0,0 +1,132 @@
+// presets.cxx -- Wrap environment presets
+//
+// Written by Torsten Dreyer, January 2011
+//
+// Copyright (C) 2010  Torsten Dreyer Torsten(at)t3r(dot)de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+#include "presets.hxx"
+
+#include <simgear/math/SGMisc.hxx>
+#include <Main/fg_props.hxx>
+
+namespace Environment {
+namespace Presets {
+
+PresetBase::PresetBase( const char * overrideNodePath )
+    : _overrideNodePath( overrideNodePath ) 
+{
+}
+
+void PresetBase::setOverride( bool value ) 
+{ 
+    /*
+    Don't initialize node in constructor because the class is used as a singleton
+    and created as a static variable in the initialization sequence when globals()
+    is not yet initialized and returns null.
+    */
+    if( _overrideNode == NULL ) 
+        _overrideNode = fgGetNode( _overrideNodePath.c_str(), true );
+    _overrideNode->setBoolValue( value ); 
+}
+
+
+Wind::Wind() : 
+    PresetBase("/environment/config/presets/wind-override")
+{
+}
+
+
+void Wind::preset( double min_hdg, double max_hdg, double speed_kt, double gust_kt )
+{
+    // see: PresetBase::setOverride()
+
+    //TODO: handle variable wind and gusts
+    if( _fromNorthNode == NULL )
+        _fromNorthNode = fgGetNode("/environment/config/presets/wind-from-north-fps", true );
+    
+    if( _fromEastNode == NULL )
+        _fromEastNode = fgGetNode("/environment/config/presets/wind-from-east-fps", true );
+
+    double avgHeading_rad = 
+      SGMiscd::normalizeAngle2(
+        (SGMiscd::normalizeAngle(min_hdg*SG_DEGREES_TO_RADIANS) + 
+         SGMiscd::normalizeAngle(max_hdg*SG_DEGREES_TO_RADIANS))/2);
+
+    double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
+    _fromNorthNode->setDoubleValue( speed_fps * cos(avgHeading_rad) );
+    _fromEastNode->setDoubleValue( speed_fps * sin(avgHeading_rad) );
+    setOverride( true );
+}
+
+Visibility::Visibility() : 
+    PresetBase("/environment/config/presets/visibility-m-override")
+{
+}
+
+void Visibility::preset( double visibility_m )
+{
+    // see: PresetBase::setOverride()
+    if( _visibilityNode == NULL )
+        _visibilityNode = fgGetNode("/environment/config/presets/visibility-m", true );
+
+    _visibilityNode->setDoubleValue(visibility_m );
+    setOverride( true );
+}
+
+Turbulence::Turbulence() : 
+    PresetBase("/environment/config/presets/turbulence-magnitude-norm-override")
+{
+}
+
+
+void Turbulence::preset(double magnitude_norm)
+{
+    // see: PresetBase::setOverride()
+    if( _magnitudeNode == NULL )
+        _magnitudeNode = fgGetNode("/environment/config/presets/turbulence-magnitude-norm", true );
+
+    _magnitudeNode->setDoubleValue( magnitude_norm );
+    setOverride( true );
+}
+
+Ceiling::Ceiling() : 
+    PresetBase("/environment/config/presets/ceiling-override")
+{
+}
+
+
+void Ceiling::preset( double elevation, double thickness )
+{
+    // see: PresetBase::setOverride()
+    if( _elevationNode == NULL )
+        _elevationNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true);
+
+    if( _thicknessNode == NULL )
+        _thicknessNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true);
+
+    _elevationNode->setDoubleValue( elevation );
+    _thicknessNode->setDoubleValue( thickness );
+    setOverride( true );
+}
+
+} // namespace Presets
+} // namespace Environment
+
diff --git a/src/Environment/presets.hxx b/src/Environment/presets.hxx
new file mode 100755
index 000000000..2f5b1ba12
--- /dev/null
+++ b/src/Environment/presets.hxx
@@ -0,0 +1,94 @@
+// presets.hxx -- Wrap environment presets
+//
+// Written by Torsten Dreyer, January 2011
+//
+// Copyright (C) 2010  Torsten Dreyer Torsten(at)t3r(dot)de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+
+#ifndef __ENVIRONMENT_PRESETS_HXX
+#define __ENVIRONMENT_PRESETS_HXX
+
+#include <simgear/structure/Singleton.hxx>
+#include <simgear/props/props.hxx>
+
+namespace Environment {
+
+/**
+ * @brief A wrapper for presets of environment properties
+ * mainly set from the command line with --wind=270@10, 
+ * visibility=1600 etc.
+ */
+namespace Presets {
+
+class PresetBase {
+public:
+    PresetBase( const char * overrideNodePath );
+    virtual void disablePreset() { setOverride(false); }
+protected:
+    void setOverride( bool value );
+private:
+    std::string _overrideNodePath;
+    SGPropertyNode_ptr _overrideNode;
+};
+
+class Ceiling : public PresetBase {
+public:
+    Ceiling();
+    void preset( double elevation, double thickness );
+private:
+    SGPropertyNode_ptr _elevationNode;
+    SGPropertyNode_ptr _thicknessNode;
+};
+
+typedef simgear::Singleton<Ceiling> CeilingSingleton;
+
+class Turbulence : public PresetBase {
+public:
+    Turbulence();
+    void preset( double magnitude_norm );
+private:
+    SGPropertyNode_ptr _magnitudeNode;
+};
+
+typedef simgear::Singleton<Turbulence> TurbulenceSingleton;
+
+class Wind : public PresetBase {
+public:
+    Wind();
+    void preset( double min_hdg, double max_hdg, double speed, double gust );
+private:
+    SGPropertyNode_ptr _fromNorthNode;
+    SGPropertyNode_ptr _fromEastNode;
+};
+
+typedef simgear::Singleton<Wind> WindSingleton;
+
+class Visibility : public PresetBase {
+public:
+    Visibility();
+    void preset( double visibility_m );
+private:
+    SGPropertyNode_ptr _visibilityNode;
+};
+
+typedef simgear::Singleton<Visibility> VisibilitySingleton;
+
+} // namespace Presets
+
+} // namespace Environment
+
+#endif //__ENVIRONMENT_PRESETS_HXX
diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx
index a8c45e999..2c7a24e70 100644
--- a/src/Main/fg_commands.cxx
+++ b/src/Main/fg_commands.cxx
@@ -25,7 +25,6 @@
 
 #include <Cockpit/panel.hxx>
 #include <Cockpit/panel_io.hxx>
-#include <Environment/environment.hxx>
 #include <FDM/flight.hxx>
 #include <GUI/gui.h>
 #include <GUI/new_gui.hxx>
@@ -47,6 +46,7 @@
 #include "viewmgr.hxx"
 #include "main.hxx"
 #include <Main/viewer.hxx>
+#include <Environment/presets.hxx>
 
 using std::string;
 using std::ifstream;
@@ -558,6 +558,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
 }
 
 
+#if 0
+These do_set_(some-environment-parameters) are deprecated and no longer 
+useful/functional - Torsten Dreyer, January 2011
 /**
  * Set the sea level outside air temperature and assigning that to all
  * boundary and aloft environment layers.
@@ -684,7 +687,7 @@ do_set_dewpoint_degc (const SGPropertyNode * arg)
     dummy.set_dewpoint_degc( dewpoint_degc );
     return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
 }
-
+#endif
 /**
  * Update the lighting manually.
  */
@@ -1260,29 +1263,21 @@ do_replay (const SGPropertyNode * arg)
     return true;
 }
 
-
+/*
 static bool
 do_decrease_visibility (const SGPropertyNode * arg)
 {
-    double new_value = fgGetDouble("/environment/visibility-m") * 0.9;
-    fgSetDouble("/environment/visibility-m", new_value);
-    fgDefaultWeatherValue("visibility-m", new_value);
-    globals->get_subsystem("environment")->reinit();
-
+    Environment::Presets::VisibilitySingleton::instance()->adjust( 0.9 );
     return true;
 }
  
 static bool
 do_increase_visibility (const SGPropertyNode * arg)
 {
-    double new_value = fgGetDouble("/environment/visibility-m") * 1.1;
-    fgSetDouble("/environment/visibility-m", new_value);
-    fgDefaultWeatherValue("visibility-m", new_value);
-    globals->get_subsystem("environment")->reinit();
-
+    Environment::Presets::VisibilitySingleton::instance()->adjust( 1.1 );
     return true;
 }
-
+*/
 /**
  * An fgcommand to allow loading of xml files via nasal,
  * the xml file's structure will be made available within
@@ -1454,10 +1449,12 @@ static struct {
     { "screen-capture", do_screen_capture },
     { "hires-screen-capture", do_hires_screen_capture },
     { "tile-cache-reload", do_tile_cache_reload },
+    /*
     { "set-sea-level-air-temp-degc", do_set_sea_level_degc },
     { "set-outside-air-temp-degc", do_set_oat_degc },
     { "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
     { "set-dewpoint-temp-degc", do_set_dewpoint_degc },
+    */
     { "timeofday", do_timeofday },
     { "property-toggle", do_property_toggle },
     { "property-assign", do_property_assign },
@@ -1480,8 +1477,10 @@ static struct {
     { "presets-commit", do_presets_commit },
     { "log-level", do_log_level },
     { "replay", do_replay },
+    /*
     { "decrease-visibility", do_decrease_visibility },
     { "increase-visibility", do_increase_visibility },
+    */
     { "loadxml", do_load_xml_to_proptree},
     { "savexml", do_save_xml_from_proptree },
     { "press-cockpit-button", do_press_cockpit_button },
diff --git a/src/Main/options.cxx b/src/Main/options.cxx
index 1931bb341..8af748298 100644
--- a/src/Main/options.cxx
+++ b/src/Main/options.cxx
@@ -56,6 +56,7 @@
 #include "util.hxx"
 #include "viewmgr.hxx"
 #include <Main/viewer.hxx>
+#include <Environment/presets.hxx>
 
 #include <simgear/version.h>
 #include <osg/Version>
@@ -994,18 +995,14 @@ fgOptViewOffset( const char *arg )
 static int
 fgOptVisibilityMeters( const char *arg )
 {
-    double visibility = atof( arg );
-    fgDefaultWeatherValue("visibility-m", visibility);
-    fgSetDouble("/environment/visibility-m", visibility);
+    Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) );
     return FG_OPTIONS_OK;
 }
 
 static int
 fgOptVisibilityMiles( const char *arg )
 {
-    double visibility = atof( arg ) * 5280.0 * SG_FEET_TO_METER;
-    fgDefaultWeatherValue("visibility-m", visibility);
-    fgSetDouble("/environment/visibility-m", visibility);
+    Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) * 5280.0 * SG_FEET_TO_METER );
     return FG_OPTIONS_OK;
 }
 
@@ -1016,7 +1013,7 @@ fgOptRandomWind( const char *arg )
     double max_hdg = min_hdg + (20 - sqrt(sg_random() * 400));
     double speed = sg_random() * sg_random() * 40;
     double gust = speed + (10 - sqrt(sg_random() * 100));
-    fgSetupWind(min_hdg, max_hdg, speed, gust);
+    Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust);
     return FG_OPTIONS_OK;
 }
 
@@ -1028,14 +1025,14 @@ fgOptWind( const char *arg )
 	SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg );
 	return FG_OPTIONS_ERROR;
     }
-    fgSetupWind(min_hdg, max_hdg, speed, gust);
+    Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust);
     return FG_OPTIONS_OK;
 }
 
 static int
 fgOptTurbulence( const char *arg )
 {
-    fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg));
+    Environment::Presets::TurbulenceSingleton::instance()->preset( atof(arg) );
     return FG_OPTIONS_OK;
 }
 
@@ -1052,9 +1049,7 @@ fgOptCeiling( const char *arg )
         elevation = atof(spec.substr(0, pos).c_str());
         thickness = atof(spec.substr(pos + 1).c_str());
     }
-    fgSetDouble("/environment/clouds/layer[0]/elevation-ft", elevation);
-    fgSetDouble("/environment/clouds/layer[0]/thickness-ft", thickness);
-    fgSetString("/environment/clouds/layer[0]/coverage", "overcast");
+    Environment::Presets::CeilingSingleton::instance()->preset( elevation, thickness );
     return FG_OPTIONS_OK;
 }
 
diff --git a/src/Main/util.cxx b/src/Main/util.cxx
index 7c20530a3..2cd15b5b0 100644
--- a/src/Main/util.cxx
+++ b/src/Main/util.cxx
@@ -17,7 +17,10 @@
 //
 // $Id$
 
-
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <simgear/compiler.h>
 
 #include <math.h>
@@ -28,6 +31,8 @@
 using std::vector;
 
 #include <simgear/debug/logstream.hxx>
+#include <simgear/math/SGLimits.hxx>
+#include <simgear/math/SGMisc.hxx>
 
 #include "fg_io.hxx"
 #include "fg_props.hxx"
@@ -38,73 +43,6 @@ using std::vector;
 #include "osgDB/Registry"
 #endif
 
-void
-fgDefaultWeatherValue (const char * propname, double value)
-{
-    unsigned int i;
-
-    SGPropertyNode * branch = fgGetNode("/environment/config/boundary", true);
-    vector<SGPropertyNode_ptr> entries = branch->getChildren("entry");
-    for (i = 0; i < entries.size(); i++) {
-        entries[i]->setDoubleValue(propname, value);
-    }
-
-    branch = fgGetNode("/environment/config/aloft", true);
-    entries = branch->getChildren("entry");
-    for (i = 0; i < entries.size(); i++) {
-        entries[i]->setDoubleValue(propname, value);
-    }
-}
-
-
-void
-fgSetupWind (double min_hdg, double max_hdg, double speed, double gust)
-{
-                                // Initialize to a reasonable state
-  fgDefaultWeatherValue("wind-from-heading-deg", min_hdg);
-  fgDefaultWeatherValue("wind-speed-kt", speed);
-
-  SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' <<
-         speed << " knots" << endl);
-
-                                // Now, add some variety to the layers
-  min_hdg += 10;
-  if (min_hdg > 360)
-      min_hdg -= 360;
-  speed *= 1.1;
-  fgSetDouble("/environment/config/boundary/entry[1]/wind-from-heading-deg",
-              min_hdg);
-  fgSetDouble("/environment/config/boundary/entry[1]/wind-speed-kt",
-              speed);
-
-  min_hdg += 20;
-  if (min_hdg > 360)
-      min_hdg -= 360;
-  speed *= 1.1;
-  fgSetDouble("/environment/config/aloft/entry[0]/wind-from-heading-deg",
-              min_hdg);
-  fgSetDouble("/environment/config/aloft/entry[0]/wind-speed-kt",
-              speed);
-
-  min_hdg += 10;
-  if (min_hdg > 360)
-      min_hdg -= 360;
-  speed *= 1.1;
-  fgSetDouble("/environment/config/aloft/entry[1]/wind-from-heading-deg",
-              min_hdg);
-  fgSetDouble("/environment/config/aloft/entry[1]/wind-speed-kt",
-              speed);
-
-  min_hdg += 10;
-  if (min_hdg > 360)
-      min_hdg -= 360;
-  speed *= 1.1;
-  fgSetDouble("/environment/config/aloft/entry[2]/wind-from-heading-deg",
-              min_hdg);
-  fgSetDouble("/environment/config/aloft/entry[2]/wind-speed-kt",
-              speed);
-}
-
 // Originally written by Alex Perry.
 double
 fgGetLowPass (double current, double target, double timeratio)
diff --git a/src/Main/util.hxx b/src/Main/util.hxx
index dcd75b130..acb25ac0d 100644
--- a/src/Main/util.hxx
+++ b/src/Main/util.hxx
@@ -26,29 +26,6 @@
 #endif
 
 
-/**
- * Initialize a single value through all existing weather levels.
- *
- * This function is useful mainly from the command-line.
- *
- * @param propname The name of the subproperty to initialized.
- * @param value The initial value.
- */
-extern void fgDefaultWeatherValue (const char * propname, double value);
-
-
-/**
- * Set up a plausible wind layout, boundary and aloft,
- * based on just a few parameters.
- *
- * @param min_hdg Minimal wind heading
- * @param max_hdg Maximal wind heading
- * @param speed Windspeed in knots
- * @param gust Wind gust variation in knots
- */
-extern void fgSetupWind (double min_hdg, double max_hdg,
-                         double speed, double gust);
-
 /**
  * Move a value towards a target.
  *

From 258a4436aa7c481a230c1c83511c9df516d170ad Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Fri, 21 Jan 2011 10:35:04 +0100
Subject: [PATCH 06/25] Fix bug 255, support turbulence to weather menu

---
 src/Environment/Makefile.am     | 2 +-
 src/Environment/environment.cxx | 8 --------
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/src/Environment/Makefile.am b/src/Environment/Makefile.am
index 90b732315..c3b1b5fbf 100644
--- a/src/Environment/Makefile.am
+++ b/src/Environment/Makefile.am
@@ -17,6 +17,6 @@ libEnvironment_a_SOURCES = \
 	ridge_lift.cxx ridge_lift.hxx \
 	ephemeris.cxx ephemeris.hxx \
 	terrainsampler.cxx terrainsampler.cxx \
-	presets.cxx presets.cxx
+	presets.cxx presets.hxx
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx
index a27189b24..4e245554b 100644
--- a/src/Environment/environment.cxx
+++ b/src/Environment/environment.cxx
@@ -27,14 +27,9 @@
 
 #include <boost/tuple/tuple.hpp>
 
-#include <simgear/constants.h>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/math/interpolater.hxx>
 #include <simgear/props/props.hxx>
-#include <simgear/environment/visual_enviro.hxx>
 
 #include <Main/fg_props.hxx>
-#include <signal.h>
 
 #include "environment.hxx"
 #include "atmosphere.hxx"
@@ -472,9 +467,6 @@ FGEnvironment::get_wind_from_down_fps () const
 double
 FGEnvironment::get_turbulence_magnitude_norm () const
 {
-  if( sgEnviro.get_turbulence_enable_state() )
-    if (fgGetBool("/environment/realwx/enabled")||fgGetBool("/environment/metar/valid"))
-      return sgEnviro.get_cloud_turbulence();
   return turbulence_magnitude_norm;
 }
 

From 99ee9a1bbb60eb4fd17ff9cec252fb8c88305b56 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Fri, 21 Jan 2011 19:55:42 +0100
Subject: [PATCH 07/25] GPWS: avoid "altitude_callout_voice != NULL" assertion
 Properly remember which active alerts were already voiced. Added NULL-pointer
 safety check

---
 src/Instrumentation/mk_viii.cxx | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx
index 745ed6c2e..8fb871a4a 100755
--- a/src/Instrumentation/mk_viii.cxx
+++ b/src/Instrumentation/mk_viii.cxx
@@ -2319,6 +2319,8 @@ MK_VIII::VoicePlayer::get_sample (const char *name)
 void
 MK_VIII::VoicePlayer::play (Voice *_voice, unsigned int flags)
 {
+  if (!_voice)
+      return;
   if (test_bits(flags, PLAY_NOW) || ! voice || voice->element->silence)
     {
       if (voice)
@@ -2978,9 +2980,10 @@ MK_VIII::AlertHandler::update ()
 	mk->voice_player.play(mk_voice(bank_angle_pause_bank_angle));
     }
 
-  // set new state
-
-  old_alerts = voice_alerts;
+  // remember all alerts voiced so far...
+  old_alerts |= voice_alerts;
+  // ... forget those no longer active
+  old_alerts &= alerts;
   repeated_alerts = 0;
 }
 

From d365689d5c1641369219bbc07ba74016a72cd266 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Fri, 21 Jan 2011 23:44:23 +0100
Subject: [PATCH 08/25] Fix crash in GPS module. Fixes crash on exit (during
 property untie). Also potential run-time crash.

---
 src/Instrumentation/gps.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx
index 853d49d46..f0ecf6f04 100644
--- a/src/Instrumentation/gps.cxx
+++ b/src/Instrumentation/gps.cxx
@@ -1158,7 +1158,7 @@ double GPS::getWP1Bearing() const
 
 double GPS::getWP1MagBearing() const
 {
-  if (!_dataValid) {
+  if (!_dataValid || !_wayptController.get()) {
     return -9999.0;
   }
 

From db3717a30eaff128d6d029bd798b40cac86ca260 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 19 Jan 2011 12:14:59 +0000
Subject: [PATCH 09/25] Working Cmake-terrasync-libsvn support. Probably needs
 additional refinement, but testable.

---
 CMakeModules/FindSvnClient.cmake | 17 ++++++++---------
 utils/TerraSync/CMakeLists.txt   |  5 ++---
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake
index 51f4452bf..717b8b04d 100644
--- a/CMakeModules/FindSvnClient.cmake
+++ b/CMakeModules/FindSvnClient.cmake
@@ -6,11 +6,8 @@ include (CheckIncludeFile)
 
 find_program(HAVE_APR_CONFIG apr-1-config)
 if(HAVE_APR_CONFIG) 
-    execute_process(COMMAND apr-1-config --includes
-        OUTPUT_VARIABLE RAW_APR_INCLUDES
-        OUTPUT_STRIP_TRAILING_WHITESPACE)
         
-    execute_process(COMMAND apr-1-config --cppflags
+    execute_process(COMMAND apr-1-config --cppflags --includes
         OUTPUT_VARIABLE APR_CFLAGS
         OUTPUT_STRIP_TRAILING_WHITESPACE)
         
@@ -20,7 +17,6 @@ if(HAVE_APR_CONFIG)
     
 # clean up some vars, or other CMake pieces complain
 	string(STRIP ${RAW_APR_LIBS} APR_LIBS)
-	string(STRIP ${RAW_APR_INCLUDES} APR_INCLUDES)
 
 else(HAVE_APR_CONFIG)
     message(STATUS "apr-1-config not found, implement manual search for APR")
@@ -38,12 +34,15 @@ find_path(LIBSVN_INCLUDE_DIR svn_client.h
 
 check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT)
 check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR)
+check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA)
 
 include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG HAVE_LIB_SVNSUBR 
-    HAVE_LIB_SVNCLIENT LIBSVN_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG 
+    HAVE_LIB_SVNSUBR 
+    HAVE_LIB_SVNCLIENT
+    HAVE_LIB_SVNRA 
+    LIBSVN_INCLUDE_DIR)
 
 if(LIBSVN_FOUND)
-    set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" ${APR_LIBS})
-	set(LIBSVN_INCLUDE_DIRS ${LIBSVN_INCLUDE_DIR} ${APR_INCLUDES})
+    set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS})
 endif(LIBSVN_FOUND)
diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index c44af48bf..86526eb0b 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -1,8 +1,6 @@
 
 if(LIBSVN_FOUND)
-	message(STATUS "includes '${LIBSVN_INCLUDE_DIRS}'")
-	include_directories(${LIBSVN_INCLUDE_DIRS})
-	add_definitions(${APR_CFLAGS})
+	include_directories(${LIBSVN_INCLUDE_DIR})
 endif(LIBSVN_FOUND)
 	
 add_executable(terrasync terrasync.cxx)
@@ -14,6 +12,7 @@ target_link_libraries(terrasync
 
 if(LIBSVN_FOUND)
 	target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
+	set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS ${APR_CFLAGS})
 endif()
 
 

From 45b239fe2677093d1e1d245e4dec2e591f093f73 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 22 Jan 2011 19:25:34 +0000
Subject: [PATCH 10/25] Support the 1.4 SVN checkout API

---
 utils/TerraSync/terrasync.cxx | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx
index bcf6e0ca8..8776cdc5a 100644
--- a/utils/TerraSync/terrasync.cxx
+++ b/utils/TerraSync/terrasync.cxx
@@ -229,16 +229,31 @@ void sync_tree(const char* dir) {
 	if (mysvn_setup() != EXIT_SUCCESS)
 	    exit(1);
 	apr_pool_t *subpool = svn_pool_create(mysvn_pool);
+	
+#if (SVN_VER_MINOR >= 5)
 	err = svn_client_checkout3(NULL,
 	    command,
 	    dest_base_dir,
 	    mysvn_rev_peg,
 	    mysvn_rev,
 	    svn_depth_infinity,
-	    0,
-	    0,
+	    0, // ignore-externals = false
+	    0, // allow unver obstructions = false
 	    mysvn_ctx,
 	    subpool);
+#else
+    // version 1.4 API
+    err = svn_client_checkout2(NULL,
+	    command,
+	    dest_base_dir,
+	    mysvn_rev_peg,
+	    mysvn_rev,
+	    1, // recurse=true - same as svn_depth_infinity for checkout3 above
+	    0, // ignore externals = false
+	    mysvn_ctx,
+	    subpool);
+#endif
+	    
 	if (err) {
 	    // Report errors from the checkout attempt
 	    cout << "failed: " << endl

From 0ad9ac4f3daf6360c91898d877ec8dbdbe08de06 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 22 Jan 2011 18:49:54 +0000
Subject: [PATCH 11/25] Fix Apple libsvn include for isysroot (SDK) builds.

---
 utils/TerraSync/CMakeLists.txt | 11 +++++++----
 utils/TerraSync/terrasync.cxx  |  2 ++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt
index 86526eb0b..88b208c16 100644
--- a/utils/TerraSync/CMakeLists.txt
+++ b/utils/TerraSync/CMakeLists.txt
@@ -1,7 +1,4 @@
 
-if(LIBSVN_FOUND)
-	include_directories(${LIBSVN_INCLUDE_DIR})
-endif(LIBSVN_FOUND)
 	
 add_executable(terrasync terrasync.cxx)
 
@@ -12,7 +9,13 @@ target_link_libraries(terrasync
 
 if(LIBSVN_FOUND)
 	target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
-	set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS ${APR_CFLAGS})
+	set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS "${APR_CFLAGS}")
+	
+	IF(APPLE)
+	    set_property(SOURCE terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
+	ELSE()
+	    include_directories(${LIBSVN_INCLUDE_DIR})
+	ENDIF(APPLE)
 endif()
 
 
diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx
index 8776cdc5a..f1a2cc46b 100644
--- a/utils/TerraSync/terrasync.cxx
+++ b/utils/TerraSync/terrasync.cxx
@@ -183,8 +183,10 @@ int mysvn_setup(void) {
     if (err)
         return svn_cmdline_handle_exit_error(err, pool, "terrasync: ");
     mysvn_ctx->auth_baton = ab;
+#if (SVN_VER_MINOR >= 5)
     mysvn_ctx->conflict_func = NULL;
     mysvn_ctx->conflict_baton = NULL;
+#endif
     // Now our magic revisions
     mysvn_rev = (svn_opt_revision_t*) apr_palloc(pool, 
         sizeof(svn_opt_revision_t));

From 59d06d130d4803836de43cda40575a1e8e90c52c Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 23 Jan 2011 00:45:06 +0100
Subject: [PATCH 12/25] Make route editing sane. Drag&drop, insert and remove
 now update the current waypoint as expected.

---
 src/Autopilot/route_mgr.cxx | 16 ++++++++++------
 src/GUI/WaypointList.cxx    |  6 ++++++
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx
index 127e2c397..8f2cacf59 100644
--- a/src/Autopilot/route_mgr.cxx
+++ b/src/Autopilot/route_mgr.cxx
@@ -352,11 +352,6 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex)
     SG_LOG(SG_AUTOPILOT, SG_WARN, "removeWayptAtIndex with invalid index:" << aIndex);
     return NULL;
   }
-  
-  if (_currentIndex > index) {
-    --_currentIndex; // shift current index down if necessary
-  }
-
   WayptVec::iterator it = _route.begin();
   it += index;
   
@@ -364,6 +359,15 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex)
   _route.erase(it);
   
   update_mirror();
+  
+  if (_currentIndex == index) {
+    currentWaypointChanged(); // current waypoint was removed
+  }
+  else
+  if (_currentIndex > index) {
+    --_currentIndex; // shift current index down if necessary
+  }
+
   _edited->fireValueChanged();
   checkFinished();
   
@@ -680,7 +684,7 @@ void FGRouteMgr::insertWayptAtIndex(Waypt* aWpt, int aIndex)
   WayptVec::iterator it = _route.begin();
   it += index;
       
-  if (_currentIndex > index) {
+  if (_currentIndex >= index) {
     ++_currentIndex;
   }
   
diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx
index 31c5e480c..f525f213b 100644
--- a/src/GUI/WaypointList.cxx
+++ b/src/GUI/WaypointList.cxx
@@ -83,9 +83,15 @@ public:
       --destIndex;
     }
     
+    int currentWpIndex = currentWaypoint();
     WayptRef w(_rm->removeWayptAtIndex(srcIndex));
     SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident());
     _rm->insertWayptAtIndex(w, destIndex);
+
+    if (srcIndex == currentWpIndex) {
+        // current waypoint was moved
+        _rm->jumpToIndex(destIndex);
+    }
   }
   
   virtual void setUpdateCallback(SGCallback* cb)

From ee26505e28888d70990f98990c5788236b49a276 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 23 Jan 2011 15:07:09 +0100
Subject: [PATCH 13/25] Added sanity checks to MP receive/send. Stop invalid
 data (NaN values) from being sent or received via MP.

---
 src/MultiPlayer/multiplaymgr.cxx | 49 ++++++++++++++++++++++++++++----
 src/MultiPlayer/multiplaymgr.hxx |  3 +-
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx
index 1d36ec257..89d2eb85a 100644
--- a/src/MultiPlayer/multiplaymgr.cxx
+++ b/src/MultiPlayer/multiplaymgr.cxx
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////
 //
-// multiplaymgr.hpp
+// multiplaymgr.cxx
 //
 // Written by Duncan McCreanor, started February 2003.
 // duncan.mccreanor@airservicesaustralia.com
@@ -526,14 +526,44 @@ union FGMultiplayMgr::MsgBuf
     T_MsgHdr Header;
 };
 
+bool
+FGMultiplayMgr::isSane(const FGExternalMotionData& motionInfo)
+{
+    // check for corrupted data (NaNs)
+    bool isCorrupted = false;
+    isCorrupted |= ((osg::isNaN(motionInfo.time           )) ||
+                    (osg::isNaN(motionInfo.lag            )) ||
+                    (osg::isNaN(motionInfo.orientation(3) )));
+    for (unsigned i = 0; (i < 3)&&(!isCorrupted); ++i)
+    {
+        isCorrupted |= ((osg::isNaN(motionInfo.position(i)      ))||
+                        (osg::isNaN(motionInfo.orientation(i)   ))||
+                        (osg::isNaN(motionInfo.linearVel(i))    )||
+                        (osg::isNaN(motionInfo.angularVel(i))   )||
+                        (osg::isNaN(motionInfo.linearAccel(i))  )||
+                        (osg::isNaN(motionInfo.angularAccel(i)) ));
+    }
+    return !isCorrupted;
+}
+
 void
 FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
 {
   if ((! mInitialised) || (! mHaveServer))
         return;
+
   if (! mHaveServer) {
-    SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server");
-    return;
+      SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server");
+      return;
+  }
+
+  if (!isSane(motionInfo))
+  {
+      // Current local data is invalid (NaN), so stop MP transmission.
+      // => Be nice to older FG versions (no NaN checks) and don't waste bandwidth.
+      SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - "
+              << "Local data is invalid (NaN). Data not transmitted.");
+      return;
   }
 
   static MsgBuf msgBuf;
@@ -780,7 +810,7 @@ FGMultiplayMgr::update(double)
     }
     if (MsgHdr->Version != PROTO_VER) {
       SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
-              << "message has invalid protocoll number!" );
+              << "message has invalid protocol number!" );
       break;
     }
     if (MsgHdr->MsgLen != bytes) {
@@ -858,6 +888,15 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
   for (unsigned i = 0; i < 3; ++i)
     motionInfo.angularAccel(i) = XDR_decode_float(PosMsg->angularAccel[i]);
 
+  // sanity check: do not allow injection of corrupted data (NaNs)
+  if (!isSane(motionInfo))
+  {
+      // drop this message, keep old position until receiving valid data
+      SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::ProcessPosMsg - "
+              << "Position message with invalid data (NaN) received from "
+              << MsgHdr->Callsign);
+      return;
+  }
 
   //cout << "INPUT MESSAGE\n";
 
@@ -953,7 +992,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
           SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type);
           xdr++;
           break;
-      }            
+      }
 
       motionInfo.properties.push_back(pData);
     }
diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx
index 5a08e1aab..8475c0ef1 100644
--- a/src/MultiPlayer/multiplaymgr.hxx
+++ b/src/MultiPlayer/multiplaymgr.hxx
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////
 //
-// multiplaymgr.hpp
+// multiplaymgr.hxx
 //
 // Written by Duncan McCreanor, started February 2003.
 // duncan.mccreanor@airservicesaustralia.com
@@ -81,6 +81,7 @@ private:
   void ProcessPosMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress,
                      long stamp);
   void ProcessChatMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress);
+  bool isSane(const FGExternalMotionData& motionInfo);
 
   /// maps from the callsign string to the FGAIMultiplayer
   typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;

From e64b3823974cb1d822ffb376d15d323a818bc9e5 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 23 Jan 2011 15:24:28 +0100
Subject: [PATCH 14/25] Report stopped MP transmission at higher log level,
 it's too important to be a "debug only" message.

---
 src/MultiPlayer/multiplaymgr.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx
index 89d2eb85a..7657ad4ee 100644
--- a/src/MultiPlayer/multiplaymgr.cxx
+++ b/src/MultiPlayer/multiplaymgr.cxx
@@ -561,7 +561,7 @@ FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
   {
       // Current local data is invalid (NaN), so stop MP transmission.
       // => Be nice to older FG versions (no NaN checks) and don't waste bandwidth.
-      SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - "
+      SG_LOG(SG_NETWORK, SG_ALERT, "FGMultiplayMgr::SendMyPosition - "
               << "Local data is invalid (NaN). Data not transmitted.");
       return;
   }

From 6cb4fbcf0afb760a3be3631f86cdb292a4ea1377 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Mon, 24 Jan 2011 19:41:56 +0100
Subject: [PATCH 15/25] Bugfix: reset transparency of non fog/mist/haze layers

---
 src/Environment/metarproperties.cxx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx
index 6d8c1c51a..171d716af 100644
--- a/src/Environment/metarproperties.cxx
+++ b/src/Environment/metarproperties.cxx
@@ -374,6 +374,7 @@ void MetarProperties::set_metar( const char * metar )
                 -9999.0 : 
                 metarClouds[i].getAltitude_ft() + _station_elevation;
 
+            layerNode->setDoubleValue( "alpha", 1.0 );
             layerNode->setStringValue( "coverage", coverage_string[coverage] );
             layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) );
             layerNode->setDoubleValue( "elevation-ft", elevation );

From 53e8fbfcbb3ddac0dc261043fea7bd24dfa6e62d Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 25 Jan 2011 00:26:07 +0000
Subject: [PATCH 16/25] Andreas Gaeb: fix #222 (JSBSIm reset problems)

---
 src/FDM/JSBSim/JSBSim.cxx             | 2 ++
 src/FDM/JSBSim/models/FGPropagate.cpp | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index d92d265f0..4fb0f43ed 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -292,6 +292,8 @@ FGJSBsim::FGJSBsim( double dt )
         fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-x-in", 196),
         fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-y-in", 0),
         fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-z-in", -16));
+    last_hook_tip[0] = 0; last_hook_tip[1] = 0; last_hook_tip[2] = 0;
+    last_hook_root[0] = 0; last_hook_root[1] = 0; last_hook_root[2] = 0;
 
     crashed = false;
 }
diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp
index 5405c8639..d917420d8 100644
--- a/src/FDM/JSBSim/models/FGPropagate.cpp
+++ b/src/FDM/JSBSim/models/FGPropagate.cpp
@@ -78,7 +78,8 @@ static const char *IdHdr = ID_PROPAGATE;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex)
+FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex),
+LocalTerrainRadius(0), SeaLevelRadius(0), VehicleRadius(0)
 {
   Debug(0);
   Name = "FGPropagate";

From 67978f92e553953f8b13710d57741602d796e08f Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Fri, 28 Jan 2011 00:06:23 +0100
Subject: [PATCH 17/25] Proposed fix for #251: Waypoint handling Do not
 consider destination/runway waypoints as done, when these are far away - even
 if the course is off by > 90 degrees.

---
 src/Instrumentation/rnav_waypt_controller.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Instrumentation/rnav_waypt_controller.cxx b/src/Instrumentation/rnav_waypt_controller.cxx
index 09ac2b812..278484d0a 100644
--- a/src/Instrumentation/rnav_waypt_controller.cxx
+++ b/src/Instrumentation/rnav_waypt_controller.cxx
@@ -221,7 +221,7 @@ private:
 
 /**
  * Special controller for runways. For runways, we want very narrow deviation
- * contraints, and to understand that any point along the paved area is
+ * constraints, and to understand that any point along the paved area is
  * equivalent to being 'at' the runway.
  */
 class RunwayCtl : public WayptController
@@ -252,7 +252,7 @@ public:
     double _courseDev = brg - _targetTrack;
     SG_NORMALIZE_RANGE(_courseDev, -180.0, 180.0);
     
-    if (fabs(_courseDev) > 90.0) {
+    if ((fabs(_courseDev) > 90.0) && (_distanceM < _rnav->overflightArmDistanceM())) {
       setDone();
     }
   } 

From b649f97b19b60ae273bf18e25b9539363b3d1c9a Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 6 Feb 2011 15:33:27 +0100
Subject: [PATCH 18/25] Fix for bug #204 and #222 by Bertrand Coconnier; NaNs
 (bug #222) were basically generated because the method JSBSim::unbind() was
 not implemented in JSBSim.cxx.

---
 src/FDM/JSBSim/JSBSim.cxx              | 27 ++++++++++++++++++++++++++
 src/FDM/JSBSim/JSBSim.hxx              |  5 +++--
 src/FDM/JSBSim/models/FGPropulsion.cpp |  8 ++++++--
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index 4fb0f43ed..a2d217ba2 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -424,6 +424,33 @@ void FGJSBsim::init()
 
 /******************************************************************************/
 
+void checkTied ( FGPropertyManager *node )
+{
+  int N = node->nChildren();
+  string name;
+
+  for (int i=0; i<N; i++) {
+    if (node->getChild(i)->nChildren() ) {
+      checkTied( (FGPropertyManager*)node->getChild(i) );
+    }
+    if ( node->getChild(i)->isTied() ) {
+      name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
+      node->Untie(name);
+    }
+  }
+}
+
+/******************************************************************************/
+
+void FGJSBsim::unbind()
+{
+  SGPropertyNode* instance = globals->get_props()->getNode("/fdm/jsbsim");
+  checkTied((FGPropertyManager*)instance);
+  FGInterface::unbind();
+}
+
+/******************************************************************************/
+
 // Run an iteration of the EOM (equations of motion)
 
 void FGJSBsim::update( double dt )
diff --git a/src/FDM/JSBSim/JSBSim.hxx b/src/FDM/JSBSim/JSBSim.hxx
index 1a8037167..a01146bcc 100644
--- a/src/FDM/JSBSim/JSBSim.hxx
+++ b/src/FDM/JSBSim/JSBSim.hxx
@@ -110,6 +110,9 @@ public:
     /// Reset flight params to a specific position
     void init();
 
+    /// Unbind properties
+    void unbind();
+
     /// @name Position Parameter Set
     //@{
     /** Set geocentric latitude
@@ -283,8 +286,6 @@ private:
     void update_gear(void);
 
     void update_external_forces(double t_off);
-
-    void resetPropertyState();
 };
 
 
diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp
index 57d2852f3..05a2da4c4 100644
--- a/src/FDM/JSBSim/models/FGPropulsion.cpp
+++ b/src/FDM/JSBSim/models/FGPropulsion.cpp
@@ -307,18 +307,23 @@ bool FGPropulsion::Load(Element* el)
     try {
       if (type == "piston_engine") {
         HavePistonEngine = true;
+        if (!IsBound) bind();
         Engines.push_back(new FGPiston(FDMExec, document, numEngines));
       } else if (type == "turbine_engine") {
         HaveTurbineEngine = true;
+        if (!IsBound) bind();
         Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
       } else if (type == "turboprop_engine") {
         HaveTurboPropEngine = true;
+        if (!IsBound) bind();
         Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
       } else if (type == "rocket_engine") {
         HaveRocketEngine = true;
+        if (!IsBound) bind();
         Engines.push_back(new FGRocket(FDMExec, document, numEngines));
       } else if (type == "electric_engine") {
         HaveElectricEngine = true;
+        if (!IsBound) bind();
         Engines.push_back(new FGElectric(FDMExec, document, numEngines));
       } else {
         cerr << "Unknown engine type: " << type << endl;
@@ -345,7 +350,6 @@ bool FGPropulsion::Load(Element* el)
   if (el->FindElement("dump-rate"))
     DumpRate = el->FindElementValueAsNumberConvertTo("dump-rate", "LBS/MIN");
 
-  if (!IsBound) bind();
   PostLoad(el, PropertyManager);
 
   return true;
@@ -642,7 +646,7 @@ void FGPropulsion::bind(void)
   typedef int (FGPropulsion::*iPMF)(void) const;
 
   IsBound = true;
-  PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, true);
+  PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false);
   if (HaveTurbineEngine) {
     PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter,  true);
     PropertyManager->Tie("propulsion/cutoff_cmd", this,  (iPMF)0, &FGPropulsion::SetCutoff,   true);

From 68728c944962f17a3754c63b4d61e58ff5bcd365 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 30 Jan 2011 16:05:28 +0100
Subject: [PATCH 19/25] Betrand Coconnier: fix bugs #47,#184: roll/pitch/speed
 via command-line Specifying initial roll, pitch and speed should be working
 again.

---
 src/FDM/flight.cxx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx
index 5676e688b..d501d1507 100644
--- a/src/FDM/flight.cxx
+++ b/src/FDM/flight.cxx
@@ -268,15 +268,15 @@ FGInterface::bind ()
 				// Orientation
   fgTie("/orientation/roll-deg", this,
 	&FGInterface::get_Phi_deg,
-	&FGInterface::set_Phi_deg);
+	&FGInterface::set_Phi_deg, false);
   fgSetArchivable("/orientation/roll-deg");
   fgTie("/orientation/pitch-deg", this,
 	&FGInterface::get_Theta_deg,
-	&FGInterface::set_Theta_deg);
+	&FGInterface::set_Theta_deg, false);
   fgSetArchivable("/orientation/pitch-deg");
   fgTie("/orientation/heading-deg", this,
 	&FGInterface::get_Psi_deg,
-	&FGInterface::set_Psi_deg);
+	&FGInterface::set_Psi_deg, false);
   fgSetArchivable("/orientation/heading-deg");
   fgTie("/orientation/track-deg", this,
 	&FGInterface::get_Track);
@@ -331,11 +331,11 @@ FGInterface::bind ()
 				// LaRCSim are fixed (LaRCSim adds the
 				// earth's rotation to the east velocity).
   fgTie("/velocities/speed-north-fps", this,
-	&FGInterface::get_V_north, &FGInterface::set_V_north);
+	&FGInterface::get_V_north, &FGInterface::set_V_north, false);
   fgTie("/velocities/speed-east-fps", this,
-	&FGInterface::get_V_east, &FGInterface::set_V_east);
+	&FGInterface::get_V_east, &FGInterface::set_V_east, false);
   fgTie("/velocities/speed-down-fps", this,
-	&FGInterface::get_V_down, &FGInterface::set_V_down);
+	&FGInterface::get_V_down, &FGInterface::set_V_down, false);
 
   fgTie("/velocities/north-relground-fps", this,
     &FGInterface::get_V_north_rel_ground);

From 6b6d7059de394bf270c8a0660820c5fc0a4c7fd4 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 5 Feb 2011 17:49:26 +0100
Subject: [PATCH 20/25] Improved fix for #204 and #222: JSBSim::unbind() needs
 to untie _all_ its properties Extends and partially reverts commit
 287cc74965e11ff3888117a9d9b88ed2bdbb9252 Previous fix did not consider
 properties outside the /fdm/jsbsim branch. FGPropertyManager now keeps track
 of all its tied properties - and provides a method to cleanly untie them
 again.

---
 src/FDM/JSBSim/FGFDMExec.h                    |  7 +++++--
 src/FDM/JSBSim/JSBSim.cxx                     | 21 +------------------
 .../JSBSim/input_output/FGPropertyManager.cpp | 18 ++++++++++++++++
 .../JSBSim/input_output/FGPropertyManager.h   |  8 +++++++
 4 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h
index 10736f4a4..c1038c471 100644
--- a/src/FDM/JSBSim/FGFDMExec.h
+++ b/src/FDM/JSBSim/FGFDMExec.h
@@ -101,8 +101,8 @@ CLASS DOCUMENTATION
     file:
 
     @code
-    fdmex = new FGFDMExec( � );
-    result = fdmex->LoadModel( � );
+    fdmex = new FGFDMExec( ... );
+    result = fdmex->LoadModel( ... );
     @endcode
 
     When an aircraft model is loaded, the config file is parsed and for each of the
@@ -226,6 +226,9 @@ public:
   /// Default destructor
   ~FGFDMExec();
 
+  /** Unbind all tied JSBSim properties. */
+  void unbind(void) {instance->unbind();}
+
   /** This routine places a model into the runlist at the specified rate. The
       "rate" is not really a clock rate. It represents how many calls to the
       FGFDMExec::Run() method must be made before the model is executed. A
diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index a2d217ba2..ba35d6900 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -424,28 +424,9 @@ void FGJSBsim::init()
 
 /******************************************************************************/
 
-void checkTied ( FGPropertyManager *node )
-{
-  int N = node->nChildren();
-  string name;
-
-  for (int i=0; i<N; i++) {
-    if (node->getChild(i)->nChildren() ) {
-      checkTied( (FGPropertyManager*)node->getChild(i) );
-    }
-    if ( node->getChild(i)->isTied() ) {
-      name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
-      node->Untie(name);
-    }
-  }
-}
-
-/******************************************************************************/
-
 void FGJSBsim::unbind()
 {
-  SGPropertyNode* instance = globals->get_props()->getNode("/fdm/jsbsim");
-  checkTied((FGPropertyManager*)instance);
+  fdmex->unbind();
   FGInterface::unbind();
 }
 
diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
index 11e566965..899565ed2 100755
--- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
+++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
@@ -49,6 +49,19 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
 namespace JSBSim {
 
 bool FGPropertyManager::suppress_warning = true;
+std::vector<std::string> FGPropertyManager::tied_properties;
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGPropertyManager::unbind(void)
+{
+    vector<string>::iterator it;
+    for (it = tied_properties.begin();it < tied_properties.end();it++)
+    {
+        Untie(*it);
+    }
+    tied_properties.clear();
+}
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -301,6 +314,7 @@ void FGPropertyManager::Untie (const string &name)
 
 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 {
+  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else if (debug_lvl & 0x20)
@@ -312,6 +326,7 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 void FGPropertyManager::Tie (const string &name, int *pointer,
                                           bool useDefault )
 {
+  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else if (debug_lvl & 0x20)
@@ -323,6 +338,7 @@ void FGPropertyManager::Tie (const string &name, int *pointer,
 void FGPropertyManager::Tie (const string &name, long *pointer,
                                           bool useDefault )
 {
+  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else if (debug_lvl & 0x20)
@@ -334,6 +350,7 @@ void FGPropertyManager::Tie (const string &name, long *pointer,
 void FGPropertyManager::Tie (const string &name, float *pointer,
                                           bool useDefault )
 {
+  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else if (debug_lvl & 0x20)
@@ -344,6 +361,7 @@ void FGPropertyManager::Tie (const string &name, float *pointer,
 
 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
 {
+  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
   else if (debug_lvl & 0x20)
diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h
index c29b5a412..54ea91874 100644
--- a/src/FDM/JSBSim/input_output/FGPropertyManager.h
+++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h
@@ -77,6 +77,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
 {
   private:
     static bool suppress_warning;
+    static std::vector<std::string> tied_properties;
   public:
     /// Constructor
     FGPropertyManager(void) {suppress_warning = false;}
@@ -399,6 +400,13 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
      */
     void Untie (const std::string &name);
 
+    /**
+     * Unbind all properties bound by this manager to an external data source.
+     *
+     * Classes should use this function to release control of any
+     * properties they have bound using this property manager.
+     */
+    void unbind (void);
 
         // Templates cause ambiguity here
 

From ac717783197dace28bd4f9946f757fc22c26085a Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 6 Feb 2011 15:16:58 +0100
Subject: [PATCH 21/25] Bertrand Coconnier: updated fix for #204 and #222:
 JSBSim reset Use shared property pointers instead of path strings, adapt
 method names to JSBSim style, catch all property ties, proper error handling
 when tieing failed.

---
 src/FDM/JSBSim/FGFDMExec.cpp                  | 18 +--------
 src/FDM/JSBSim/FGFDMExec.h                    |  2 +-
 src/FDM/JSBSim/JSBSim.cxx                     |  2 +-
 .../JSBSim/input_output/FGPropertyManager.cpp | 37 +++++++++++--------
 .../JSBSim/input_output/FGPropertyManager.h   | 26 ++++++++-----
 5 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp
index ab0bf8a9a..25c5bdd17 100644
--- a/src/FDM/JSBSim/FGFDMExec.cpp
+++ b/src/FDM/JSBSim/FGFDMExec.cpp
@@ -78,22 +78,6 @@ static const char *IdHdr = ID_FDMEXEC;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-void checkTied ( FGPropertyManager *node )
-{
-  int N = node->nChildren();
-  string name;
-
-  for (int i=0; i<N; i++) {
-    if (node->getChild(i)->nChildren() ) {
-      checkTied( (FGPropertyManager*)node->getChild(i) );
-    }
-    if ( node->getChild(i)->isTied() ) {
-      name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
-      node->Untie(name);
-    }
-  }
-}
-
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Constructor
 
@@ -185,7 +169,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root)
 FGFDMExec::~FGFDMExec()
 {
   try {
-    checkTied( instance );
+    Unbind();
     DeAllocate();
     
     if (IdFDM == 0) { // Meaning this is no child FDM
diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h
index c1038c471..b982654e7 100644
--- a/src/FDM/JSBSim/FGFDMExec.h
+++ b/src/FDM/JSBSim/FGFDMExec.h
@@ -227,7 +227,7 @@ public:
   ~FGFDMExec();
 
   /** Unbind all tied JSBSim properties. */
-  void unbind(void) {instance->unbind();}
+  void Unbind(void) {instance->Unbind();}
 
   /** This routine places a model into the runlist at the specified rate. The
       "rate" is not really a clock rate. It represents how many calls to the
diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index ba35d6900..0f8d5130a 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -426,7 +426,7 @@ void FGJSBsim::init()
 
 void FGJSBsim::unbind()
 {
-  fdmex->unbind();
+  fdmex->Unbind();
   FGInterface::unbind();
 }
 
diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
index 899565ed2..c0218ec20 100755
--- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
+++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp
@@ -53,7 +53,7 @@ std::vector<std::string> FGPropertyManager::tied_properties;
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGPropertyManager::unbind(void)
+void FGPropertyManager::Unbind(void)
 {
     vector<string>::iterator it;
     for (it = tied_properties.begin();it < tied_properties.end();it++)
@@ -314,11 +314,12 @@ void FGPropertyManager::Untie (const string &name)
 
 void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 {
-  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
-  else if (debug_lvl & 0x20)
-    cout << name << endl;
+  else {
+    tied_properties.push_back(name);
+    if (debug_lvl & 0x20) std::cout << name << std::endl;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -326,11 +327,12 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault)
 void FGPropertyManager::Tie (const string &name, int *pointer,
                                           bool useDefault )
 {
-  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
-  else if (debug_lvl & 0x20)
-    cout << name << endl;
+  else {
+    tied_properties.push_back(name);
+    if (debug_lvl & 0x20) std::cout << name << std::endl;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -338,11 +340,12 @@ void FGPropertyManager::Tie (const string &name, int *pointer,
 void FGPropertyManager::Tie (const string &name, long *pointer,
                                           bool useDefault )
 {
-  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
-  else if (debug_lvl & 0x20)
-    cout << name << endl;
+  else {
+    tied_properties.push_back(name);
+    if (debug_lvl & 0x20) std::cout << name << std::endl;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -350,22 +353,24 @@ void FGPropertyManager::Tie (const string &name, long *pointer,
 void FGPropertyManager::Tie (const string &name, float *pointer,
                                           bool useDefault )
 {
-  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
-  else if (debug_lvl & 0x20)
-    cout << name << endl;
+  else {
+    tied_properties.push_back(name);
+    if (debug_lvl & 0x20) std::cout << name << std::endl;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault)
 {
-  tied_properties.push_back(name);
   if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault))
     cerr << "Failed to tie property " << name << " to a pointer" << endl;
-  else if (debug_lvl & 0x20)
-    cout << name << endl;
+  else {
+    tied_properties.push_back(name);
+    if (debug_lvl & 0x20) std::cout << name << std::endl;
+  }
 }
 
 } // namespace JSBSim
diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h
index 54ea91874..a08f89681 100644
--- a/src/FDM/JSBSim/input_output/FGPropertyManager.h
+++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h
@@ -406,7 +406,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
      * Classes should use this function to release control of any
      * properties they have bound using this property manager.
      */
-    void unbind (void);
+    void Unbind (void);
 
         // Templates cause ambiguity here
 
@@ -534,8 +534,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     {
       if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault))
         std::cout << "Failed to tie property " << name << " to functions" << std::endl;
-      else if (debug_lvl & 0x20)
-        std::cout << name << std::endl;
+      else {
+        tied_properties.push_back(name);
+        if (debug_lvl & 0x20) std::cout << name << std::endl;
+      }
     }
 
 
@@ -562,8 +564,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     {
       if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault))
         std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl;
-      else if (debug_lvl & 0x20)
-        std::cout << name << std::endl;
+      else {
+        tied_properties.push_back(name);
+        if (debug_lvl & 0x20) std::cout << name << std::endl;
+      }
     }
 
 
@@ -592,8 +596,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     {
       if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault))
         std::cout << "Failed to tie property " << name << " to object methods" << std::endl;
-      else if (debug_lvl & 0x20)
-        std::cout << name << std::endl;
+      else {
+        tied_properties.push_back(name);
+        if (debug_lvl & 0x20) std::cout << name << std::endl;
+      }
     }
 
     /**
@@ -621,8 +627,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase
     {
       if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault))
         std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl;
-      else if (debug_lvl & 0x20)
-        std::cout << name << std::endl;
+      else {
+        tied_properties.push_back(name);
+        if (debug_lvl & 0x20) std::cout << name << std::endl;
+      }
    }
 };
 }

From 591ef4ab0157f79d35486a5c7ac1e16147cda7af Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 6 Feb 2011 16:46:36 +0100
Subject: [PATCH 22/25] Fixed incomplete merge of JSBSim.cxx Commit
 287cc74965e11ff3888117a9d9b88ed2bdbb9252 wasn't merged to release/2.2.0
 properly by Commit b649f97b19b60ae273bf18e25b9539363b3d1c9a.

---
 src/FDM/JSBSim/JSBSim.cxx | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index 0f8d5130a..8b693bcab 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -144,8 +144,6 @@ FGJSBsim::FGJSBsim( double dt )
         }
     }
     
-    resetPropertyState();
-
     fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
 
     // Register ground callback.
@@ -1423,22 +1421,3 @@ void FGJSBsim::update_external_forces(double t_off)
     fgSetDouble("/fdm/jsbsim/systems/hook/tailhook-pos-deg", fi);
 }
 
-
-void FGJSBsim::resetPropertyState()
-{
-// this code works-around bug #222:
-// http://code.google.com/p/flightgear-bugs/issues/detail?id=222
-// for whatever reason, having an existing value for the WOW
-// property causes the NaNs. Should that be fixed, this code can die
-  SGPropertyNode* gear = fgGetNode("/fdm/jsbsim/gear", false);
-  if (!gear) {
-    return;
-  }
-  
-  int index = 0;
-  SGPropertyNode* unitNode = NULL;
-  for (; (unitNode = gear->getChild("unit", index)) != NULL; ++index) {
-    unitNode->removeChild("WOW", 0, false);
-  }
-}
-

From a4ebec667da0f849bcbf0be3fed1df3bca7d1db9 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Fri, 11 Feb 2011 18:53:35 +0100
Subject: [PATCH 23/25] Ivan Ngeow: Fixed compile for FreeBSD platforms.

---
 utils/TerraSync/terrasync.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx
index f1a2cc46b..d15078d9a 100644
--- a/utils/TerraSync/terrasync.cxx
+++ b/utils/TerraSync/terrasync.cxx
@@ -290,7 +290,7 @@ void sync_tree(const char* dir) {
 
 #if defined(_MSC_VER) || defined(__MINGW32__)
 typedef void (__cdecl * sighandler_t)(int);
-#elif defined( __APPLE__ )
+#elif defined( __APPLE__ ) || defined (__FreeBSD__)
 typedef sig_t sighandler_t;
 #endif
 

From 526cd9fa6e5b89522c528d4a7f5f7b2cafb9095e Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 13 Feb 2011 16:50:23 +0100
Subject: [PATCH 24/25] Avoid crash and/or long delay on shutdown in METAR
 loader. Catching loader thread on subsystem destruction is too late, since it
 depends on other subsystems (which are destroyed earlier). => Need to stop &
 join thread during subsystem shutdown. Also changed loader sleep logic - to
 avoid excessive delays (up to 30 seconds) on shutdown. (Issues mostly
 happened when running offline with realwx enabled.)

---
 src/Environment/realwx_ctrl.cxx | 48 ++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/Environment/realwx_ctrl.cxx b/src/Environment/realwx_ctrl.cxx
index a547ef7e5..71f52d7ba 100644
--- a/src/Environment/realwx_ctrl.cxx
+++ b/src/Environment/realwx_ctrl.cxx
@@ -191,6 +191,7 @@ public:
     NoaaMetarRealWxController( SGPropertyNode_ptr rootNode );
     virtual ~NoaaMetarRealWxController();
     virtual void update (bool first, double delta_time_sec);
+    virtual void shutdown ();
 
     class MetarLoadRequest {
     public:
@@ -234,14 +235,17 @@ private:
      class MetarLoadThread : public OpenThreads::Thread {
      public:
         MetarLoadThread( long maxAge );
+        virtual ~MetarLoadThread( ) { stop(); } 
         void requestMetar( const MetarLoadRequest & metarRequest, bool background = true );
         bool hasMetar() { return _responseQueue.size() > 0; }
         MetarLoadResponse getMetar() { return _responseQueue.pop(); }
         virtual void run();
+        void stop();
      private:
         void fetch( const MetarLoadRequest & );
         long _maxAge;
         long _minRequestInterval;
+        volatile bool _stop;
         SGBlockingQueue <MetarLoadRequest> _requestQueue;
         SGBlockingQueue <MetarLoadResponse> _responseQueue;
      };
@@ -261,18 +265,20 @@ NoaaMetarRealWxController::NoaaMetarRealWxController( SGPropertyNode_ptr rootNod
 #endif
 }
 
-NoaaMetarRealWxController::~NoaaMetarRealWxController()
+void NoaaMetarRealWxController::shutdown()
 {
 #if defined(ENABLE_THREADS)
     if( _metarLoadThread ) {
-        MetarLoadRequest request("");
-        _metarLoadThread->requestMetar(request);
-        _metarLoadThread->join();
         delete _metarLoadThread;
+        _metarLoadThread = NULL;
     }
 #endif // ENABLE_THREADS
 }
 
+NoaaMetarRealWxController::~NoaaMetarRealWxController()
+{
+}
+
 void NoaaMetarRealWxController::update( bool first, double dt )
 {
     _positionTimeToLive -= dt;
@@ -319,7 +325,7 @@ void NoaaMetarRealWxController::update( bool first, double dt )
                     "NoaaMetarRealWxController::update(): spawning load request for station-id '" << stationId << "'" );
             
                 MetarLoadRequest request( stationId );
-                // load the metar for the neares airport in the foreground if the fdm is uninitialized
+                // load the metar for the nearest airport in the foreground if the fdm is uninitialized
                 // to make sure a metar is received
                 // before the automatic runway selection code runs. All subsequent calls
                 // run in the background
@@ -348,7 +354,8 @@ void NoaaMetarRealWxController::update( bool first, double dt )
 #if defined(ENABLE_THREADS)
 NoaaMetarRealWxController::MetarLoadThread::MetarLoadThread( long maxAge ) :
   _maxAge(maxAge),
-  _minRequestInterval(2000)
+  _minRequestInterval(2000),
+  _stop(false)
 {
 }
 
@@ -368,24 +375,41 @@ void NoaaMetarRealWxController::MetarLoadThread::requestMetar( const MetarLoadRe
     }
 }
 
+void NoaaMetarRealWxController::MetarLoadThread::stop()
+{
+    // set stop flag and wake up the thread with an empty request
+    _stop = true;
+    MetarLoadRequest request("");
+    requestMetar(request);
+    join();
+}
+
 void NoaaMetarRealWxController::MetarLoadThread::run()
 {
     SGTimeStamp lastRun = SGTimeStamp::fromSec(0);
     for( ;; ) {
         SGTimeStamp dt = SGTimeStamp::now() - lastRun;
 
-        if( dt.getSeconds() * 1000 < _minRequestInterval )
-            microSleep( (_minRequestInterval - dt.getSeconds() * 1000 ) * 1000 );
-        
-        lastRun = SGTimeStamp::now();
+        long delayMs = _minRequestInterval - dt.getSeconds() * 1000;
+        while (( delayMs > 0 ) && !_stop)
+        {
+            // sleep no more than 3 seconds at a time, otherwise shutdown response is too slow
+            long sleepMs = (delayMs>3000) ? 3000 : delayMs; 
+            microSleep( sleepMs * 1000 );
+            delayMs -= sleepMs;
+        }
 
+        if (_stop)
+            break;
+
+        lastRun = SGTimeStamp::now();
+ 
         const MetarLoadRequest request = _requestQueue.pop();
 
-        if( request._stationId.size() == 0 )
+        if (( request._stationId.size() == 0 ) || _stop)
             break;
 
         fetch( request );
-
     }
 }
 

From c5366cceb6d345d3526ab013b04eb815fe0a6845 Mon Sep 17 00:00:00 2001
From: Tim Moore <timoore33@gmail.com>
Date: Tue, 15 Feb 2011 12:30:56 +0100
Subject: [PATCH 25/25] accomodate changes to osgDB::DatabasePager interface

The change was introduced in OSG SVN revision 12080. Note: that
revision has a bug that causes fgfs to crash. The bug is fixed in
revision 12170.
---
 src/Scenery/SceneryPager.cxx | 39 ++++++++++++++++++++++++++++++------
 src/Scenery/SceneryPager.hxx | 19 +++++-------------
 2 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/src/Scenery/SceneryPager.cxx b/src/Scenery/SceneryPager.cxx
index 183511361..9328973ef 100644
--- a/src/Scenery/SceneryPager.cxx
+++ b/src/Scenery/SceneryPager.cxx
@@ -44,15 +44,12 @@ SceneryPager::~SceneryPager()
 {
 }
 
+#if SG_PAGEDLOD_HAS_OPTIONS
+#else
 void SceneryPager::requestNodeFile(const std::string& fileName, Group* group,
                                    float priority, const FrameStamp* framestamp,
                                    ref_ptr<Referenced>& databaseRequest,
-#if SG_OSG_MIN_VERSION_REQUIRED(2,9,5)
-                                   const osg::Referenced* options
-#else
-                                   osgDB::ReaderWriter::Options* options
-#endif
-                                   )
+                                   osgDB::ReaderWriter::Options* options)
 {
     simgear::SGPagedLOD *sgplod = dynamic_cast<simgear::SGPagedLOD*>(group);
     if(sgplod)
@@ -64,6 +61,7 @@ void SceneryPager::requestNodeFile(const std::string& fileName, Group* group,
                                        databaseRequest,
                                        options);
 }
+#endif
 
 void SceneryPager::queueRequest(const std::string& fileName, Group* group,
                                 float priority, FrameStamp* frameStamp,
@@ -81,6 +79,35 @@ void SceneryPager::queueDeleteRequest(osg::ref_ptr<osg::Object>& objptr)
     _deleteRequests.push_back(objptr);
     objptr = 0;
 }
+
+// Work around interface change in
+// osgDB::DatabasePager::requestNodeFile
+namespace
+{
+struct NodePathProxy
+{
+    NodePathProxy(NodePath& nodePath)
+        : _nodePath(nodePath)
+    {
+    }
+    operator Group* () { return static_cast<Group*>(_nodePath.back()); }
+    operator NodePath& () { return _nodePath; }
+    NodePath& _nodePath;
+};
+}
+
+void SceneryPager::PagerRequest::doRequest(SceneryPager* pager)
+{
+    if (_group->getNumChildren() == 0) {
+        NodePath path;
+        path.push_back(_group.get());
+        pager->requestNodeFile(_fileName, NodePathProxy(path), _priority,
+                               _frameStamp.get(),
+                               *_databaseRequest,
+                               _options.get());
+    }
+}
+
 void SceneryPager::signalEndFrame()
 {
     using namespace std;
diff --git a/src/Scenery/SceneryPager.hxx b/src/Scenery/SceneryPager.hxx
index ba018993c..04e6ef5c4 100644
--- a/src/Scenery/SceneryPager.hxx
+++ b/src/Scenery/SceneryPager.hxx
@@ -28,6 +28,7 @@
 #include <osgDB/DatabasePager>
 
 #include <simgear/structure/OSGVersion.hxx>
+#include <simgear/scene/model/SGPagedLOD.hxx>
 
 namespace flightgear
 {
@@ -39,16 +40,14 @@ public:
     // Unhide DatabasePager::requestNodeFile
     using osgDB::DatabasePager::requestNodeFile;
     // reimplement to add readerWriterOptions from SGPagedLOD
+#if SG_PAGEDLOD_HAS_OPTIONS
+#else
     virtual void requestNodeFile(const std::string& fileName, osg::Group* group,
                                  float priority,
                                  const osg::FrameStamp* framestamp,
                                  osg::ref_ptr<osg::Referenced>& databaseRequest,
-#if SG_OSG_MIN_VERSION_REQUIRED(2,9,5)
-                                 const osg::Referenced* options
-#else
-                                 osgDB::ReaderWriter::Options* options
+                                 osgDB::ReaderWriter::Options* options);
 #endif
-                                 );
     void queueRequest(const std::string& fileName, osg::Group* node,
                       float priority, osg::FrameStamp* frameStamp,
                       osg::ref_ptr<osg::Referenced>& databaseRequest,
@@ -77,15 +76,7 @@ protected:
             _databaseRequest(&databaseRequest)
         {}
 
-        void doRequest(SceneryPager* pager)
-        {
-            if (_group->getNumChildren() == 0)
-                pager->requestNodeFile(_fileName, _group.get(), _priority,
-                                       _frameStamp.get(),
-                                       *_databaseRequest,
-                                       _options.get());
-        }
-
+        void doRequest(SceneryPager* pager);
         std::string _fileName;
         osg::ref_ptr<osg::Group> _group;
         float _priority;