diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 6ae969ddb..63908b96f 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -52,8 +52,9 @@ #include "karts/max_speed.hpp" #include "karts/skidding.hpp" #include "modes/linear_world.hpp" -#include "network/race_state.hpp" #include "network/network_manager.hpp" +#include "network/rewind_manager.hpp" +#include "network/race_state.hpp" #include "physics/btKart.hpp" #include "physics/btKartRaycast.hpp" #include "physics/btUprightConstraint.hpp" @@ -530,7 +531,7 @@ void Kart::blockViewWithPlunger() if(isShielded()) { decreaseShieldTime(0.0f); //decrease the default amount of time - Log::verbose("Kart", "Decreasing shield, because of removing the plunger. \n"); + Log::verbose("Kart", "Decreasing shield, because of removing the plunger."); } } // blockViewWithPlunger @@ -1088,7 +1089,7 @@ void Kart::update(float dt) // Update the position and other data taken from the physics Moveable::update(dt); - if(!history->replayHistory()) + if(!history->replayHistory() && !RewindManager::get()->isRewinding()) m_controller->update(dt); // if its view is blocked by plunger, decrease remaining time @@ -1362,7 +1363,7 @@ void Kart::setSquash(float time, float slowdown) if (isShielded()) { decreaseShieldTime(stk_config->m_bubblegum_shield_time/2.0f); - Log::verbose("Kart", "Decreasing shield \n"); + Log::verbose("Kart", "Decreasing shield"); return; } @@ -2043,7 +2044,7 @@ void Kart::updatePhysics(float dt) ); #endif -} // updatePhysics +} // updatephysics //----------------------------------------------------------------------------- /** Adjust the engine sound effect depending on the speed of the kart. diff --git a/src/karts/kart_rewinder.cpp b/src/karts/kart_rewinder.cpp index c832f78e6..c247676f9 100644 --- a/src/karts/kart_rewinder.cpp +++ b/src/karts/kart_rewinder.cpp @@ -93,7 +93,7 @@ void KartRewinder::update() m_previous_control.copyToMemory(buffer); // The rewind manager will free the memory once it's not needed anymore - RewindManager::get()->addEvent(this, World::getWorld()->getTime(), buffer); + RewindManager::get()->addEvent(this, buffer); } // update // ---------------------------------------------------------------------------- diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 38359763f..e4ca37654 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -827,11 +827,12 @@ void World::update(float dt) if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt); if(ReplayPlay::get()) ReplayPlay::get()->update(dt); if(history->replayHistory()) dt=history->getNextDelta(); - WorldStatus::update(dt); // Clear race state so that new information can be stored race_state->clear(); - RewindManager::get()->saveStates(dt); + RewindManager::get()->setCurrentTime(World::getWorld()->getTime(), dt); + RewindManager::get()->saveStates(); + WorldStatus::update(dt); if(network_manager->getMode()!=NetworkManager::NW_CLIENT && diff --git a/src/network/rewind_manager.cpp b/src/network/rewind_manager.cpp index f81e2b69c..356e4f288 100644 --- a/src/network/rewind_manager.cpp +++ b/src/network/rewind_manager.cpp @@ -49,12 +49,12 @@ void RewindManager::destroy() * for all state info. * \param size Necessary buffer size for a state. */ -RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time, - char *buffer, bool is_event, - bool is_confirmed) +RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, char *buffer, + bool is_event, bool is_confirmed) { m_rewinder = rewinder; - m_time = time; + m_time = RewindManager::get()->getCurrentTime();; + m_time_step = RewindManager::get()->getCurrentTimeStep(); m_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime(); m_buffer = buffer; m_type = is_event ? RIT_EVENT : RIT_STATE; @@ -62,10 +62,11 @@ RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time, } // RewindInfo // ---------------------------------------------------------------------------- -RewindManager::RewindInfo::RewindInfo(float time) +RewindManager::RewindInfo::RewindInfo() { m_rewinder = NULL; - m_time = time; + m_time = RewindManager::get()->getCurrentTime(); + m_time_step = RewindManager::get()->getCurrentTimeStep(); m_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime(); m_buffer = NULL; m_type = RIT_TIME; @@ -220,10 +221,10 @@ unsigned int RewindManager::findFirstIndex(float target_time) const * \param time Time at which the event was recorded. * \param buffer Pointer to the event data. */ -void RewindManager::addEvent(Rewinder *rewinder, float time, char *buffer) +void RewindManager::addEvent(Rewinder *rewinder, char *buffer) { if(m_is_rewinding) return; - RewindInfo *ri = new RewindInfo(rewinder, time, buffer, /*is_event*/true, + RewindInfo *ri = new RewindInfo(rewinder, buffer, /*is_event*/true, /*is_confirmed*/true); insertRewindInfo(ri); } // addEvent @@ -233,7 +234,7 @@ void RewindManager::addEvent(Rewinder *rewinder, float time, char *buffer) * rewinder to do so. * \param dt Time step size. */ -void RewindManager::saveStates(float dt) +void RewindManager::saveStates() { if(!m_enable_rewind_manager || m_all_rewinder.size()==0 || @@ -242,7 +243,7 @@ void RewindManager::saveStates(float dt) float time = World::getWorld()->getTime(); if(time - m_last_saved_state < m_state_frequency) { - RewindInfo *ri = new RewindInfo(World::getWorld()->getTime()); + RewindInfo *ri = new RewindInfo(); insertRewindInfo(ri); return; } @@ -255,7 +256,7 @@ void RewindManager::saveStates(float dt) if(size>=0) { m_overall_state_size += size; - RewindInfo *ri = new RewindInfo(m_all_rewinder[i], time, p, + RewindInfo *ri = new RewindInfo(m_all_rewinder[i], p, /*is_event*/false, /*is_confirmed*/true); assert(ri); @@ -324,11 +325,6 @@ void RewindManager::rewindTo(float rewind_time) // current time. // TODO: this assumes atm that all rewinder have a initial state // for 'current_time'!!! - while(m_rewind_info[state]->getTime()==exact_rewind_time) - { - m_rewind_info[state]->rewind(); - state ++; - } // while rewind info at time current_time // Store the time to which we have to replay to float current_time = World::getWorld()->getTime(); @@ -337,27 +333,15 @@ void RewindManager::rewindTo(float rewind_time) // Now go forward through the saved states, and // replay taking the events into account. - while(World::getWorld()->getTime() < current_time && - state < (int)m_rewind_info.size()) + while( World::getWorld()->getTime() < current_time && + state < (int)m_rewind_info.size() ) { - // Find the next RewindInfo which needs to be taken into account - // All other states can be deleted - // TODO ... for now - int next_important_state = state; - while(next_important_state < (int)m_rewind_info.size() && - m_rewind_info[next_important_state]->isState() && - !m_rewind_info[next_important_state]->isConfirmed() ) - { - // TODO discard/replace state - next_important_state ++; - } - float dt = determineTimeStepSize(state, current_time); - float next_time = World::getWorld()->getTime() + dt; + // Now set all events and confirmed states while(state < (int)m_rewind_info.size() && - m_rewind_info[state]->getTime() <= next_time) + m_rewind_info[state]->getTime()<=World::getWorld()->getTime()+0.001f) { if(m_rewind_info[state]->isEvent() || m_rewind_info[state]->isConfirmed() ) @@ -388,6 +372,8 @@ void RewindManager::rewindTo(float rewind_time) */ float RewindManager::determineTimeStepSize(int next_state, float end_time) { + return m_rewind_info[next_state]->getTimeStep(); + return m_rewind_info[next_state]->getTime()-World::getWorld()->getTime(); float dt = 1.0f/60.0f; diff --git a/src/network/rewind_manager.hpp b/src/network/rewind_manager.hpp index 99d146704..7847949e6 100644 --- a/src/network/rewind_manager.hpp +++ b/src/network/rewind_manager.hpp @@ -108,6 +108,9 @@ private: /** Time when this state was taken. */ float m_time; + /** Time step size. */ + float m_time_step; + /** The 'left over' time from the physics. */ float m_local_physics_time; @@ -122,10 +125,10 @@ private: /** The Rewinder instance for which this data is. */ Rewinder *m_rewinder; public: - RewindInfo(Rewinder *rewinder, float time, char *buffer, + RewindInfo(Rewinder *rewinder, char *buffer, bool is_event, bool is_confirmed); // -------------------------------------------------------------------- - RewindInfo(float time); + RewindInfo(); // -------------------------------------------------------------------- ~RewindInfo() { @@ -138,6 +141,9 @@ private: /** Returns the time at which this rewind state was saved. */ float getTime() const { return m_time; } // -------------------------------------------------------------------- + /** Time step size. */ + float getTimeStep() const { return m_time_step; } + // -------------------------------------------------------------------- bool isEvent() const { return m_type==RIT_EVENT; } // -------------------------------------------------------------------- bool isTime() const { return m_type==RIT_TIME; } @@ -203,6 +209,15 @@ private: /** Time at which the last state was saved. */ float m_last_saved_state; + /** The current time to be used in all states/events. This is used to + * give all states and events during one frame the same time, even + * if e.g. states are saved before world time is increased, other + * events later. */ + float m_current_time; + + /** The current time step size. */ + float m_time_step; + #define REWIND_SEARCH_STATS #ifdef REWIND_SEARCH_STATS @@ -223,6 +238,24 @@ public: static RewindManager *create(); static void destroy(); // ------------------------------------------------------------------------ + /** Sets the time that is to be used for all further states or events, + * and the time step size. This is necessary so that states/events before + * and after World::m_time is increased have the same time stamp. + * \param t Time. + * \param dt Time step size. + */ + void setCurrentTime(float t, float dt) + { + m_current_time = t; + m_time_step = dt; + } // setCurrentTime + + // ------------------------------------------------------------------------ + /** Returns the current time. */ + float getCurrentTime() const { return m_current_time; } + // ------------------------------------------------------------------------ + float getCurrentTimeStep() const { return m_time_step; } + // ------------------------------------------------------------------------ /** En- or disables rewinding. */ static void setEnable(bool m) { m_enable_rewind_manager = m;} @@ -242,7 +275,9 @@ public: // ------------------------------------------------------------------------ void reset(); - void saveStates(float dt); + void saveStates(); + void rewindTo(float target_time); + void addEvent(Rewinder *rewinder, char *buffer); // ------------------------------------------------------------------------ /** Adds a Rewinder to the list of all rewinders. * \return true If rewinding is enabled, false otherwise. @@ -254,9 +289,8 @@ public: return true; } // addRewinder // ------------------------------------------------------------------------ - void rewindTo(float target_time); - // ------------------------------------------------------------------------ - void addEvent(Rewinder *rewinder, float time, char *buffer); + /** Returns true if currently a rewind is happening. */ + bool isRewinding() const { return m_is_rewinding; } }; // RewindManager