From be1117f7828f5a8b3a61eb85ac3554dfcf299f59 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 28 May 2011 11:16:03 +0200
Subject: [PATCH 1/9] fixed #308: "Reload input" did not respect joysticks.xml
 Predefined joystick information must be maintained on "reload input".

---
 src/Input/FGJoystickInput.cxx | 17 +++++++++++------
 src/Input/FGJoystickInput.hxx |  5 +++--
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/src/Input/FGJoystickInput.cxx b/src/Input/FGJoystickInput.cxx
index afc7ad8fd..506de36bb 100644
--- a/src/Input/FGJoystickInput.cxx
+++ b/src/Input/FGJoystickInput.cxx
@@ -49,7 +49,8 @@ FGJoystickInput::joystick::joystick ()
     naxes(0),
     nbuttons(0),
     axes(0),
-    buttons(0)
+    buttons(0),
+    predefined(true)
 {
 }
 
@@ -73,15 +74,18 @@ FGJoystickInput::FGJoystickInput()
 
 FGJoystickInput::~FGJoystickInput()
 {
-    _remove();
+    _remove(true);
 }
 
-void FGJoystickInput::_remove()
+void FGJoystickInput::_remove(bool all)
 {
     SGPropertyNode * js_nodes = fgGetNode("/input/joysticks", true);
-    js_nodes->removeChildren("js", false);
+
     for (int i = 0; i < MAX_JOYSTICKS; i++)
     {
+        // do not remove predefined joysticks info on reinit
+        if ((all)||(!bindings[i].predefined))
+            js_nodes->removeChild("js", i, false);
         if (bindings[i].js)
             delete bindings[i].js;
         bindings[i].js = NULL;
@@ -92,7 +96,7 @@ void FGJoystickInput::init()
 {
   jsInit();
   SG_LOG(SG_INPUT, SG_DEBUG, "Initializing joystick bindings");
-  SGPropertyNode * js_nodes = fgGetNode("/input/joysticks", true);
+  SGPropertyNode_ptr js_nodes = fgGetNode("/input/joysticks", true);
 
   FGDeviceConfigurationMap configMap("Input/Joysticks", js_nodes, "js-named");
 
@@ -112,6 +116,7 @@ void FGJoystickInput::init()
       SG_LOG(SG_INPUT, SG_INFO, "Using existing bindings for joystick " << i);
 
     } else {
+      bindings[i].predefined = false;
       SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
       SGPropertyNode_ptr named;
 
@@ -137,7 +142,7 @@ void FGJoystickInput::init()
 
 void FGJoystickInput::reinit() {
   SG_LOG(SG_INPUT, SG_DEBUG, "Re-Initializing joystick bindings");
-  _remove();
+  _remove(false);
   FGJoystickInput::init();
   FGJoystickInput::postinit();
 }
diff --git a/src/Input/FGJoystickInput.hxx b/src/Input/FGJoystickInput.hxx
index 392fc54b3..45de33f94 100644
--- a/src/Input/FGJoystickInput.hxx
+++ b/src/Input/FGJoystickInput.hxx
@@ -25,7 +25,7 @@
 #ifndef _FGJOYSTICKINPUT_HXX
 #define _FGJOYSTICKINPUT_HXX
 
-#ifndef __cplusplus                                                          
+#ifndef __cplusplus
 # error This library requires C++
 #endif
 
@@ -52,7 +52,7 @@ public:
   static const int MAX_JOYSTICK_BUTTONS = 32;
 
 private:
-   void _remove();
+   void _remove(bool all);
 
   /**
    * Settings for a single joystick axis.
@@ -83,6 +83,7 @@ private:
     int nbuttons;
     axis * axes;
     FGButton * buttons;
+    bool predefined;
   };
   joystick bindings[MAX_JOYSTICKS];
 

From 051fba87d369f1d7dcba1f698f8f310ef27bfc4f Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sat, 28 May 2011 18:24:58 +0200
Subject: [PATCH 2/9] "Straighten" VC90 fgpanel project and add it to the
 solution

---
 projects/VC90/FlightGear.sln         | 11 +++++++++++
 projects/VC90/fgpanel/fgpanel.vcproj | 15 +++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/projects/VC90/FlightGear.sln b/projects/VC90/FlightGear.sln
index bb1d39b4b..90ea51407 100644
--- a/projects/VC90/FlightGear.sln
+++ b/projects/VC90/FlightGear.sln
@@ -54,6 +54,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yasim", "yasim\yasim.vcproj
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "..\..\..\Simgear\projects\VC90\SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fgpanel", "fgpanel\fgpanel.vcproj", "{FA27B353-179C-4DE8-B3AC-E260F8F790DD}"
+	ProjectSection(ProjectDependencies) = postProject
+		{22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -156,6 +161,12 @@ Global
 		{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|Win32.Build.0 = Release|Win32
 		{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.ActiveCfg = Release|x64
 		{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release|x64.Build.0 = Release|x64
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|Win32.Build.0 = Debug|Win32
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Debug|x64.ActiveCfg = Debug|Win32
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|Win32.ActiveCfg = Release|Win32
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|Win32.Build.0 = Release|Win32
+		{FA27B353-179C-4DE8-B3AC-E260F8F790DD}.Release|x64.ActiveCfg = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/projects/VC90/fgpanel/fgpanel.vcproj b/projects/VC90/fgpanel/fgpanel.vcproj
index 47b67eb33..bc09aff71 100755
--- a/projects/VC90/fgpanel/fgpanel.vcproj
+++ b/projects/VC90/fgpanel/fgpanel.vcproj
@@ -18,10 +18,10 @@
 	<Configurations>
 		<Configuration
 			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
 			ConfigurationType="1"
-			CharacterSet="1"
+			CharacterSet="2"
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
@@ -41,7 +41,8 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				AdditionalIncludeDirectories="..\..\..\..\SimGear;..\..\..\..\boost_1_44_0;..\..\..\..\install\msvc90\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\src\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;NOMINMAX;HAVE_CONFIG_H"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="3"
@@ -60,7 +61,9 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib zlibd.lib libpngd.lib fnt_d.lib ul_d.lib sg_d.lib pui_d.lib"
 				LinkIncremental="2"
+				AdditionalLibraryDirectories="..\..\..\..\install\msvc90\OpenSceneGraph\lib;..\..\..\..\3rdParty\lib"
 				GenerateDebugInformation="true"
 				SubSystem="1"
 				TargetMachine="1"
@@ -89,8 +92,8 @@
 		</Configuration>
 		<Configuration
 			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
 			ConfigurationType="1"
 			CharacterSet="2"
 			WholeProgramOptimization="1"

From a32ef9f39169c873d24c5385dcb948c89ab19002 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 28 May 2011 21:20:06 +0100
Subject: [PATCH 3/9] Fix yet another subtle resize problem I introduced, which
 upset PUI. This code is terribly fragile - yuck. Thanks to papillion 81 for
 tracking down the issue,

---
 src/Main/renderer.cxx | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx
index 4edaf2406..4902abea0 100644
--- a/src/Main/renderer.cxx
+++ b/src/Main/renderer.cxx
@@ -784,9 +784,14 @@ FGRenderer::resize( int width, int height ) {
 
     int curWidth = _xsize->getIntValue(),
         curHeight = _ysize->getIntValue();
-
-    _xsize->setIntValue(width);
-    _ysize->setIntValue(height);
+    if ((curHeight != height) || (curWidth != width)) {
+    // must guard setting these, or PLIB-PUI fails with too many live interfaces
+        _xsize->setIntValue(width);
+        _ysize->setIntValue(height);
+    }
+    
+    // must set view aspect ratio each frame, or initial values are wrong.
+    // should probably be fixed 'smarter' during view setup.
     double aspect = height / (double) width;
 
     // for all views

From b4d90150c50094ac25f2e9ed7ea8302a3ef148d2 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sat, 28 May 2011 23:27:46 +0200
Subject: [PATCH 4/9] issue #127: make screen shots work with OSG
 multi-threading Make sure actual snap shot is executed in graphics context.
 (patch requires simgear+fgdata update!)

---
 src/GUI/gui_funcs.cxx | 136 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 133 insertions(+), 3 deletions(-)

diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx
index ccbd0a550..06459a8f6 100644
--- a/src/GUI/gui_funcs.cxx
+++ b/src/GUI/gui_funcs.cxx
@@ -42,6 +42,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/screen/screen-dump.hxx>
+#include <simgear/structure/event_mgr.hxx>
 
 #include <Cockpit/panel.hxx>
 #include <Main/globals.hxx>
@@ -49,8 +50,11 @@
 #include <Main/fg_os.hxx>
 #include <Main/renderer.hxx>
 #include <Main/viewmgr.hxx>
+#include <Main/WindowSystemAdapter.hxx>
+#include <Main/CameraGroup.hxx>
 #include <GUI/new_gui.hxx>
 
+
 #ifdef _WIN32
 #  include <shellapi.h>
 #endif
@@ -406,9 +410,134 @@ void fgHiResDumpWrapper () {
     fgHiResDump();
 }
 
+namespace
+{
+    using namespace flightgear;
+
+    class GUISnapShotOperation : 
+        public GraphicsContextOperation
+    {
+    public:
+
+        // start new snap shot
+        static bool start()
+        {
+            // allow only one snapshot at a time
+            if (_snapShotOp.valid())
+                return false;
+            _snapShotOp = new GUISnapShotOperation();
+            /* register with graphics context so actual snap shot is done
+             * in the graphics context (thread) */
+            osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
+            WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
+            osg::GraphicsContext* gc = 0;
+            if (guiCamera)
+                gc = guiCamera->getGraphicsContext();
+            if (gc) {
+                gc->add(_snapShotOp.get());
+            } else {
+                wsa->windows[0]->gc->add(_snapShotOp.get());
+            }
+            return true;
+        }
+
+    private:
+        // constructor to be executed in main loop's thread
+        GUISnapShotOperation() :
+            flightgear::GraphicsContextOperation(std::string("GUI snap shot")),
+            _master_freeze(fgGetNode("/sim/freeze/master", true)),
+            _freeze(_master_freeze->getBoolValue()),
+            _result(false),
+            _mouse(fgGetMouseCursor())
+        {
+            if (!_freeze)
+                _master_freeze->setBoolValue(true);
+
+            fgSetMouseCursor(MOUSE_CURSOR_NONE);
+
+            string dir = fgGetString("/sim/paths/screenshot-dir");
+            if (dir.empty())
+                dir = fgGetString("/sim/fg-current");
+
+            _path.set(dir + '/');
+            if (_path.create_dir( 0755 )) {
+                SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '"
+                        << dir << "'. Trying home directory.");
+                dir = fgGetString("/sim/fg-home");
+            }
+
+            char filename[24];
+            static int count = 1;
+            while (count < 1000) {
+                snprintf(filename, 24, "fgfs-screen-%03d.png", count++);
+
+                SGPath p(dir);
+                p.append(filename);
+                if (!p.exists()) {
+                    _path.set(p.str());
+                    break;
+                }
+            }
+
+            _xsize = fgGetInt("/sim/startup/xsize");
+            _ysize = fgGetInt("/sim/startup/ysize");
+
+            FGRenderer *renderer = globals->get_renderer();
+            renderer->resize(_xsize, _ysize);
+            globals->get_event_mgr()->addTask("SnapShotTimer",
+                    this, &GUISnapShotOperation::timerExpired,
+                    0.1, false);
+        }
+
+        // to be executed in graphics context (maybe separate thread)
+        void run(osg::GraphicsContext* gc)
+        {
+            _result = sg_glDumpWindow(_path.c_str(),
+                                     _xsize,
+                                     _ysize);
+        }
+
+        // timer method, to be executed in main loop's thread
+        virtual void timerExpired()
+        {
+            if (isFinished())
+            {
+                globals->get_event_mgr()->removeTask("SnapShotTimer");
+
+                fgSetString("/sim/paths/screenshot-last", _path.c_str());
+                fgSetBool("/sim/signals/screenshot", _result);
+
+                fgSetMouseCursor(_mouse);
+
+                if ( !_freeze )
+                    _master_freeze->setBoolValue(false);
+
+                _snapShotOp = 0;
+            }
+        }
+    
+        static osg::ref_ptr<GUISnapShotOperation> _snapShotOp;
+        SGPropertyNode_ptr _master_freeze;
+        bool _freeze;
+        bool _result;
+        int _mouse;
+        int _xsize, _ysize;
+        SGPath _path;
+    };
+
+}
+
+osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp;
 
 // do a screen snap shot
-bool fgDumpSnapShot () {
+bool fgDumpSnapShot ()
+{
+#if 1
+    // start snap shot operation, while needs to be executed in
+    // graphics context
+    return GUISnapShotOperation::start();
+#else
+    // obsolete code => remove when new code is stable
     static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master");
 
     bool freeze = master_freeze->getBoolValue();
@@ -455,7 +584,7 @@ bool fgDumpSnapShot () {
         }
     }
 
-    int result = sg_glDumpWindow(path.c_str(),
+    bool result = sg_glDumpWindow(path.c_str(),
                                  fgGetInt("/sim/startup/xsize"),
                                  fgGetInt("/sim/startup/ysize"));
 
@@ -467,7 +596,8 @@ bool fgDumpSnapShot () {
     if ( !freeze ) {
         fgSetBool("/sim/freeze/master", false);
     }
-    return result != 0;
+    return result;
+#endif
 }
 
 // do an entire scenegraph dump

From 0d0b5c616c26012100aa6e6493447d086645b918 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 29 May 2011 00:05:33 +0200
Subject: [PATCH 5/9] Bertrand Coconnier: bug fix for #184, JSBSim: command
 line arguments 1. The atmospheric properties of FG are not yet initialized
 when JSBSim is initialized. -> patch is quite basic and there may exist
 smarter ways to initialize properly the environment before the FDM. 2. The
 Euler angles were initialized after the velocities. 3. The glide slope and
 rate of climb were ignored. Fixes all FDMs (YASim, UIUC, JSBSim, etc.) 4.
 Some properties were instructed to re-use their previous value while they
 should not. 5. Some bugs existed in JSBSim trim code. -> This bug has already
 been fixed in JSBSim but the corresponding patch has not yet been applied to
 FG.

---
 src/Environment/environment_mgr.cxx           |  7 ++
 src/FDM/JSBSim/JSBSim.cxx                     | 30 ++++----
 .../initialization/FGInitialCondition.cpp     | 35 +++++----
 .../initialization/FGInitialCondition.h       |  5 +-
 src/FDM/flight.cxx                            | 76 +++++++++++--------
 5 files changed, 89 insertions(+), 64 deletions(-)

diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx
index e48039029..42023ea84 100644
--- a/src/Environment/environment_mgr.cxx
+++ b/src/Environment/environment_mgr.cxx
@@ -97,6 +97,13 @@ FGEnvironmentMgr::init ()
   SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem");
   SGSubsystemGroup::init();
   fgClouds->Init();
+
+  // Initialize the longitude, latitude and altitude to the initial position
+  // of the aircraft so that the atmospheric properties (pressure, temperature
+  // and density) can be initialized accordingly.
+  _altitudeNode->setDoubleValue(fgGetDouble("/sim/presets/altitude-ft"));
+  _longitude_n->setDoubleValue(fgGetDouble("/sim/presets/longitude-deg"));
+  _latitude_n->setDoubleValue(fgGetDouble("/sim/presets/latitude-deg"));
 }
 
 void
diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx
index 806401cf9..54ed59872 100644
--- a/src/FDM/JSBSim/JSBSim.cxx
+++ b/src/FDM/JSBSim/JSBSim.cxx
@@ -181,7 +181,7 @@ FGJSBsim::FGJSBsim( double dt )
     MassBalance     = fdmex->GetMassBalance();
     Propulsion      = fdmex->GetPropulsion();
     Aircraft        = fdmex->GetAircraft();
-    Propagate        = fdmex->GetPropagate();
+    Propagate       = fdmex->GetPropagate();
     Auxiliary       = fdmex->GetAuxiliary();
     Inertial        = fdmex->GetInertial();
     Aerodynamics    = fdmex->GetAerodynamics();
@@ -369,9 +369,9 @@ void FGJSBsim::init()
       Atmosphere->UseInternal();
     }
 
-    fgic->SetVNorthFpsIC( -wind_from_north->getDoubleValue() );
-    fgic->SetVEastFpsIC( -wind_from_east->getDoubleValue() );
-    fgic->SetVDownFpsIC( -wind_from_down->getDoubleValue() );
+    fgic->SetWindNEDFpsIC( -wind_from_north->getDoubleValue(),
+                           -wind_from_east->getDoubleValue(),
+                           -wind_from_down->getDoubleValue() );
 
     //Atmosphere->SetExTemperature(get_Static_temperature());
     //Atmosphere->SetExPressure(get_Static_pressure());
@@ -393,20 +393,20 @@ void FGJSBsim::init()
     }
 // end of egt_degf deprecation patch
 
-    if (fgGetBool("/sim/presets/running")) {
-          for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++) {
-            SGPropertyNode * node = fgGetNode("engines/engine", i, true);
-            node->setBoolValue("running", true);
-            Propulsion->GetEngine(i)->SetRunning(true);
-          }
-    }
-
     FCS->SetDfPos( ofNorm, globals->get_controls()->get_flaps() );
 
     common_init();
 
     copy_to_JSBsim();
     fdmex->RunIC();     //loop JSBSim once w/o integrating
+    if (fgGetBool("/sim/presets/running")) {
+      Propulsion->InitRunning(-1);
+      for (unsigned int i = 0; i < Propulsion->GetNumEngines(); i++) {
+        FGPiston* eng = (FGPiston*)Propulsion->GetEngine(i);
+        globals->get_controls()->set_magnetos(i, eng->GetMagnetos());
+        globals->get_controls()->set_mixture(i, FCS->GetMixtureCmd(i));
+      }
+    }
     copy_from_JSBsim(); //update the bus
 
     SG_LOG( SG_FLIGHT, SG_INFO, "  Initialized JSBSim with:" );
@@ -1282,7 +1282,7 @@ void FGJSBsim::do_trim(void)
   {
     fgtrim = new FGTrim(fdmex,tGround);
   } else {
-    fgtrim = new FGTrim(fdmex,tLongitudinal);
+    fgtrim = new FGTrim(fdmex,tFull);
   }
 
   if ( !fgtrim->DoTrim() ) {
@@ -1296,7 +1296,7 @@ void FGJSBsim::do_trim(void)
   pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
   throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
   aileron_trim->setDoubleValue( FCS->GetDaCmd() );
-  rudder_trim->setDoubleValue( FCS->GetDrCmd() );
+  rudder_trim->setDoubleValue( -FCS->GetDrCmd() );
 
   globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
   globals->get_controls()->set_elevator(FCS->GetDeCmd());
@@ -1304,7 +1304,7 @@ void FGJSBsim::do_trim(void)
     globals->get_controls()->set_throttle(i, FCS->GetThrottleCmd(i));
 
   globals->get_controls()->set_aileron(FCS->GetDaCmd());
-  globals->get_controls()->set_rudder( FCS->GetDrCmd());
+  globals->get_controls()->set_rudder( -FCS->GetDrCmd());
 
   SG_LOG( SG_FLIGHT, SG_INFO, "  Trim complete" );
 }
diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
index 0dbcf88ce..00a3840f1 100644
--- a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
+++ b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp
@@ -61,7 +61,7 @@ using namespace std;
 
 namespace JSBSim {
 
-static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.59 2011/04/03 13:18:51 bcoconni Exp $";
+static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.61 2011/05/20 00:47:03 bcoconni Exp $";
 static const char *IdHdr = ID_INITIALCONDITION;
 
 //******************************************************************************
@@ -112,7 +112,7 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
   FGQuaternion Quat(phi, theta, psi);
   Quat.Normalize();
   Tl2b = Quat.GetT();
-  Tb2l = Quat.GetTInv();
+  Tb2l = Tl2b.Transposed();
 
   vUVW_NED = Tb2l * FGColumnVector3(u0, v0, w0);
   vt = vUVW_NED.Magnitude();
@@ -322,20 +322,18 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot)
 
   FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
   FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED;
-  double hdot0 = _vt_NED(eW);
+  double hdot0 = -_vt_NED(eW);
 
   if (fabs(hdot0) < vt) {
     double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0));
     _vt_NED(eU) *= scale;
     _vt_NED(eV) *= scale;
   }
-  _vt_NED(eW) = hdot;
+  _vt_NED(eW) = -hdot;
   vUVW_NED = _vt_NED - _WIND_NED;
 
-  // The AoA is not modified here but the function SetAlphaRadIC is updating the
-  // same angles than SetClimbRateFpsIC needs to update.
-  // TODO : create a subroutine that only shares the relevant code.
-  SetAlphaRadIC(alpha);
+  // Updating the angles theta and beta to keep the true airspeed amplitude
+  calcThetaBeta(alpha, _vt_NED);
 }
 
 //******************************************************************************
@@ -346,13 +344,22 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot)
 void FGInitialCondition::SetAlphaRadIC(double alfa)
 {
   FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
+  calcThetaBeta(alfa, _vt_NED);
+}
 
+//******************************************************************************
+// When the AoA is modified, we need to update the angles theta and beta to
+// keep the true airspeed amplitude, the climb rate and the heading unchanged.
+// Beta will be modified if the aircraft roll angle is not null.
+
+void FGInitialCondition::calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED)
+{
   double calpha = cos(alfa), salpha = sin(alfa);
   double cpsi = cos(psi), spsi = sin(psi);
   double cphi = cos(phi), sphi = sin(phi);
   FGMatrix33 Tpsi( cpsi, spsi, 0.,
-                    -spsi, cpsi, 0.,
-                       0.,   0., 1.);
+                  -spsi, cpsi, 0.,
+                     0.,   0., 1.);
   FGMatrix33 Tphi(1.,   0.,   0.,
                   0., cphi, sphi,
                   0.,-sphi, cphi);
@@ -398,11 +405,11 @@ void FGInitialCondition::SetAlphaRadIC(double alfa)
   Tl2b = Quat.GetT();
   Tb2l = Quat.GetTInv();
 
-  FGColumnVector3 v2 = Talpha * Quat.GetT() * _vt_NED;
+  FGColumnVector3 v2 = Talpha * Tl2b * _vt_NED;
 
   alpha = alfa;
   beta = atan2(v2(eV), v2(eU));
-  double cbeta=0.0, sbeta=0.0;
+  double cbeta=1.0, sbeta=0.0;
   if (vt != 0.0) {
     cbeta = v2(eU) / vt;
     sbeta = v2(eV) / vt;
@@ -687,6 +694,8 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
   double ve0 = vt * sqrt(rho/rhoSL);
 
   altitudeASL=alt;
+  position.SetRadius(alt + sea_level_radius);
+
   temperature = fdmex->GetAtmosphere()->GetTemperature(altitudeASL);
   soundSpeed = sqrt(SHRatio*Reng*temperature);
   rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL);
@@ -703,8 +712,6 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt)
     default: // Make the compiler stop complaining about missing enums
       break;
   }
-
-  position.SetRadius(alt + sea_level_radius);
 }
 
 //******************************************************************************
diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.h b/src/FDM/JSBSim/initialization/FGInitialCondition.h
index 308122450..e110ebbb3 100644
--- a/src/FDM/JSBSim/initialization/FGInitialCondition.h
+++ b/src/FDM/JSBSim/initialization/FGInitialCondition.h
@@ -54,7 +54,7 @@ INCLUDES
 DEFINITIONS
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
+#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 FORWARD DECLARATIONS
@@ -213,7 +213,7 @@ CLASS DOCUMENTATION
    @property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
 
    @author Tony Peden
-   @version "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
+   @version "$Id: FGInitialCondition.h,v 1.27 2011/05/20 00:47:03 bcoconni Exp $"
 */
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -666,6 +666,7 @@ private:
   double getMachFromVcas(double vcas);
   double calcVcas(double Mach) const;
   void calcAeroAngles(const FGColumnVector3& _vt_BODY);
+  void calcThetaBeta(double alfa, const FGColumnVector3& _vt_NED);
   void bind(void);
   void Debug(int from);
 
diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx
index d501d1507..431605a9f 100644
--- a/src/FDM/flight.cxx
+++ b/src/FDM/flight.cxx
@@ -179,6 +179,15 @@ FGInterface::common_init ()
     double slr = SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v);
     _set_Sea_level_radius( slr * SG_METER_TO_FEET );
 
+    // Set initial Euler angles
+    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
+    set_Euler_Angles( fgGetDouble("/sim/presets/roll-deg")
+                        * SGD_DEGREES_TO_RADIANS,
+                      fgGetDouble("/sim/presets/pitch-deg")
+                        * SGD_DEGREES_TO_RADIANS,
+                      fgGetDouble("/sim/presets/heading-deg")
+                        * SGD_DEGREES_TO_RADIANS );
+
     // Set initial velocities
     SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
     if ( !fgHasNode("/sim/presets/speed-set") ) {
@@ -207,14 +216,11 @@ FGInterface::common_init ()
         }
     }
 
-    // Set initial Euler angles
-    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
-    set_Euler_Angles( fgGetDouble("/sim/presets/roll-deg")
-                        * SGD_DEGREES_TO_RADIANS,
-                      fgGetDouble("/sim/presets/pitch-deg")
-                        * SGD_DEGREES_TO_RADIANS,
-                      fgGetDouble("/sim/presets/heading-deg")
-                        * SGD_DEGREES_TO_RADIANS );
+    if ( fgHasNode("/sim/presets/glideslope-deg") )
+        set_Gamma_vert_rad( fgGetDouble("/sim/presets/glideslope-deg")
+                              * SGD_DEGREES_TO_RADIANS );
+    else if ( fgHasNode( "/velocities/vertical-speed-fps") )
+        set_Climb_Rate( fgGetDouble("/velocities/vertical-speed-fps") );
 
     SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
 }
@@ -251,7 +257,7 @@ FGInterface::bind ()
         false);
   fgSetArchivable("/position/altitude-ft");
   fgTie("/position/altitude-agl-ft", this,
-        &FGInterface::get_Altitude_AGL, &FGInterface::set_AltitudeAGL);
+        &FGInterface::get_Altitude_AGL, &FGInterface::set_AltitudeAGL, false);
   fgSetArchivable("/position/ground-elev-ft");
   fgTie("/position/ground-elev-ft", this,
         &FGInterface::get_Runway_altitude); // read-only
@@ -263,7 +269,7 @@ FGInterface::bind ()
   fgSetArchivable("/position/sea-level-radius-ft");
   fgTie("/position/sea-level-radius-ft", this,
         &FGInterface::get_Sea_level_radius,
-        &FGInterface::_set_Sea_level_radius);
+        &FGInterface::_set_Sea_level_radius, false);
 
 				// Orientation
   fgTie("/orientation/roll-deg", this,
@@ -279,24 +285,27 @@ FGInterface::bind ()
 	&FGInterface::set_Psi_deg, false);
   fgSetArchivable("/orientation/heading-deg");
   fgTie("/orientation/track-deg", this,
-	&FGInterface::get_Track);
+	&FGInterface::get_Track); // read-only
 
   // Body-axis "euler rates" (rotation speed, but in a funny
   // representation).
   fgTie("/orientation/roll-rate-degps", this,
-	&FGInterface::get_Phi_dot_degps, &FGInterface::set_Phi_dot_degps);
+	&FGInterface::get_Phi_dot_degps,
+	&FGInterface::set_Phi_dot_degps, false);
   fgTie("/orientation/pitch-rate-degps", this,
-	&FGInterface::get_Theta_dot_degps, &FGInterface::set_Theta_dot_degps);
+	&FGInterface::get_Theta_dot_degps,
+	&FGInterface::set_Theta_dot_degps, false);
   fgTie("/orientation/yaw-rate-degps", this,
-	&FGInterface::get_Psi_dot_degps, &FGInterface::set_Psi_dot_degps);
+	&FGInterface::get_Psi_dot_degps,
+	&FGInterface::set_Psi_dot_degps, false);
 
-  fgTie("/orientation/p-body", this, &FGInterface::get_P_body);
-  fgTie("/orientation/q-body", this, &FGInterface::get_Q_body);
-  fgTie("/orientation/r-body", this, &FGInterface::get_R_body);
+  fgTie("/orientation/p-body", this, &FGInterface::get_P_body); // read-only
+  fgTie("/orientation/q-body", this, &FGInterface::get_Q_body); // read-only
+  fgTie("/orientation/r-body", this, &FGInterface::get_R_body); // read-only
   
                                 // Ground speed knots
   fgTie("/velocities/groundspeed-kt", this,
-        &FGInterface::get_V_ground_speed_kt);
+        &FGInterface::get_V_ground_speed_kt); // read-only
 
 				// Calibrated airspeed
   fgTie("/velocities/airspeed-kt", this,
@@ -305,7 +314,7 @@ FGInterface::bind ()
 	false);
 
     fgTie("/velocities/equivalent-kt", this,
-        &FGInterface::get_V_equiv_kts);
+        &FGInterface::get_V_equiv_kts); // read-only
 
 				// Mach number
   fgTie("/velocities/mach", this,
@@ -338,11 +347,11 @@ FGInterface::bind ()
 	&FGInterface::get_V_down, &FGInterface::set_V_down, false);
 
   fgTie("/velocities/north-relground-fps", this,
-    &FGInterface::get_V_north_rel_ground);
+    &FGInterface::get_V_north_rel_ground); // read-only
   fgTie("/velocities/east-relground-fps", this,
-    &FGInterface::get_V_east_rel_ground);
+    &FGInterface::get_V_east_rel_ground); // read-only
   fgTie("/velocities/down-relground-fps", this,
-    &FGInterface::get_V_down_rel_ground);
+    &FGInterface::get_V_down_rel_ground); // read-only
 
 
 				// Relative wind
@@ -367,36 +376,37 @@ FGInterface::bind ()
 				// Climb and slip (read-only)
   fgTie("/velocities/vertical-speed-fps", this,
 	&FGInterface::get_Climb_Rate,
-  &FGInterface::set_Climb_Rate ); 
+        &FGInterface::set_Climb_Rate, false );
   fgTie("/velocities/glideslope", this,
   &FGInterface::get_Gamma_vert_rad,
-  &FGInterface::set_Gamma_vert_rad );
+  &FGInterface::set_Gamma_vert_rad, false );
   fgTie("/orientation/side-slip-rad", this,
-	&FGInterface::get_Beta, &FGInterface::_set_Beta);
+	&FGInterface::get_Beta, &FGInterface::_set_Beta, false);
   fgTie("/orientation/side-slip-deg", this,
   &FGInterface::get_Beta_deg); // read-only
   fgTie("/orientation/alpha-deg", this,
-  &FGInterface::get_Alpha_deg, &FGInterface::set_Alpha_deg); // read-only
+  &FGInterface::get_Alpha_deg, &FGInterface::set_Alpha_deg, false);
   fgTie("/accelerations/nlf", this,
   &FGInterface::get_Nlf); // read-only
 
                                 // NED accelerations
   fgTie("/accelerations/ned/north-accel-fps_sec",
-        this, &FGInterface::get_V_dot_north);
+        this, &FGInterface::get_V_dot_north); // read-only
   fgTie("/accelerations/ned/east-accel-fps_sec",
-        this, &FGInterface::get_V_dot_east);
+        this, &FGInterface::get_V_dot_east); // read-only
   fgTie("/accelerations/ned/down-accel-fps_sec",
-        this, &FGInterface::get_V_dot_down);
+        this, &FGInterface::get_V_dot_down); // read-only
 
                                 // Pilot accelerations
   fgTie("/accelerations/pilot/x-accel-fps_sec",
-        this, &FGInterface::get_A_X_pilot, &FGInterface::set_A_X_pilot);
+        this, &FGInterface::get_A_X_pilot, &FGInterface::set_A_X_pilot, false);
   fgTie("/accelerations/pilot/y-accel-fps_sec",
-        this, &FGInterface::get_A_Y_pilot, &FGInterface::set_A_Y_pilot);
+        this, &FGInterface::get_A_Y_pilot, &FGInterface::set_A_Y_pilot, false);
   fgTie("/accelerations/pilot/z-accel-fps_sec",
-        this, &FGInterface::get_A_Z_pilot, &FGInterface::set_A_Z_pilot);
+        this, &FGInterface::get_A_Z_pilot, &FGInterface::set_A_Z_pilot, false);
         
-  fgTie("/accelerations/n-z-cg-fps_sec", this, &FGInterface::get_N_Z_cg);
+  fgTie("/accelerations/n-z-cg-fps_sec",
+        this, &FGInterface::get_N_Z_cg); // read-only
 
 }
 

From 9c983359aa709e47565e094c0fc25700f2a26980 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 13 Nov 2010 14:38:35 +0000
Subject: [PATCH 6/9] Move all MP code in src/MultiPlayer. Allow the subsystem
 to be (re-)inited at runtime.

---
 projects/VC90/FlightGear/FlightGear.vcproj |   8 -
 src/Main/fg_io.cxx                         |  49 ++--
 src/MultiPlayer/multiplaymgr.cxx           | 293 +++++++++++++++++--
 src/MultiPlayer/multiplaymgr.hxx           |  53 ++--
 src/Network/CMakeLists.txt                 |   1 -
 src/Network/Makefile.am                    |   3 -
 src/Network/multiplay.cxx                  | 319 ---------------------
 src/Network/multiplay.hxx                  |  97 -------
 8 files changed, 326 insertions(+), 497 deletions(-)
 delete mode 100644 src/Network/multiplay.cxx
 delete mode 100644 src/Network/multiplay.hxx

diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj
index f7d56ff93..8d70c4028 100644
--- a/projects/VC90/FlightGear/FlightGear.vcproj
+++ b/projects/VC90/FlightGear/FlightGear.vcproj
@@ -3033,14 +3033,6 @@
 				RelativePath="..\..\..\src\Network\jsclient.hxx"
 				>
 			</File>
-			<File
-				RelativePath="..\..\..\src\Network\multiplay.cxx"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\Network\multiplay.hxx"
-				>
-			</File>
 			<File
 				RelativePath="..\..\..\src\Network\native.cxx"
 				>
diff --git a/src/Main/fg_io.cxx b/src/Main/fg_io.cxx
index 6d6be65f5..c45b98f86 100644
--- a/src/Main/fg_io.cxx
+++ b/src/Main/fg_io.cxx
@@ -65,7 +65,7 @@
 #include <Network/ray.hxx>
 #include <Network/rul.hxx>
 #include <Network/generic.hxx>
-#include <Network/multiplay.hxx>
+
 #ifdef FG_HAVE_HLA
 #include <Network/HLA/hla.hxx>
 #endif
@@ -219,10 +219,23 @@ FGIO::parse_port_config( const string& config )
 		return NULL;
 	    }
 	    string dir = tokens[1];
-	    string rate = tokens[2];
+	    int rate = atoi(tokens[2].c_str());
 	    string host = tokens[3];
-	    string port = tokens[4];
-	    return new FGMultiplay(dir, atoi(rate.c_str()), host, atoi(port.c_str()));
+
+	     short port = atoi(tokens[4].c_str());    
+
+        // multiplay used to be handled by an FGProtocol, but no longer. This code
+        // retains compatability with existing command-line syntax
+          fgSetInt("/sim/multiplay/tx-rate-hz", rate);
+          if (dir == "in") {
+            fgSetInt("/sim/multiplay/rxport", port);
+            fgSetString("/sim/multiplay/rxhost", host.c_str());
+          } else if (dir == "out") {
+            fgSetInt("/sim/multiplay/txport", port);
+            fgSetString("/sim/multiplay/txhost", host.c_str());
+          }
+
+          return NULL;
 #ifdef FG_HAVE_HLA
 	} else if ( protocol == "hla" ) {
 	    return new FGHLA(tokens);
@@ -343,20 +356,20 @@ FGIO::init()
     // appropriate FGIOChannel structures
     string_list::iterator i = globals->get_channel_options_list()->begin();
     string_list::iterator end = globals->get_channel_options_list()->end();
-    for (; i != end; ++i )
-    {
-	p = parse_port_config( *i );
-	if ( p != NULL ) {
-	    p->open();
-	    io_channels.push_back( p );
-	    if ( !p->is_enabled() ) {
-		SG_LOG( SG_IO, SG_ALERT, "I/O Channel config failed." );
-		exit(-1);
-	    }
-	} else {
-	    SG_LOG( SG_IO, SG_INFO, "I/O Channel parse failed." );
-	}
-    }
+    for (; i != end; ++i ) {
+      p = parse_port_config( *i );
+      if (!p) {
+        continue;
+      }
+      
+      p->open();
+      if ( !p->is_enabled() ) {
+        SG_LOG( SG_IO, SG_ALERT, "I/O Channel config failed." );
+        delete p;
+      }
+      
+      io_channels.push_back( p );
+    } // of channel options iteration
 }
 
 void
diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx
index 9a5413827..a8f862388 100644
--- a/src/MultiPlayer/multiplaymgr.cxx
+++ b/src/MultiPlayer/multiplaymgr.cxx
@@ -42,9 +42,11 @@
 #include <simgear/props/props.hxx>
 
 #include <AIModel/AIManager.hxx>
+#include <AIModel/AIMultiplayer.hxx>
 #include <Main/fg_props.hxx>
 #include "multiplaymgr.hxx"
 #include "mpmessages.hxx"
+#include <FDM/flightProperties.hxx>
 
 using namespace std;
 
@@ -56,11 +58,18 @@ using namespace std;
 const char sMULTIPLAYMGR_BID[] = "$Id$";
 const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
 
+struct IdPropertyList {
+  unsigned id;
+  const char* name;
+  simgear::props::Type type;
+};
+ 
+static const IdPropertyList* findProperty(unsigned id);
+  
 // A static map of protocol property id values to property paths,
 // This should be extendable dynamically for every specific aircraft ...
 // For now only that static list
-const FGMultiplayMgr::IdPropertyList
-FGMultiplayMgr::sIdPropertyList[] = {
+static const IdPropertyList sIdPropertyList[] = {
   {100, "surface-positions/left-aileron-pos-norm",  simgear::props::FLOAT},
   {101, "surface-positions/right-aileron-pos-norm", simgear::props::FLOAT},
   {102, "surface-positions/elevator-pos-norm",      simgear::props::FLOAT},
@@ -229,34 +238,33 @@ FGMultiplayMgr::sIdPropertyList[] = {
   {10319, "sim/multiplay/generic/int[19]", simgear::props::INT}
 };
 
-const unsigned
-FGMultiplayMgr::numProperties = (sizeof(FGMultiplayMgr::sIdPropertyList)
-                                 / sizeof(FGMultiplayMgr::sIdPropertyList[0]));
+const unsigned int numProperties = (sizeof(sIdPropertyList)
+                                 / sizeof(sIdPropertyList[0]));
 
 // Look up a property ID using binary search.
 namespace
 {
   struct ComparePropertyId
   {
-    bool operator()(const FGMultiplayMgr::IdPropertyList& lhs,
-                    const FGMultiplayMgr::IdPropertyList& rhs)
+    bool operator()(const IdPropertyList& lhs,
+                    const IdPropertyList& rhs)
     {
       return lhs.id < rhs.id;
     }
-    bool operator()(const FGMultiplayMgr::IdPropertyList& lhs,
+    bool operator()(const IdPropertyList& lhs,
                     unsigned id)
     {
       return lhs.id < id;
     }
     bool operator()(unsigned id,
-                    const FGMultiplayMgr::IdPropertyList& rhs)
+                    const IdPropertyList& rhs)
     {
       return id < rhs.id;
     }
-  };
-    
+  };    
 }
-const FGMultiplayMgr::IdPropertyList* FGMultiplayMgr::findProperty(unsigned id)
+
+const IdPropertyList* findProperty(unsigned id)
 {
   std::pair<const IdPropertyList*, const IdPropertyList*> result
     = std::equal_range(sIdPropertyList, sIdPropertyList + numProperties, id,
@@ -276,8 +284,7 @@ namespace
     const xdr_data_t* xdr = data;
     while (xdr < end) {
       unsigned id = XDR_decode_uint32(*xdr);
-      const FGMultiplayMgr::IdPropertyList* plist
-        = FGMultiplayMgr::findProperty(id);
+      const IdPropertyList* plist = findProperty(id);
     
       if (plist) {
         xdr++;
@@ -336,6 +343,24 @@ namespace
     return true;
   }
 }
+
+class MPPropertyListener : public SGPropertyChangeListener
+{
+public:
+  MPPropertyListener(FGMultiplayMgr* mp) :
+    _multiplay(mp)
+  {
+  }
+
+  virtual void childAdded(SGPropertyNode*, SGPropertyNode*)
+  {
+    _multiplay->setPropertiesChanged();
+  }
+
+private:
+  FGMultiplayMgr* _multiplay;
+};
+
 //////////////////////////////////////////////////////////////////////
 //
 //  MultiplayMgr constructor
@@ -343,9 +368,9 @@ namespace
 //////////////////////////////////////////////////////////////////////
 FGMultiplayMgr::FGMultiplayMgr() 
 {
-  mSocket        = 0;
   mInitialised   = false;
   mHaveServer    = false;
+  mListener = NULL;
 } // FGMultiplayMgr::FGMultiplayMgr()
 //////////////////////////////////////////////////////////////////////
 
@@ -356,7 +381,7 @@ FGMultiplayMgr::FGMultiplayMgr()
 //////////////////////////////////////////////////////////////////////
 FGMultiplayMgr::~FGMultiplayMgr() 
 {
-  Close();
+  
 } // FGMultiplayMgr::~FGMultiplayMgr()
 //////////////////////////////////////////////////////////////////////
 
@@ -375,22 +400,36 @@ FGMultiplayMgr::init (void)
     SG_LOG(SG_NETWORK, SG_WARN, "FGMultiplayMgr::init - already initialised");
     return;
   }
+  
+  fgSetBool("/sim/multiplay/online", false);
+  
   //////////////////////////////////////////////////
   //  Set members from property values
   //////////////////////////////////////////////////
   short rxPort = fgGetInt("/sim/multiplay/rxport");
   string rxAddress = fgGetString("/sim/multiplay/rxhost");
-  short txPort = fgGetInt("/sim/multiplay/txport");
+  short txPort = fgGetInt("/sim/multiplay/txport", 5000);
   string txAddress = fgGetString("/sim/multiplay/txhost");
+  
+  int hz = fgGetInt("/sim/multiplay/tx-rate-hz", 10);
+  if (hz < 1) {
+    hz = 10;
+  }
+  
+  mDt = 1.0 / hz;
+  mTimeUntilSend = 0.0;
+  
   mCallsign = fgGetString("/sim/multiplay/callsign");
-  if (txPort > 0 && !txAddress.empty()) {
+  if (!txAddress.empty()) {
     mServer.set(txAddress.c_str(), txPort);
     if (strncmp (mServer.getHost(), "0.0.0.0", 8) == 0) {
       mHaveServer = false;
-      SG_LOG(SG_NETWORK, SG_DEBUG,
+      SG_LOG(SG_NETWORK, SG_WARN,
         "FGMultiplayMgr - could not resolve '"
         << txAddress << "', Multiplayermode disabled");
+      return;
     } else {
+        SG_LOG(SG_NETWORK, SG_INFO, "have server");
       mHaveServer = true;
     }
     if (rxPort <= 0)
@@ -408,11 +447,10 @@ FGMultiplayMgr::init (void)
   SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxaddress="<<rxAddress );
   SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxport= "<<rxPort);
   SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<mCallsign);
-  Close(); // Should Init be called twice, close Socket first
-           // A memory leak was reported here by valgrind
-  mSocket = new simgear::Socket();
+  
+  mSocket.reset(new simgear::Socket());
   if (!mSocket->open(false)) {
-    SG_LOG( SG_NETWORK, SG_DEBUG,
+    SG_LOG( SG_NETWORK, SG_WARN,
             "FGMultiplayMgr::init - Failed to create data socket" );
     return;
   }
@@ -424,6 +462,11 @@ FGMultiplayMgr::init (void)
     return;
   }
   
+  mPropertiesChanged = true;
+  mListener = new MPPropertyListener(this);
+  globals->get_props()->addChangeListener(mListener, false);
+  
+  fgSetBool("/sim/multiplay/online", true);
   mInitialised = true;
 } // FGMultiplayMgr::init()
 //////////////////////////////////////////////////////////////////////
@@ -435,19 +478,39 @@ FGMultiplayMgr::init (void)
 //
 //////////////////////////////////////////////////////////////////////
 void
-FGMultiplayMgr::Close (void) 
+FGMultiplayMgr::shutdown (void) 
 {
-  mMultiPlayerMap.clear();
-
-  if (mSocket) {
+  fgSetBool("/sim/multiplay/online", false);
+  
+  if (mSocket.get()) {
     mSocket->close();
-    delete mSocket;
-    mSocket = 0;
+    mSocket.reset(); 
   }
+  
+  MultiPlayerMap::iterator it = mMultiPlayerMap.begin(),
+    end = mMultiPlayerMap.end();
+  for (; it != end; ++it) {
+    it->second->setDie(true);
+  }
+  mMultiPlayerMap.clear();
+  
+  if (mListener) {
+    globals->get_props()->removeChangeListener(mListener);
+    delete mListener;
+    mListener = NULL;
+  }
+  
   mInitialised = false;
 } // FGMultiplayMgr::Close(void)
 //////////////////////////////////////////////////////////////////////
 
+void
+FGMultiplayMgr::reinit()
+{
+  shutdown();
+  init();
+}
+
 //////////////////////////////////////////////////////////////////////
 //
 //  Description: Sends the position data for the local position.
@@ -757,7 +820,7 @@ FGMultiplayMgr::SendTextMessage(const string &MsgText)
 //  
 //////////////////////////////////////////////////////////////////////
 void
-FGMultiplayMgr::update(double) 
+FGMultiplayMgr::update(double dt) 
 {
   if (!mInitialised)
     return;
@@ -765,6 +828,14 @@ FGMultiplayMgr::update(double)
   /// Just for expiry
   long stamp = SGTimeStamp::now().getSeconds();
 
+  //////////////////////////////////////////////////
+  //  Send if required
+  //////////////////////////////////////////////////
+  mTimeUntilSend -= dt;
+  if (mTimeUntilSend <= 0.0) {
+    Send();
+  }
+
   //////////////////////////////////////////////////
   //  Read the receive socket and process any data
   //////////////////////////////////////////////////
@@ -813,7 +884,7 @@ FGMultiplayMgr::update(double)
               << "message has invalid protocol number!" );
       break;
     }
-    if (MsgHdr->MsgLen != bytes) {
+    if (static_cast<ssize_t>(MsgHdr->MsgLen) != bytes) {
       SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
              << "message from " << MsgHdr->Callsign << " has invalid length!");
       break;
@@ -854,6 +925,140 @@ FGMultiplayMgr::update(double)
 } // FGMultiplayMgr::ProcessData(void)
 //////////////////////////////////////////////////////////////////////
 
+void
+FGMultiplayMgr::Send()
+{
+  using namespace simgear;
+  
+  findProperties();
+    
+  // smooth the send rate, by adjusting based on the 'remainder' time, which
+  // is how -ve mTimeUntilSend is. Watch for large values and ignore them,
+  // however.
+    if ((mTimeUntilSend < 0.0) && (fabs(mTimeUntilSend) < mDt)) {
+      mTimeUntilSend = mDt + mTimeUntilSend;
+    } else {
+      mTimeUntilSend = mDt;
+    }
+
+    double sim_time = globals->get_sim_time_sec();
+    static double lastTime = 0.0;
+    
+   // SG_LOG(SG_GENERAL, SG_INFO, "actual dt=" << sim_time - lastTime);
+    lastTime = sim_time;
+    
+    FlightProperties ifce;
+
+    // put together a motion info struct, you will get that later
+    // from FGInterface directly ...
+    FGExternalMotionData motionInfo;
+
+    // The current simulation time we need to update for,
+    // note that the simulation time is updated before calling all the
+    // update methods. Thus it contains the time intervals *end* time.
+    // The FDM is already run, so the states belong to that time.
+    motionInfo.time = sim_time;
+    motionInfo.lag = mDt;
+
+    // These are for now converted from lat/lon/alt and euler angles.
+    // But this should change in FGInterface ...
+    double lon = ifce.get_Longitude();
+    double lat = ifce.get_Latitude();
+    // first the aprioriate structure for the geodetic one
+    SGGeod geod = SGGeod::fromRadFt(lon, lat, ifce.get_Altitude());
+    // Convert to cartesion coordinate
+    motionInfo.position = SGVec3d::fromGeod(geod);
+    
+    // The quaternion rotating from the earth centered frame to the
+    // horizontal local frame
+    SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)lon, (float)lat);
+    // The orientation wrt the horizontal local frame
+    float heading = ifce.get_Psi();
+    float pitch = ifce.get_Theta();
+    float roll = ifce.get_Phi();
+    SGQuatf hlOr = SGQuatf::fromYawPitchRoll(heading, pitch, roll);
+    // The orientation of the vehicle wrt the earth centered frame
+    motionInfo.orientation = qEc2Hl*hlOr;
+
+    if (!globals->get_subsystem("flight")->is_suspended()) {
+      // velocities
+      motionInfo.linearVel = SG_FEET_TO_METER*SGVec3f(ifce.get_uBody(),
+                                                      ifce.get_vBody(),
+                                                      ifce.get_wBody());
+      motionInfo.angularVel = SGVec3f(ifce.get_P_body(),
+                                      ifce.get_Q_body(),
+                                      ifce.get_R_body());
+      
+      // accels, set that to zero for now.
+      // Angular accelerations are missing from the interface anyway,
+      // linear accelerations are screwed up at least for JSBSim.
+//  motionInfo.linearAccel = SG_FEET_TO_METER*SGVec3f(ifce.get_U_dot_body(),
+//                                                    ifce.get_V_dot_body(),
+//                                                    ifce.get_W_dot_body());
+      motionInfo.linearAccel = SGVec3f::zeros();
+      motionInfo.angularAccel = SGVec3f::zeros();
+    } else {
+      // if the interface is suspendend, prevent the client from
+      // wild extrapolations
+      motionInfo.linearVel = SGVec3f::zeros();
+      motionInfo.angularVel = SGVec3f::zeros();
+      motionInfo.linearAccel = SGVec3f::zeros();
+      motionInfo.angularAccel = SGVec3f::zeros();
+    }
+
+    // now send the properties
+    PropertyMap::iterator it;
+    for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) {
+      FGPropertyData* pData = new FGPropertyData;
+      pData->id = it->first;
+      pData->type = it->second->getType();
+      
+      switch (pData->type) {
+        case props::INT:
+        case props::LONG:
+        case props::BOOL:
+          pData->int_value = it->second->getIntValue();
+          break;
+        case props::FLOAT:
+        case props::DOUBLE:
+          pData->float_value = it->second->getFloatValue();
+          break;
+        case props::STRING:
+        case props::UNSPECIFIED:
+          {
+            // FIXME: We assume unspecified are strings for the moment.
+
+            const char* cstr = it->second->getStringValue();
+            int len = strlen(cstr);
+            
+            if (len > 0)
+            {            
+              pData->string_value = new char[len + 1];
+              strcpy(pData->string_value, cstr);
+            }
+            else
+            {
+              // Size 0 - ignore
+              pData->string_value = 0;            
+            }
+
+            //cout << " Sending property " << pData->id << " " << pData->type << " " <<  pData->string_value << "\n";
+            break;        
+          }
+        default:
+          // FIXME Currently default to a float. 
+          //cout << "Unknown type when iterating through props: " << pData->type << "\n";
+          pData->float_value = it->second->getFloatValue();
+          break;
+      }
+      
+      motionInfo.properties.push_back(pData);
+    }
+
+    SendMyPosition(motionInfo);
+}
+
+
 //////////////////////////////////////////////////////////////////////
 //
 //  handle a position message
@@ -1101,3 +1306,29 @@ FGMultiplayMgr::getMultiplayer(const std::string& callsign)
   else
     return 0;
 }
+
+void
+FGMultiplayMgr::findProperties()
+{
+  if (!mPropertiesChanged) {
+    return;
+  }
+  
+  mPropertiesChanged = false;
+  
+  for (unsigned i = 0; i < numProperties; ++i) {
+      const char* name = sIdPropertyList[i].name;
+      SGPropertyNode* pNode = globals->get_props()->getNode(name);
+      if (!pNode) {
+        continue;
+      }
+      
+      int id = sIdPropertyList[i].id;
+      if (mPropertyMap.find(id) != mPropertyMap.end()) {
+        continue; // already activated
+      }
+      
+      mPropertyMap[id] = pNode;
+      SG_LOG(SG_NETWORK, SG_DEBUG, "activating MP property:" << pNode->getPath());
+    }
+}
diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx
index 8475c0ef1..daae68b57 100644
--- a/src/MultiPlayer/multiplaymgr.hxx
+++ b/src/MultiPlayer/multiplaymgr.hxx
@@ -31,48 +31,50 @@
 
 #define MULTIPLAYTXMGR_HID "$Id$"
 
-#include "mpmessages.hxx"
 
 #include <string>
 #include <vector>
 
 #include <simgear/compiler.h>
 #include <simgear/props/props.hxx>
-#include <Main/globals.hxx>
 #include <simgear/io/raw_socket.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 
-#include <AIModel/AIMultiplayer.hxx>
-
-struct FGExternalMotionInfo;
+struct FGExternalMotionData;
+class MPPropertyListener;
+struct T_MsgHdr;
+class FGAIMultiplayer;
 
 class FGMultiplayMgr : public SGSubsystem
 {
-public:
-
-  struct IdPropertyList {
-    unsigned id;
-    const char* name;
-    simgear::props::Type type;
-  };
-  static const IdPropertyList sIdPropertyList[];
-  static const unsigned numProperties;
-
-  static const IdPropertyList* findProperty(unsigned id);
-  
+public:  
   FGMultiplayMgr();
   ~FGMultiplayMgr();
   
   virtual void init(void);
   virtual void update(double dt);
   
-  void Close(void);
+  virtual void shutdown(void);
+  virtual void reinit();
+  
   // transmitter
-  void SendMyPosition(const FGExternalMotionData& motionInfo);
+  
   void SendTextMessage(const string &sMsgText);
   // receiver
   
 private:
+  friend class MPPropertyListener;
+  
+  void setPropertiesChanged()
+  {
+    mPropertiesChanged = true;
+  }
+  
+  void findProperties();
+  
+  void Send();
+  void SendMyPosition(const FGExternalMotionData& motionInfo);
+
   union MsgBuf;
   FGAIMultiplayer* addMultiplayer(const std::string& callsign,
                                   const std::string& modelName);
@@ -87,11 +89,22 @@ private:
   typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;
   MultiPlayerMap mMultiPlayerMap;
 
-  simgear::Socket* mSocket;
+  std::auto_ptr<simgear::Socket> mSocket;
   simgear::IPAddress mServer;
   bool mHaveServer;
   bool mInitialised;
   std::string mCallsign;
+  
+  // Map between the property id's from the multiplayers network packets
+  // and the property nodes
+  typedef std::map<unsigned int, SGSharedPtr<SGPropertyNode> > PropertyMap;
+  PropertyMap mPropertyMap;
+  
+  bool mPropertiesChanged;
+  MPPropertyListener* mListener;
+  
+  double mDt; // reciprocal of /sim/multiplay/tx-rate-hz
+  double mTimeUntilSend;
 };
 
 #endif
diff --git a/src/Network/CMakeLists.txt b/src/Network/CMakeLists.txt
index 1f42c68c7..3f0e202c2 100644
--- a/src/Network/CMakeLists.txt
+++ b/src/Network/CMakeLists.txt
@@ -15,7 +15,6 @@ set(SOURCES
 	jpg-httpd.cxx
 	jsclient.cxx
 	lfsglass.cxx
-	multiplay.cxx
 	native.cxx
 	native_ctrls.cxx
 	native_fdm.cxx
diff --git a/src/Network/Makefile.am b/src/Network/Makefile.am
index 0935d3ca4..e4ecc3b10 100644
--- a/src/Network/Makefile.am
+++ b/src/Network/Makefile.am
@@ -9,8 +9,6 @@ else
 JPEG_SERVER =
 endif
 
-MPLAYER_AS = multiplay.cxx multiplay.hxx
-
 libNetwork_a_SOURCES = \
 	protocol.cxx protocol.hxx \
 	ATC-Main.cxx ATC-Main.hxx \
@@ -33,7 +31,6 @@ libNetwork_a_SOURCES = \
 	net_ctrls.hxx net_fdm.hxx net_fdm_mini.hxx net_gui.hxx \
         nmea.cxx nmea.hxx \
         opengc.cxx opengc.hxx opengc_data.hxx \
-	$(MPLAYER_AS) \
 	props.cxx props.hxx \
 	pve.cxx pve.hxx \
 	ray.cxx ray.hxx \
diff --git a/src/Network/multiplay.cxx b/src/Network/multiplay.cxx
deleted file mode 100644
index ddedccea8..000000000
--- a/src/Network/multiplay.cxx
+++ /dev/null
@@ -1,319 +0,0 @@
-// multiplay.cxx -- protocol object for multiplay in Flightgear
-//
-// Written by Diarmuid Tyson, started February 2003.
-// diarmuid.tyson@airservicesaustralia.com
-//
-// With addtions by Vivian Meazza, January 2006
-//
-// Copyright (C) 2003  Airservices Australia
-//
-// 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 <simgear/compiler.h>
-
-#include <cstring>
-#include <iostream>
-#include <map>
-#include <string>
-
-#include <simgear/debug/logstream.hxx>
-#include <simgear/math/SGMath.hxx>
-
-#include <FDM/flightProperties.hxx>
-#include <MultiPlayer/mpmessages.hxx>
-
-#include "multiplay.hxx"
-
-using std::string;
-
-
-// These constants are provided so that the ident command can list file versions.
-const char sFG_MULTIPLAY_BID[] = "$Id$";
-const char sFG_MULTIPLAY_HID[] = FG_MULTIPLAY_HID;
-
-typedef std::set<std::string> string_set;
-
-class MPPropertyListener : public SGPropertyChangeListener
-{
-public:
-  MPPropertyListener(FGMultiplay* mp) :
-    _multiplay(mp)
-  {
-  }
-
-  virtual void childAdded(SGPropertyNode*, SGPropertyNode*)
-  {
-    _multiplay->setPropertiesChanged();
-  }
-
-private:
-  FGMultiplay* _multiplay;
-};
-
-/******************************************************************
-* Name: FGMultiplay
-* Description: Constructor.  Initialises the protocol and stores
-* host and port information.
-******************************************************************/
-FGMultiplay::FGMultiplay (const string &dir, const int rate, const string &host, const int port) {
-
-  set_hz(rate);
-
-  set_direction(dir);
-
-  if (get_direction() == SG_IO_IN) {
-
-    fgSetInt("/sim/multiplay/rxport", port);
-    fgSetString("/sim/multiplay/rxhost", host.c_str());
-
-  } else if (get_direction() == SG_IO_OUT) {
-
-    fgSetInt("/sim/multiplay/txport", port);
-    fgSetString("/sim/multiplay/txhost", host.c_str());
-
-  }
-
-  mPropertiesChanged = true;
-}
-
-
-/******************************************************************
-* Name: ~FGMultiplay
-* Description: Destructor.
-******************************************************************/
-FGMultiplay::~FGMultiplay () {
-}
-
-
-/******************************************************************
-* Name: open
-* Description: Enables the protocol.
-******************************************************************/
-bool FGMultiplay::open() {
-
-    if ( is_enabled() ) {
-	SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel "
-		<< "is already in use, ignoring" );
-	return false;
-    }
-
-    set_enabled(true);
-    
-    mPropertiesChanged = true;
-    
-    MPPropertyListener* pl = new MPPropertyListener(this);
-    globals->get_props()->addChangeListener(pl, false);
-    return is_enabled();
-}
-
-void FGMultiplay::findProperties()
-{
-  if (!mPropertiesChanged) {
-    return;
-  }
-  
-  mPropertiesChanged = false;
-  
-  for (unsigned i = 0; i < FGMultiplayMgr::numProperties; ++i) {
-      const char* name = FGMultiplayMgr::sIdPropertyList[i].name;
-      SGPropertyNode* pNode = globals->get_props()->getNode(name);
-      if (!pNode) {
-        continue;
-      }
-      
-      int id = FGMultiplayMgr::sIdPropertyList[i].id;
-      if (mPropertyMap.find(id) != mPropertyMap.end()) {
-        continue; // already activated
-      }
-      
-      mPropertyMap[id] = pNode;
-      SG_LOG(SG_NETWORK, SG_INFO, "activating MP property:" << pNode->getPath());
-    }
-
-}
-
-
-/******************************************************************
-* Name: process
-* Description: Prompts the multiplayer mgr to either send
-* or receive data over the network
-******************************************************************/
-bool FGMultiplay::process() {
-  using namespace simgear;
-  if (get_direction() == SG_IO_OUT) {
-    findProperties();
-    
-    // check if we have left initialization phase. That will not provide
-    // interresting data, also the freeze in simulation time hurts the
-    // multiplayer clients
-    double sim_time = globals->get_sim_time_sec();
-//     if (sim_time < 20)
-//       return true;
-
-    FlightProperties ifce;
-
-    // put together a motion info struct, you will get that later
-    // from FGInterface directly ...
-    FGExternalMotionData motionInfo;
-
-    // The current simulation time we need to update for,
-    // note that the simulation time is updated before calling all the
-    // update methods. Thus it contains the time intervals *end* time.
-    // The FDM is already run, so the states belong to that time.
-    motionInfo.time = sim_time;
-
-    // The typical lag will be the reciprocal of the output frequency
-    double hz = get_hz();
-    if (hz != 0) // I guess we can test a double for exact zero in this case
-      motionInfo.lag = 1/get_hz();
-    else
-      motionInfo.lag = 0.1; //??
-
-    // These are for now converted from lat/lon/alt and euler angles.
-    // But this should change in FGInterface ...
-    double lon = ifce.get_Longitude();
-    double lat = ifce.get_Latitude();
-    // first the aprioriate structure for the geodetic one
-    SGGeod geod = SGGeod::fromRadFt(lon, lat, ifce.get_Altitude());
-    // Convert to cartesion coordinate
-    motionInfo.position = SGVec3d::fromGeod(geod);
-    
-    // The quaternion rotating from the earth centered frame to the
-    // horizontal local frame
-    SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)lon, (float)lat);
-    // The orientation wrt the horizontal local frame
-    float heading = ifce.get_Psi();
-    float pitch = ifce.get_Theta();
-    float roll = ifce.get_Phi();
-    SGQuatf hlOr = SGQuatf::fromYawPitchRoll(heading, pitch, roll);
-    // The orientation of the vehicle wrt the earth centered frame
-    motionInfo.orientation = qEc2Hl*hlOr;
-
-    if (!globals->get_subsystem("flight")->is_suspended()) {
-      // velocities
-      motionInfo.linearVel = SG_FEET_TO_METER*SGVec3f(ifce.get_uBody(),
-                                                      ifce.get_vBody(),
-                                                      ifce.get_wBody());
-      motionInfo.angularVel = SGVec3f(ifce.get_P_body(),
-                                      ifce.get_Q_body(),
-                                      ifce.get_R_body());
-      
-      // accels, set that to zero for now.
-      // Angular accelerations are missing from the interface anyway,
-      // linear accelerations are screwed up at least for JSBSim.
-//  motionInfo.linearAccel = SG_FEET_TO_METER*SGVec3f(ifce.get_U_dot_body(),
-//                                                    ifce.get_V_dot_body(),
-//                                                    ifce.get_W_dot_body());
-      motionInfo.linearAccel = SGVec3f::zeros();
-      motionInfo.angularAccel = SGVec3f::zeros();
-    } else {
-      // if the interface is suspendend, prevent the client from
-      // wild extrapolations
-      motionInfo.linearVel = SGVec3f::zeros();
-      motionInfo.angularVel = SGVec3f::zeros();
-      motionInfo.linearAccel = SGVec3f::zeros();
-      motionInfo.angularAccel = SGVec3f::zeros();
-    }
-
-    // now send the properties
-    PropertyMap::iterator it;
-    for (it = mPropertyMap.begin(); it != mPropertyMap.end(); ++it) {
-      FGPropertyData* pData = new FGPropertyData;
-      pData->id = it->first;
-      pData->type = it->second->getType();
-      
-      switch (pData->type) {
-        case props::INT:
-        case props::LONG:
-        case props::BOOL:
-          pData->int_value = it->second->getIntValue();
-          break;
-        case props::FLOAT:
-        case props::DOUBLE:
-          pData->float_value = it->second->getFloatValue();
-          break;
-        case props::STRING:
-        case props::UNSPECIFIED:
-          {
-            // FIXME: We assume unspecified are strings for the moment.
-
-            const char* cstr = it->second->getStringValue();
-            int len = strlen(cstr);
-            
-            if (len > 0)
-            {            
-              pData->string_value = new char[len + 1];
-              strcpy(pData->string_value, cstr);
-            }
-            else
-            {
-              // Size 0 - ignore
-              pData->string_value = 0;            
-            }
-
-            //cout << " Sending property " << pData->id << " " << pData->type << " " <<  pData->string_value << "\n";
-            break;        
-          }
-        default:
-          // FIXME Currently default to a float. 
-          //cout << "Unknown type when iterating through props: " << pData->type << "\n";
-          pData->float_value = it->second->getFloatValue();
-          break;
-      }
-      
-      motionInfo.properties.push_back(pData);
-    }
-
-    FGMultiplayMgr* mpmgr = (FGMultiplayMgr*) globals->get_subsystem("mp");
-    mpmgr->SendMyPosition(motionInfo);
-  }
-
-  return true;
-}
-
-
-/******************************************************************
-* Name: close
-* Description:  Closes the multiplayer mgrs to stop any further
-* network processing
-******************************************************************/
-bool FGMultiplay::close()
-{
-  mPropertyMap.clear();
-  
-  FGMultiplayMgr* mgr = (FGMultiplayMgr*) globals->get_subsystem("mp");
-
-  if (mgr == 0) {
-    return false;
-  }
-
-  if (get_direction() == SG_IO_IN) {
-
-    mgr->Close();
-
-  } else if (get_direction() == SG_IO_OUT) {
-
-    mgr->Close();
-
-  }
-
-  return true;
-}
-
diff --git a/src/Network/multiplay.hxx b/src/Network/multiplay.hxx
deleted file mode 100644
index f596ea0eb..000000000
--- a/src/Network/multiplay.hxx
+++ /dev/null
@@ -1,97 +0,0 @@
-// multiplay.hxx -- protocol object for multiplay in Flightgear
-//
-// Written by Diarmuid Tyson, started February 2003.
-// diarmuid.tyson@airservicesaustralia.com
-//
-// With additions by Vivian Meazza, January 2006
-//
-// Copyright (C) 2003  Airservices Australia
-//
-// 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 _FG_MULTIPLAY_HXX
-#define _FG_MULTIPLAY_HXX
-
-#define FG_MULTIPLAY_HID "$Id$"
-
-#include <simgear/compiler.h>
-
-#include <string>
-
-#include <simgear/props/props.hxx>
-
-#include <Main/globals.hxx>
-#include <Main/fg_props.hxx>
-#include <Model/acmodel.hxx>
-#include <MultiPlayer/multiplaymgr.hxx>
-
-#include "protocol.hxx"
-
-using std::string;
-
-
-/****************************************************************
-* @version $Id$
-*
-* Description: FGMultiplay is an FGProtocol object used as the basic
-* interface for the multiplayer code into FlightGears generic IO
-* subsystem.  It only implements the basic FGProtocol methods: open(),
-* process() and close().  It does not use Sim Gear's IO channels, as
-* the MultiplayMgrs creates their own sockets through plib.
-*
-* It will set up it's direction and rate protocol properties when
-* created.  Subsequent calls to process will prompt the
-* MultiplayMgr to either send or receive data over the network.
-*
-******************************************************************/
-
-class FGMultiplay : public FGProtocol {
-public:
-
-    /** Constructor */
-    FGMultiplay (const string &dir, const int rate, const string &host, const int port);
-
-    /** Destructor. */
-    ~FGMultiplay ();
-
-    /** Enables the FGMultiplay object. */
-    bool open();
-
-    /** Tells the multiplayer_mgr to send/receive data.
-    */
-    bool process();
-
-    /** Closes the multiplayer_mgr.
-    */
-    bool close();
-
-    void setPropertiesChanged()
-    {
-      mPropertiesChanged = true;
-    }
-private:
-  bool mPropertiesChanged;
-  
-  void findProperties();
-  
-  // Map between the property id's from the multiplayers network packets
-  // and the property nodes
-  typedef std::map<unsigned, SGSharedPtr<SGPropertyNode> > PropertyMap;
-  PropertyMap mPropertyMap;
-};
-
-
-#endif // _FG_MULTIPLAY_HXX

From 11bb6ef1466a64c966479f39e0526da03ce1b33c Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Sun, 29 May 2011 09:34:56 +0200
Subject: [PATCH 7/9] Fix linux build - auto_ptr<> needs <memory>

---
 src/MultiPlayer/multiplaymgr.hxx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx
index daae68b57..42444f014 100644
--- a/src/MultiPlayer/multiplaymgr.hxx
+++ b/src/MultiPlayer/multiplaymgr.hxx
@@ -34,6 +34,7 @@
 
 #include <string>
 #include <vector>
+#include <memory>
 
 #include <simgear/compiler.h>
 #include <simgear/props/props.hxx>

From 3c8a80d968755f0097366616fa26e281c4279ae5 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 29 May 2011 18:44:15 +0200
Subject: [PATCH 8/9] Deterministic loading sequence for Nasal scripts Avoid
 loading Nasal scripts in (random) file system order

---
 src/Scripting/NasalSys.cxx | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx
index 62a2b261c..2690bda6d 100644
--- a/src/Scripting/NasalSys.cxx
+++ b/src/Scripting/NasalSys.cxx
@@ -805,10 +805,19 @@ void FGNasalSys::update(double)
     _context = naNewContext();
 }
 
+bool pathSortPredicate(const SGPath& p1, const SGPath& p2)
+{
+  return p1.file() < p2.file();
+}
+
 // Loads all scripts in given directory 
 void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir)
 {
     simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
+    // sort scripts, avoid loading sequence effects due to file system's
+    // random directory order
+    std::sort(scripts.begin(), scripts.end(), pathSortPredicate);
+
     for (unsigned int i=0; i<scripts.size(); ++i) {
       SGPath fullpath(scripts[i]);
       SGPath file = fullpath.file();

From 863551a932e21f3d4315c0ceb51005929acc9f20 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Sun, 29 May 2011 18:46:11 +0200
Subject: [PATCH 9/9] fix #142: initial window position Be (at least a bit)
 smarter with initial x/y position Also some minor type/comment issues.

---
 src/Main/WindowBuilder.cxx     | 17 +++++++++--------
 src/Main/options.cxx           |  2 +-
 src/Main/viewmgr.cxx           |  2 +-
 src/MultiPlayer/mpmessages.hxx |  2 +-
 src/Sound/sample_queue.cxx     |  2 +-
 src/Time/light.cxx             |  4 ++--
 6 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/Main/WindowBuilder.cxx b/src/Main/WindowBuilder.cxx
index 740671cd5..52f09011d 100644
--- a/src/Main/WindowBuilder.cxx
+++ b/src/Main/WindowBuilder.cxx
@@ -69,9 +69,9 @@ WindowBuilder::makeDefaultTraits(bool stencil)
     traits->red = traits->green = traits->blue = cbits;
     traits->depth = zbits;
     if (alpha)
-	traits->alpha = 8;
+        traits->alpha = 8;
     if (stencil)
-	traits->stencil = 8;
+        traits->stencil = 8;
     traits->doubleBuffer = true;
     traits->mipMapGeneration = true;
     traits->windowName = "FlightGear";
@@ -83,20 +83,21 @@ WindowBuilder::makeDefaultTraits(bool stencil)
         unsigned width = 0;
         unsigned height = 0;
         wsi->getScreenResolution(*traits, width, height);
-	traits->windowDecoration = false;
+        traits->windowDecoration = false;
         traits->width = width;
         traits->height = height;
         traits->supportsResize = false;
     } else {
-	traits->windowDecoration = true;
+        traits->windowDecoration = true;
         traits->width = w;
         traits->height = h;
-#if defined(WIN32) || defined(__APPLE__)
+        unsigned screenwidth = 0;
+        unsigned screenheight = 0;
+        wsi->getScreenResolution(*traits, screenwidth, screenheight);
         // Ugly Hack, why does CW_USEDEFAULT works like phase of the moon?
         // Mac also needs this to show window frame, menubar and Docks
-        traits->x = 100;
-        traits->y = 100;
-#endif
+        traits->x = (w>screenwidth) ? 0 : (screenwidth-w)/3;
+        traits->y = (h>screenheight) ? 0 : (screenheight-h)/3;
         traits->supportsResize = true;
     }
     return traits;
diff --git a/src/Main/options.cxx b/src/Main/options.cxx
index df50b344c..01f1e4438 100644
--- a/src/Main/options.cxx
+++ b/src/Main/options.cxx
@@ -1838,7 +1838,7 @@ fgUsage (bool verbose)
 
                          while ( t_str.size() > 47 ) {
 
-                            unsigned int m = t_str.rfind(' ', 47);
+                            string::size_type m = t_str.rfind(' ', 47);
                             msg += t_str.substr(0, m) + '\n';
                             msg.append( 32, ' ');
 
diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx
index 955529189..ea9fcd7a6 100644
--- a/src/Main/viewmgr.cxx
+++ b/src/Main/viewmgr.cxx
@@ -356,7 +356,7 @@ FGViewMgr::update (double dt)
   abs_viewer_position = loop_view->getViewPosition();
 
   // update audio listener values
-  // set the viewer posotion in Cartesian coordinates in meters
+  // set the viewer position in Cartesian coordinates in meters
   smgr->set_position( abs_viewer_position, loop_view->getPosition() );
   smgr->set_orientation( current_view_orientation );
 
diff --git a/src/MultiPlayer/mpmessages.hxx b/src/MultiPlayer/mpmessages.hxx
index f5b89eb82..38e7fea58 100644
--- a/src/MultiPlayer/mpmessages.hxx
+++ b/src/MultiPlayer/mpmessages.hxx
@@ -164,7 +164,7 @@ struct FGExternalMotionData {
   // the earth centered frame
   SGVec3f angularAccel;
   
-  // The set of properties recieved for this timeslot
+  // The set of properties received for this timeslot
   std::vector<FGPropertyData*> properties;
 
   ~FGExternalMotionData()
diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx
index e5c2293a6..ac56c9b25 100644
--- a/src/Sound/sample_queue.cxx
+++ b/src/Sound/sample_queue.cxx
@@ -80,7 +80,7 @@ FGSampleQueue::update (double dt)
             last_volume = volume;
         }
 
-        // process mesage queue
+        // process message queue
         const string msgid = "Sequential Audio Message";
         bool now_playing = false;
         if ( exists( msgid ) ) {
diff --git a/src/Time/light.cxx b/src/Time/light.cxx
index 348bd524d..79259c03c 100644
--- a/src/Time/light.cxx
+++ b/src/Time/light.cxx
@@ -345,7 +345,7 @@ void FGLight::update_adj_fog_color () {
     else
        hor_rotation = fmod(hor_rotation, SGD_2PI);
 
-    // revert to unmodified values before usign them.
+    // revert to unmodified values before using them.
     //
     SGVec4f color = thesky->get_scene_color();
 
@@ -359,7 +359,7 @@ void FGLight::update_adj_fog_color () {
     float s_green = color[1]*color[1]*color[1];
     float s_blue =  color[2]*color[2];
 
-    // interpolate beween the sunrise/sunset color and the color
+    // interpolate between the sunrise/sunset color and the color
     // at the opposite direction of this effect. Take in account
     // the current visibility.
     //