Made the history files use events for players (will break physics replay
for AIs for now). Useful for network debugging.
This commit is contained in:
parent
c1a3d281f6
commit
373ec0f242
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "karts/controller/kart_control.hpp"
|
#include "karts/controller/kart_control.hpp"
|
||||||
|
|
||||||
|
#include "network/protocols/game_protocol.hpp"
|
||||||
#include "network/rewind_manager.hpp"
|
#include "network/rewind_manager.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -46,23 +47,6 @@ void KartControl::rewind(BareNetworkString *buffer)
|
|||||||
}
|
}
|
||||||
} // rewind
|
} // rewind
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
/** Sets this KartControl form the given value (basically a copy). This
|
|
||||||
* function uses the explicit setSteer() etc function, which means that
|
|
||||||
* rewind information will be collected.
|
|
||||||
*/
|
|
||||||
void KartControl::set(const KartControl &c)
|
|
||||||
{
|
|
||||||
setAccel(c.getAccel());
|
|
||||||
setBrake(c.getBrake());
|
|
||||||
setFire(c.getFire());
|
|
||||||
setLookBack(c.getLookBack());
|
|
||||||
setNitro(c.getNitro());
|
|
||||||
setRescue(c.getRescue());
|
|
||||||
setSkidControl(c.getSkidControl());
|
|
||||||
setSteer(c.getSteer());
|
|
||||||
} // set
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the current steering value. */
|
/** Sets the current steering value. */
|
||||||
void KartControl::setSteer(float f)
|
void KartControl::setSteer(float f)
|
||||||
|
@ -61,7 +61,6 @@ public:
|
|||||||
void setRescue(bool b);
|
void setRescue(bool b);
|
||||||
void setFire(bool b);
|
void setFire(bool b);
|
||||||
void setLookBack(bool b);
|
void setLookBack(bool b);
|
||||||
void set(const KartControl &c);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
KartControl()
|
KartControl()
|
||||||
|
@ -149,6 +149,10 @@ bool LocalPlayerController::action(PlayerAction action, int value,
|
|||||||
// optimises traffic to the server and other clients.
|
// optimises traffic to the server and other clients.
|
||||||
if (!PlayerController::action(action, value, /*dry_run*/true)) return false;
|
if (!PlayerController::action(action, value, /*dry_run*/true)) return false;
|
||||||
|
|
||||||
|
// Register event with history
|
||||||
|
if(!history->replayHistory())
|
||||||
|
history->addEvent(m_kart->getWorldKartId(), action, value);
|
||||||
|
|
||||||
// If this is a client, send the action to networking layer
|
// If this is a client, send the action to networking layer
|
||||||
if (World::getWorld()->isNetworkWorld() &&
|
if (World::getWorld()->isNetworkWorld() &&
|
||||||
NetworkConfig::get()->isClient() &&
|
NetworkConfig::get()->isClient() &&
|
||||||
|
@ -318,7 +318,7 @@ void PlayerController::update(float dt)
|
|||||||
// Don't do steering if it's replay. In position only replay it doesn't
|
// Don't do steering if it's replay. In position only replay it doesn't
|
||||||
// matter, but if it's physics replay the gradual steering causes
|
// matter, but if it's physics replay the gradual steering causes
|
||||||
// incorrect results, since the stored values are already adjusted.
|
// incorrect results, since the stored values are already adjusted.
|
||||||
if (!history->replayHistory())
|
if (!history->replayHistory() || !history->dontDoPhysics())
|
||||||
steer(dt, m_steer_val);
|
steer(dt, m_steer_val);
|
||||||
|
|
||||||
if (World::getWorld()->getPhase() == World::GOAL_PHASE)
|
if (World::getWorld()->getPhase() == World::GOAL_PHASE)
|
||||||
|
@ -1262,7 +1262,7 @@ void Kart::update(float dt)
|
|||||||
// is used furthermore for engine power, camera distance etc
|
// is used furthermore for engine power, camera distance etc
|
||||||
updateSpeed();
|
updateSpeed();
|
||||||
|
|
||||||
if(!history->replayHistory())
|
if(!history->replayHistory() || !history->dontDoPhysics())
|
||||||
m_controller->update(dt);
|
m_controller->update(dt);
|
||||||
|
|
||||||
#undef DEBUG_CAMERA_SHAKE
|
#undef DEBUG_CAMERA_SHAKE
|
||||||
|
@ -1272,6 +1272,7 @@ int handleCmdLine()
|
|||||||
history->doReplayHistory( (History::HistoryReplayMode)n);
|
history->doReplayHistory( (History::HistoryReplayMode)n);
|
||||||
// Force the no-start screen flag, since this initialises
|
// Force the no-start screen flag, since this initialises
|
||||||
// the player structures correctly.
|
// the player structures correctly.
|
||||||
|
if(!MainMenuScreen::m_enable_online)
|
||||||
UserConfigParams::m_no_start_screen = true;
|
UserConfigParams::m_no_start_screen = true;
|
||||||
} // --history=%d
|
} // --history=%d
|
||||||
|
|
||||||
@ -1780,13 +1781,17 @@ int main(int argc, char *argv[] )
|
|||||||
{
|
{
|
||||||
// This will setup the race manager etc.
|
// This will setup the race manager etc.
|
||||||
history->Load();
|
history->Load();
|
||||||
|
if (!MainMenuScreen::m_enable_online)
|
||||||
|
{
|
||||||
race_manager->setupPlayerKartInfo();
|
race_manager->setupPlayerKartInfo();
|
||||||
race_manager->startNew(false);
|
race_manager->startNew(false);
|
||||||
main_loop->run();
|
main_loop->run();
|
||||||
// well, actually run() will never return, since
|
// well, actually run() will never return, since
|
||||||
// it exits after replaying history (see history::GetNextDT()).
|
// it either loops or exits after replaying history (see
|
||||||
|
// history::updateReplayAndGetDT()).
|
||||||
// So the next line is just to make this obvious here!
|
// So the next line is just to make this obvious here!
|
||||||
exit(-3);
|
exit(-3);
|
||||||
|
} // if !online
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not replaying
|
// Not replaying
|
||||||
|
@ -64,13 +64,6 @@ MainLoop::~MainLoop()
|
|||||||
float MainLoop::getLimitedDt()
|
float MainLoop::getLimitedDt()
|
||||||
{
|
{
|
||||||
float dt = 0;
|
float dt = 0;
|
||||||
// If we are doing a replay, use the dt from the history file
|
|
||||||
if (World::getWorld() && history->replayHistory() )
|
|
||||||
{
|
|
||||||
dt = history->updateReplayAndGetDT();
|
|
||||||
return dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// In profile mode without graphics, run with a fixed dt of 1/60
|
// In profile mode without graphics, run with a fixed dt of 1/60
|
||||||
if ((ProfileWorld::isProfileMode() && ProfileWorld::isNoGraphics()) ||
|
if ((ProfileWorld::isProfileMode() && ProfileWorld::isNoGraphics()) ||
|
||||||
@ -155,6 +148,14 @@ float MainLoop::getLimitedDt()
|
|||||||
{
|
{
|
||||||
dt = World::getWorld()->adjustDT(dt);
|
dt = World::getWorld()->adjustDT(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are doing a replay, use the dt from the history file if this
|
||||||
|
// is not networked, otherwise history will use current time and dt
|
||||||
|
// to findout which events to replay
|
||||||
|
if (World::getWorld() && history->replayHistory() )
|
||||||
|
{
|
||||||
|
dt = history->updateReplayAndGetDT(World::getWorld()->getTime(), dt);
|
||||||
|
}
|
||||||
return dt;
|
return dt;
|
||||||
} // getLimitedDt
|
} // getLimitedDt
|
||||||
|
|
||||||
|
@ -211,7 +211,6 @@ void RewindManager::update(float dt)
|
|||||||
PROFILER_PUSH_CPU_MARKER("RewindManager - send state", 0x20, 0x7F, 0x40);
|
PROFILER_PUSH_CPU_MARKER("RewindManager - send state", 0x20, 0x7F, 0x40);
|
||||||
GameProtocol::getInstance()->sendState();
|
GameProtocol::getInstance()->sendState();
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
m_last_saved_state = time;
|
m_last_saved_state = time;
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
@ -241,6 +240,7 @@ void RewindManager::playEventsTill(float time, float *dt)
|
|||||||
Log::setPrefix("");
|
Log::setPrefix("");
|
||||||
TimeStepInfo *tsi = m_rewind_queue.getCurrent();
|
TimeStepInfo *tsi = m_rewind_queue.getCurrent();
|
||||||
World::getWorld()->setTime(tsi->getTime());
|
World::getWorld()->setTime(tsi->getTime());
|
||||||
|
Physics::getInstance()->getPhysicsWorld()->resetLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is necessary to avoid that rewinding an event will store the
|
// This is necessary to avoid that rewinding an event will store the
|
||||||
@ -275,6 +275,7 @@ void RewindManager::playEventsTill(float time, float *dt)
|
|||||||
void RewindManager::rewindTo(float rewind_time)
|
void RewindManager::rewindTo(float rewind_time)
|
||||||
{
|
{
|
||||||
assert(!m_is_rewinding);
|
assert(!m_is_rewinding);
|
||||||
|
bool is_history = history->replayHistory();
|
||||||
history->doReplayHistory(History::HISTORY_NONE);
|
history->doReplayHistory(History::HISTORY_NONE);
|
||||||
|
|
||||||
// First save all current transforms so that the error
|
// First save all current transforms so that the error
|
||||||
@ -316,6 +317,7 @@ void RewindManager::rewindTo(float rewind_time)
|
|||||||
if (World::getWorld()->getPhase() == WorldStatus::IN_GAME_MENU_PHASE)
|
if (World::getWorld()->getPhase() == WorldStatus::IN_GAME_MENU_PHASE)
|
||||||
{
|
{
|
||||||
m_is_rewinding = false;
|
m_is_rewinding = false;
|
||||||
|
history->doReplayHistory(History::HISTORY_PHYSICS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,8 +353,8 @@ void RewindManager::rewindTo(float rewind_time)
|
|||||||
{
|
{
|
||||||
(*rewinder)->computeError();
|
(*rewinder)->computeError();
|
||||||
}
|
}
|
||||||
|
if(is_history)
|
||||||
|
history->doReplayHistory(History::HISTORY_PHYSICS);
|
||||||
m_is_rewinding = false;
|
m_is_rewinding = false;
|
||||||
} // rewindTo
|
} // rewindTo
|
||||||
|
|
||||||
|
@ -23,9 +23,12 @@
|
|||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "karts/controller/controller.hpp"
|
||||||
|
#include "network/network_config.hpp"
|
||||||
#include "network/rewind_manager.hpp"
|
#include "network/rewind_manager.hpp"
|
||||||
#include "physics/physics.hpp"
|
#include "physics/physics.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
|
#include "states_screens/main_menu_screen.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "utils/constants.hpp"
|
#include "utils/constants.hpp"
|
||||||
|
|
||||||
@ -37,16 +40,9 @@ History* history = 0;
|
|||||||
History::History()
|
History::History()
|
||||||
{
|
{
|
||||||
m_replay_mode = HISTORY_NONE;
|
m_replay_mode = HISTORY_NONE;
|
||||||
|
m_history_time = 0.0f;
|
||||||
} // History
|
} // History
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** Starts replay from the history file in the current directory.
|
|
||||||
*/
|
|
||||||
void History::startReplay()
|
|
||||||
{
|
|
||||||
Load();
|
|
||||||
} // startReplay
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Initialise the history for a new recording. It especially allocates memory
|
/** Initialise the history for a new recording. It especially allocates memory
|
||||||
* to store the history.
|
* to store the history.
|
||||||
@ -57,6 +53,7 @@ void History::initRecording()
|
|||||||
/ stk_config->m_replay_dt );
|
/ stk_config->m_replay_dt );
|
||||||
allocateMemory(max_frames);
|
allocateMemory(max_frames);
|
||||||
m_current = -1;
|
m_current = -1;
|
||||||
|
m_event_index = 0;
|
||||||
m_wrapped = false;
|
m_wrapped = false;
|
||||||
m_size = 0;
|
m_size = 0;
|
||||||
} // initRecording
|
} // initRecording
|
||||||
@ -75,6 +72,24 @@ void History::allocateMemory(int number_of_frames)
|
|||||||
m_all_rotations.resize(number_of_frames*num_karts);
|
m_all_rotations.resize(number_of_frames*num_karts);
|
||||||
} // allocateMemory
|
} // allocateMemory
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Stores an input event (e.g. acceleration or steering event) into the
|
||||||
|
* history data for physics replay.
|
||||||
|
* \param kart_id The kart index which triggered the event.
|
||||||
|
* \param pa The action.
|
||||||
|
* \param value Value of the action (0=release, 32768 = pressed), in
|
||||||
|
* between in case of analog devices.
|
||||||
|
*/
|
||||||
|
void History::addEvent(int kart_id, PlayerAction pa, int value)
|
||||||
|
{
|
||||||
|
InputEvent ie;
|
||||||
|
ie.m_index = m_current;
|
||||||
|
ie.m_action = pa;
|
||||||
|
ie.m_value = value;
|
||||||
|
ie.m_kart_index = kart_id;
|
||||||
|
m_all_input_events.emplace_back(ie);
|
||||||
|
} // addEvent
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Saves the current history.
|
/** Saves the current history.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
@ -109,16 +124,21 @@ void History::updateSaving(float dt)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Sets the kart position and controls to the recorded history value.
|
/** Sets the kart position and controls to the recorded history value.
|
||||||
* \param dt Time step size.
|
* \return dt Time step size.
|
||||||
*/
|
*/
|
||||||
float History::updateReplayAndGetDT()
|
float History::updateReplayAndGetDT(float world_time, float dt)
|
||||||
|
{
|
||||||
|
if (m_history_time >= world_time) return dt;
|
||||||
|
World *world = World::getWorld();
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
m_current++;
|
m_current++;
|
||||||
World *world = World::getWorld();
|
|
||||||
if (m_current >= (int)m_all_deltas.size())
|
if (m_current >= (int)m_all_deltas.size())
|
||||||
{
|
{
|
||||||
Log::info("History", "Replay finished");
|
Log::info("History", "Replay finished");
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
|
m_history_time = 0;
|
||||||
// This is useful to use a reproducable rewind problem:
|
// This is useful to use a reproducable rewind problem:
|
||||||
// replay it with history, for debugging only
|
// replay it with history, for debugging only
|
||||||
#undef DO_REWIND_AT_END_OF_HISTORY
|
#undef DO_REWIND_AT_END_OF_HISTORY
|
||||||
@ -131,6 +151,7 @@ float History::updateReplayAndGetDT()
|
|||||||
world->reset();
|
world->reset();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int num_karts = world->getNumKarts();
|
unsigned int num_karts = world->getNumKarts();
|
||||||
for (unsigned k = 0; k < num_karts; k++)
|
for (unsigned k = 0; k < num_karts; k++)
|
||||||
{
|
{
|
||||||
@ -141,12 +162,32 @@ float History::updateReplayAndGetDT()
|
|||||||
kart->setXYZ(m_all_xyz[index]);
|
kart->setXYZ(m_all_xyz[index]);
|
||||||
kart->setRotation(m_all_rotations[index]);
|
kart->setRotation(m_all_rotations[index]);
|
||||||
}
|
}
|
||||||
else
|
else // HISTORY_PHYSICS
|
||||||
{
|
{
|
||||||
kart->getControls().set(m_all_controls[index]);
|
while (m_event_index < m_all_input_events.size() &&
|
||||||
|
m_all_input_events[m_event_index].m_index == m_current)
|
||||||
|
{
|
||||||
|
const InputEvent &ie = m_all_input_events[m_event_index];
|
||||||
|
AbstractKart *kart = world->getKart(ie.m_kart_index);
|
||||||
|
kart->getController()->action(ie.m_action, ie.m_value);
|
||||||
|
m_event_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//kart->getControls().set(m_all_controls[index]);
|
||||||
}
|
}
|
||||||
|
} // for k < num_karts
|
||||||
|
|
||||||
|
m_history_time += m_all_deltas[m_current];
|
||||||
|
|
||||||
|
// If this is not networked, exit the loop after one iteration
|
||||||
|
// and return the new dt
|
||||||
|
if(!NetworkConfig::get()->isNetworking())
|
||||||
return m_all_deltas[m_current];
|
return m_all_deltas[m_current];
|
||||||
|
|
||||||
|
} while (m_history_time < world_time + dt);
|
||||||
|
|
||||||
|
// In network mode, don't adjust dt, just return the input value
|
||||||
|
return dt;
|
||||||
} // updateReplayAndGetDT
|
} // updateReplayAndGetDT
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -175,7 +216,7 @@ void History::Save()
|
|||||||
|
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
const int num_karts = world->getNumKarts();
|
const int num_karts = world->getNumKarts();
|
||||||
fprintf(fd, "Version: %s\n", STK_VERSION);
|
fprintf(fd, "Version-1: %s\n", STK_VERSION);
|
||||||
fprintf(fd, "numkarts: %d\n", num_karts);
|
fprintf(fd, "numkarts: %d\n", num_karts);
|
||||||
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
|
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
|
||||||
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
||||||
@ -199,24 +240,42 @@ void History::Save()
|
|||||||
index=(index+1)%m_size;
|
index=(index+1)%m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = num_karts * (m_wrapped ? m_current : 0);
|
index = m_wrapped ? m_current : 0;
|
||||||
|
int event_index = 0;
|
||||||
for(int i=0; i<m_size; i++)
|
for(int i=0; i<m_size; i++)
|
||||||
{
|
{
|
||||||
|
int base_index = index * num_karts;
|
||||||
for(int k=0; k<num_karts; k++)
|
for(int k=0; k<num_karts; k++)
|
||||||
{
|
{
|
||||||
fprintf(fd, "%f %f %d %f %f %f %f %f %f %f\n",
|
fprintf(fd, "%f %f %d %f %f %f %f %f %f %f\n",
|
||||||
m_all_controls[index+k].getSteer(),
|
m_all_controls[base_index+k].getSteer(),
|
||||||
m_all_controls[index+k].getAccel(),
|
m_all_controls[base_index+k].getAccel(),
|
||||||
m_all_controls[index+k].getButtonsCompressed(),
|
m_all_controls[base_index+k].getButtonsCompressed(),
|
||||||
m_all_xyz[index+k].getX(), m_all_xyz[index+k].getY(),
|
m_all_xyz[base_index+k].getX(), m_all_xyz[base_index+k].getY(),
|
||||||
m_all_xyz[index+k].getZ(),
|
m_all_xyz[base_index+k].getZ(),
|
||||||
m_all_rotations[index+k].getX(),
|
m_all_rotations[base_index+k].getX(),
|
||||||
m_all_rotations[index+k].getY(),
|
m_all_rotations[base_index+k].getY(),
|
||||||
m_all_rotations[index+k].getZ(),
|
m_all_rotations[base_index+k].getZ(),
|
||||||
m_all_rotations[index+k].getW() );
|
m_all_rotations[base_index+k].getW() );
|
||||||
} // for i
|
|
||||||
index=(index+num_karts)%(num_karts*m_size);
|
|
||||||
} // for k
|
} // for k
|
||||||
|
// Find number of events for this frame
|
||||||
|
int count = 0;
|
||||||
|
while ( event_index+count < (int)m_all_input_events.size() &&
|
||||||
|
m_all_input_events[event_index+count].m_index == index )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
fprintf(fd, "%d\n", count);
|
||||||
|
for (int k = 0; k < count; k++)
|
||||||
|
{
|
||||||
|
fprintf(fd, "%d %d %d\n",
|
||||||
|
m_all_input_events[event_index].m_kart_index,
|
||||||
|
m_all_input_events[event_index].m_action,
|
||||||
|
m_all_input_events[event_index].m_value);
|
||||||
|
event_index++;
|
||||||
|
}
|
||||||
|
index=(index+1)%m_size;
|
||||||
|
} // for i
|
||||||
fprintf(fd, "History file end.\n");
|
fprintf(fd, "History file end.\n");
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
} // Save
|
} // Save
|
||||||
@ -245,10 +304,18 @@ void History::Load()
|
|||||||
if (fgets(s, 1023, fd) == NULL)
|
if (fgets(s, 1023, fd) == NULL)
|
||||||
Log::fatal("History", "Could not read history.dat.");
|
Log::fatal("History", "Could not read history.dat.");
|
||||||
|
|
||||||
if (sscanf(s,"Version: %1023s",s1)!=1)
|
int version = 0;
|
||||||
Log::fatal("History", "No Version information found in history file (bogus history file).");
|
if (sscanf(s, "Version-1: %1023s", s1) == 1)
|
||||||
else if (strcmp(s1,STK_VERSION))
|
version = 1;
|
||||||
Log::warn("History", "History is version '%s', STK version is '%s'.", s1, STK_VERSION);
|
else if (sscanf(s,"Version: %1023s",s1)!=1)
|
||||||
|
Log::fatal("History", "No Version information found in history "
|
||||||
|
"file (bogus history file).");
|
||||||
|
if (strcmp(s1,STK_VERSION))
|
||||||
|
Log::warn("History", "History is version '%s', STK version is '%s'.",
|
||||||
|
s1, STK_VERSION);
|
||||||
|
if (version != 1)
|
||||||
|
Log::fatal("History",
|
||||||
|
"Old-style history files are not supported anymore.");
|
||||||
|
|
||||||
if (fgets(s, 1023, fd) == NULL)
|
if (fgets(s, 1023, fd) == NULL)
|
||||||
Log::fatal("History", "Could not read history.dat.");
|
Log::fatal("History", "Could not read history.dat.");
|
||||||
@ -292,7 +359,7 @@ void History::Load()
|
|||||||
if(sscanf(s, "model %d: %1023s",&n, s1) != 2)
|
if(sscanf(s, "model %d: %1023s",&n, s1) != 2)
|
||||||
Log::fatal("History", "No model information for kart %d found.", i);
|
Log::fatal("History", "No model information for kart %d found.", i);
|
||||||
m_kart_ident.push_back(s1);
|
m_kart_ident.push_back(s1);
|
||||||
if(i<race_manager->getNumPlayers())
|
if(i<race_manager->getNumPlayers() && !MainMenuScreen::m_enable_online)
|
||||||
{
|
{
|
||||||
race_manager->setPlayerKart(i, s1);
|
race_manager->setPlayerKart(i, s1);
|
||||||
}
|
}
|
||||||
@ -304,6 +371,7 @@ void History::Load()
|
|||||||
|
|
||||||
allocateMemory(m_size);
|
allocateMemory(m_size);
|
||||||
m_current = -1;
|
m_current = -1;
|
||||||
|
m_event_index = 0;
|
||||||
|
|
||||||
for(int i=0; i<m_size; i++)
|
for(int i=0; i<m_size; i++)
|
||||||
{
|
{
|
||||||
@ -315,7 +383,7 @@ void History::Load()
|
|||||||
// KartControl data would access the rewind manager).
|
// KartControl data would access the rewind manager).
|
||||||
bool rewind_manager_was_enabled = RewindManager::isEnabled();
|
bool rewind_manager_was_enabled = RewindManager::isEnabled();
|
||||||
RewindManager::setEnable(false);
|
RewindManager::setEnable(false);
|
||||||
|
m_all_input_events.clear();
|
||||||
for(int i=0; i<m_size; i++)
|
for(int i=0; i<m_size; i++)
|
||||||
{
|
{
|
||||||
for(unsigned int k=0; k<num_karts; k++)
|
for(unsigned int k=0; k<num_karts; k++)
|
||||||
@ -334,8 +402,24 @@ void History::Load()
|
|||||||
m_all_xyz[index] = Vec3(x,y,z);
|
m_all_xyz[index] = Vec3(x,y,z);
|
||||||
m_all_rotations[index] = btQuaternion(rx,ry,rz,rw);
|
m_all_rotations[index] = btQuaternion(rx,ry,rz,rw);
|
||||||
m_all_controls[index].setButtonsCompressed(char(buttonsCompressed));
|
m_all_controls[index].setButtonsCompressed(char(buttonsCompressed));
|
||||||
} // for i
|
|
||||||
} // for k
|
} // for k
|
||||||
|
fgets(s, 1023, fd);
|
||||||
|
int count;
|
||||||
|
if (sscanf(s, "%d\n", &count) != 1)
|
||||||
|
Log::warn("History", "Problems reading event count: '%s'.", s);
|
||||||
|
for (int k = 0; k < count; k++)
|
||||||
|
{
|
||||||
|
fgets(s, 1023, fd);
|
||||||
|
InputEvent ie;
|
||||||
|
ie.m_index = i;
|
||||||
|
if (sscanf(s, "%d %d %d\n", &ie.m_kart_index, &ie.m_action,
|
||||||
|
&ie.m_value) != 3)
|
||||||
|
{
|
||||||
|
Log::warn("History", "Problems reading event: '%s'", s);
|
||||||
|
}
|
||||||
|
m_all_input_events.emplace_back(ie);
|
||||||
|
} // for k < count
|
||||||
|
} // for i
|
||||||
RewindManager::setEnable(rewind_manager_was_enabled);
|
RewindManager::setEnable(rewind_manager_was_enabled);
|
||||||
|
|
||||||
fprintf(fd, "History file end.\n");
|
fprintf(fd, "History file end.\n");
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "LinearMath/btQuaternion.h"
|
#include "LinearMath/btQuaternion.h"
|
||||||
|
|
||||||
|
#include "input/input.hpp"
|
||||||
#include "karts/controller/kart_control.hpp"
|
#include "karts/controller/kart_control.hpp"
|
||||||
#include "utils/aligned_array.hpp"
|
#include "utils/aligned_array.hpp"
|
||||||
#include "utils/vec3.hpp"
|
#include "utils/vec3.hpp"
|
||||||
@ -53,6 +54,9 @@ private:
|
|||||||
/** Points to the last used entry, and will wrap around. */
|
/** Points to the last used entry, and will wrap around. */
|
||||||
int m_current;
|
int m_current;
|
||||||
|
|
||||||
|
/** Points to the last used input event index. */
|
||||||
|
unsigned int m_event_index;
|
||||||
|
|
||||||
/** True if the buffer has wrapped around. */
|
/** True if the buffer has wrapped around. */
|
||||||
bool m_wrapped;
|
bool m_wrapped;
|
||||||
|
|
||||||
@ -67,6 +71,10 @@ private:
|
|||||||
/** Stores the kart controls being used (for physics replay). */
|
/** Stores the kart controls being used (for physics replay). */
|
||||||
std::vector<KartControl> m_all_controls;
|
std::vector<KartControl> m_all_controls;
|
||||||
|
|
||||||
|
/** For networking: keep track of the replay time so that the
|
||||||
|
* right event can be replayed. */
|
||||||
|
float m_history_time;
|
||||||
|
|
||||||
/** Stores the coordinates (for simple replay). */
|
/** Stores the coordinates (for simple replay). */
|
||||||
AlignedArray<Vec3> m_all_xyz;
|
AlignedArray<Vec3> m_all_xyz;
|
||||||
|
|
||||||
@ -76,15 +84,32 @@ private:
|
|||||||
/** The identities of the karts to use. */
|
/** The identities of the karts to use. */
|
||||||
std::vector<std::string> m_kart_ident;
|
std::vector<std::string> m_kart_ident;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
struct InputEvent
|
||||||
|
{
|
||||||
|
/** Index at which the even happened. */
|
||||||
|
int m_index;
|
||||||
|
/** For which kart the event was. */
|
||||||
|
int m_kart_index;
|
||||||
|
/** Which action it was. */
|
||||||
|
PlayerAction m_action;
|
||||||
|
/** The value to use. */
|
||||||
|
int m_value;
|
||||||
|
}; // InputEvent
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** All input events. */
|
||||||
|
std::vector<InputEvent> m_all_input_events;
|
||||||
|
|
||||||
void allocateMemory(int number_of_frames);
|
void allocateMemory(int number_of_frames);
|
||||||
public:
|
public:
|
||||||
History ();
|
History ();
|
||||||
void startReplay ();
|
|
||||||
void initRecording ();
|
void initRecording ();
|
||||||
void Save ();
|
void Save ();
|
||||||
void Load ();
|
void Load ();
|
||||||
void updateSaving(float dt);
|
void updateSaving(float dt);
|
||||||
float updateReplayAndGetDT();
|
float updateReplayAndGetDT(float time, float dt);
|
||||||
|
void addEvent(int kart_id, PlayerAction pa, int value);
|
||||||
|
|
||||||
// -------------------I-----------------------------------------------------
|
// -------------------I-----------------------------------------------------
|
||||||
/** Returns the identifier of the n-th kart. */
|
/** Returns the identifier of the n-th kart. */
|
||||||
|
Loading…
Reference in New Issue
Block a user