Rerecording: Wind back the frame counter in the status bar when a save state is loaded. Issues: The frame updates do currently not occur as often as the input updates. The input updates occur more frequently, perhaps closer to 60 times per real seconds.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2274 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
718aa585e2
commit
9afd7fb620
|
@ -91,11 +91,17 @@ s64 Timer::GetTimeDifference(void)
|
|||
return(timeGetTime() - m_LastTime);
|
||||
}
|
||||
|
||||
// Add the time difference since the last Update() to the starting time
|
||||
/* Add the time difference since the last Update() to the starting time. This is used to compensate
|
||||
for a paused game. */
|
||||
void Timer::AddTimeDifference()
|
||||
{
|
||||
m_StartTime += GetTimeDifference();
|
||||
}
|
||||
// Wind back the starting time to a custom time
|
||||
void Timer::WindBackStartingTime(u64 WindBack)
|
||||
{
|
||||
m_StartTime += WindBack;
|
||||
}
|
||||
|
||||
// Get the time elapsed since the Start()
|
||||
u64 Timer::GetTimeElapsed(void)
|
||||
|
|
|
@ -36,6 +36,7 @@ class Timer
|
|||
// The time difference is always returned in milliseconds, regardless of alternative internal representation
|
||||
s64 GetTimeDifference(void);
|
||||
void AddTimeDifference();
|
||||
void WindBackStartingTime(u64 WindBack);
|
||||
|
||||
static void IncreaseResolution();
|
||||
static void RestoreResolution();
|
||||
|
@ -44,7 +45,7 @@ class Timer
|
|||
|
||||
static std::string GetTimeFormatted();
|
||||
std::string GetTimeElapsedFormatted();
|
||||
u64 Timer::GetTimeElapsed();
|
||||
u64 GetTimeElapsed();
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ namespace Core
|
|||
void WriteStatus();
|
||||
void RerecordingStart();
|
||||
void RerecordingStop();
|
||||
void WindBack(int Counter);
|
||||
extern int g_FrameCounter;
|
||||
extern bool g_FrameStep;
|
||||
#endif
|
||||
|
|
|
@ -125,6 +125,40 @@ void RerecordingStop()
|
|||
// Update status bar
|
||||
WriteStatus();
|
||||
}
|
||||
|
||||
/* Wind back the frame counter when a save state is loaded. Currently we don't know what that means in
|
||||
time so we just guess that the time is proportional the the number of frames
|
||||
|
||||
Todo: There are many assumptions here: We probably want to replace the time here by the actual time
|
||||
that we save together with the save state or the input recording for example. And have it adjusted
|
||||
for full speed playback (whether it's 30 fps or 60 fps or some other speed that the game is natively
|
||||
capped at). Also the input interrupts do not occur as often as the frame renderings, they occur more
|
||||
often. So we may want to move the input recording to fram updates, or perhaps sync the input interrupts
|
||||
to frame updates.
|
||||
*/
|
||||
void WindBack(int Counter)
|
||||
{
|
||||
/* Counter should be smaller than g_FrameCounter, however it currently updates faster than the
|
||||
frames so currently it may not be the same. Therefore I use the abs() function. */
|
||||
int AbsoluteFrameDifference = abs(g_FrameCounter - Counter);
|
||||
float FractionalFrameDifference = (float) AbsoluteFrameDifference / (float) g_FrameCounter;
|
||||
|
||||
// Update the frame counter
|
||||
g_FrameCounter = Counter;
|
||||
|
||||
// Approximate a time to wind back the clock to
|
||||
// Get the current time
|
||||
u64 CurrentTimeMs = ReRecTimer.GetTimeElapsed();
|
||||
// Save the current time in seconds in a new double
|
||||
double CurrentTimeSeconds = (double) (CurrentTimeMs / 1000);
|
||||
// Reduce it by the same proportion as the counter was wound back
|
||||
CurrentTimeSeconds = CurrentTimeSeconds * FractionalFrameDifference;
|
||||
// Update the clock
|
||||
ReRecTimer.WindBackStartingTime((u64)CurrentTimeSeconds * 1000);
|
||||
|
||||
// Logging
|
||||
Console::Print("WindBack: %i %u\n", Counter, (u64)CurrentTimeSeconds);
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -191,6 +225,9 @@ void FrameUpdate()
|
|||
{
|
||||
// Write to the status bar
|
||||
WriteStatus();
|
||||
/* I don't think the frequent update has any material speed inpact at all, but should it
|
||||
have you can controls the update speed by changing the "% 10" in this line */
|
||||
//if (g_FrameCounter % 10 == 0) WriteStatus();
|
||||
|
||||
// Pause if frame stepping is on
|
||||
if(g_FrameStep)
|
||||
|
|
|
@ -193,6 +193,14 @@ int abc = 0;
|
|||
//Console::Print("WIIMOTE_RECONNECT\n");
|
||||
Core::ReconnectWiimote();
|
||||
return 0;
|
||||
|
||||
#ifdef RERECORDING
|
||||
case INPUT_FRAME_COUNTER:
|
||||
// Wind back the frame counter after a save state has been loaded
|
||||
Core::WindBack((int)lParam);
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
break;
|
||||
//default:
|
||||
|
|
|
@ -27,7 +27,8 @@ enum PLUGIN_COMM
|
|||
OPENGL_WM_USER_STOP = 10,
|
||||
OPENGL_WM_USER_CREATE,
|
||||
NJOY_RELOAD, // Reload nJoy if DirectInput has failed
|
||||
WIIMOTE_RECONNECT // Reconnect the Wiimote if it has disconnected
|
||||
WIIMOTE_RECONNECT, // Reconnect the Wiimote if it has disconnected
|
||||
INPUT_FRAME_COUNTER // Wind back the frame counter for rerecording
|
||||
};
|
||||
///////////////////////////////
|
||||
|
||||
|
|
|
@ -686,9 +686,22 @@ void Initialize(void *init)
|
|||
|
||||
void DoState(unsigned char **ptr, int mode)
|
||||
{
|
||||
#ifdef RERECORDING
|
||||
// Load or save the counter
|
||||
PointerWrap p(ptr, mode);
|
||||
p.Do(count);
|
||||
|
||||
//Console::Print("count: %i\n", count);
|
||||
|
||||
// Update the frame counter for the sake of the status bar
|
||||
if (mode == PointerWrap::MODE_READ)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// This only works when rendering to the main window, I think
|
||||
PostMessage(GetParent(g_PADInitialize.hWnd), WM_USER, INPUT_FRAME_COUNTER, count);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
|
Loading…
Reference in New Issue