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. //