#include <simgear/structure/exception.hxx>
#include <Main/fg_props.hxx>
-#include <FDM/fdm_shell.hxx>
#include "replay.hxx"
#include "flightrecorder.hxx"
if ( disable_replay->getBoolValue() )
{
- current_replay_state = replay_master->getIntValue();
- replay_master->setIntValue(0);
- replay_time->setDoubleValue(0);
- replay_time_str->setStringValue("");
- disable_replay->setBoolValue(0);
- speed_up->setDoubleValue(1.0);
- fgSetString("/sim/messages/copilot", "Replay stopped");
+ if (fgGetBool("/sim/freeze/master",false)||
+ fgGetBool("/sim/freeze/clock",false))
+ {
+ fgSetBool("/sim/freeze/master",false);
+ fgSetBool("/sim/freeze/clock",false);
+ last_replay_state = 1;
+ }
+ else
+ if ((replay_master->getIntValue() != 3)||
+ (last_replay_state == 3))
+ {
+ current_replay_state = replay_master->getIntValue();
+ replay_master->setIntValue(0);
+ replay_time->setDoubleValue(0);
+ replay_time_str->setStringValue("");
+ disable_replay->setBoolValue(0);
+ speed_up->setDoubleValue(1.0);
+ speed_up->setDoubleValue(1.0);
+ if (fgGetBool("/sim/replay/mute",false))
+ {
+ fgSetBool("/sim/sound/enabled",true);
+ fgSetBool("/sim/replay/mute",false);
+ }
+ fgSetString("/sim/messages/copilot", "Replay stopped. Your controls!");
+ }
}
int replay_state = replay_master->getIntValue();
-
- if ((replay_state > 0)&&
- (last_replay_state == 0))
- {
- // replay is starting, suspend FDM
- /* FIXME we need to suspend/resume the FDM - not the entire FDM shell.
- * FDM isn't available via the global subsystem manager yet, so need a
- * method at the FDMshell for now */
- ((FDMShell*) globals->get_subsystem("flight"))->getFDM()->suspend();
- }
- else
if ((replay_state == 0)&&
(last_replay_state > 0))
{
if (current_replay_state == 3)
{
- // "my controls!" requested: pilot takes control at current replay position...
+ // take control at current replay position ("My controls!").
// May need to uncrash the aircraft here :)
fgSetBool("/sim/crashed", false);
}
else
{
- // replay was active, restore most recent frame
+ // normal replay exit, restore most recent frame
replay(DBL_MAX);
}
- // replay is finished, resume FDM
- ((FDMShell*) globals->get_subsystem("flight"))->getFDM()->resume();
+
+ // replay is finished
+ last_replay_state = replay_state;
+ return;
}
// remember recent state
case 0:
// replay inactive, keep recording
break;
- case 1:
+ case 1: // normal replay
+ case 3: // prepare to resume normal flight at current replay position
{
// replay active
double current_time = replay_time->getDoubleValue();
return; // don't record the replay session
}
case 2: // normal replay operation
- case 3: // replay operation, prepare to resume normal flight at current replay position
- // replay paused, no-op
return; // don't record the replay session
default:
throw sg_range_exception("unknown FGReplay state");
int iterations = _calc_multiloop(dt);
// If we're crashed, then we don't care
- if(_fdm->getAirplane()->getModel()->isCrashed()) {
+ if(fgGetBool("/sim/crashed") || _fdm->getAirplane()->getModel()->isCrashed()) {
if(!fgGetBool("/sim/crashed"))
fgSetBool("/sim/crashed", true);
+ _fdm->getAirplane()->getModel()->setCrashed(false);
return;
}
Math::set3(v, s.v);
if(copyState || needCopy)
- model->setState(&s);
+ model->setState(&s);
// wind
Math::tmul33(xyz2ned, wind, wind);
}
}
+
+/** Reinit the FDM.
+ * This is only used after a replay session and when the user requested to resume at
+ * a past point of time. In thise case the FDM must reload all values from the property
+ * tree (as given by the replay system). */
+void YASim::reinit()
+{
+ // Process inputs. Use excessive value for dt to make sure all transition effects
+ // have reached their final state (i.e. gear is extended/retracted) - which is vital
+ // for many properties to be complete before the first FDM run (otherwise the gear may
+ // still be up, thrust-reversers/speed-brakes/... may still be partially deployed...).
+ _fdm->getExternalInput(1000);
+
+ // get current FDM values from the property tree
+ copyToYASim(true);
+}
_pressure_inhg = _props->getNode("environment/pressure-inhg", true);
_density_slugft = _props->getNode("environment/density-slugft3", true);
_data_logging = _props->getNode("/sim/temp/fdm-data-logging", true);
+ _replay_master = _props->getNode("/sim/freeze/replay-state", true);
createImplementation();
}
_impl->ToggleDataLogging(doLog);
}
- if (!_impl->is_suspended())
- _impl->update(dt);
+ switch(_replay_master->getIntValue())
+ {
+ case 0:
+ // normal FDM operation
+ _impl->update(dt);
+ break;
+ case 3:
+ // resume FDM operation at current replay position
+ _impl->reinit();
+ break;
+ default:
+ // replay is active
+ break;
+ }
}
void FDMShell::createImplementation()
}
}
-
-/*
- * Return FDM subsystem.
- */
-
-SGSubsystem* FDMShell::getFDM()
-{
- /* FIXME we could drop/replace this method, when _impl was a added
- * to the global subsystem manager - like other proper subsystems... */
- return _impl;
-}