From d7bda211fd3cc7ad8c93146ffaa2c8597b798800 Mon Sep 17 00:00:00 2001 From: smelenchuk Date: Tue, 15 Feb 2011 17:03:20 +0000 Subject: [PATCH] Have playback of input files stop upon reaching the frame count designated in the header, preventing that number from being tampered with and assisting in recording verifiability. Adjusted the "resume recording from end of playback" code to account for playback stopping in the middle of a movie as above. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7176 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/OnFrame.cpp | 41 ++++++++++++++---------- Source/Core/Core/Src/OnFrame.h | 2 +- Source/Core/Core/Src/State.cpp | 2 +- Source/Core/DolphinWX/Src/FrameTools.cpp | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Source/Core/Core/Src/OnFrame.cpp b/Source/Core/Core/Src/OnFrame.cpp index 0b84e9cb3e..189855c6b5 100644 --- a/Source/Core/Core/Src/OnFrame.cpp +++ b/Source/Core/Core/Src/OnFrame.cpp @@ -50,19 +50,21 @@ unsigned int g_framesToSkip = 0, g_frameSkipCounter = 0; int g_numPads = 0; ControllerState g_padState; -char g_playingFile[256] = "\0"; FILE *g_recordfd = NULL; -u64 g_frameCounter = 0, g_lagCounter = 0; +u64 g_frameCounter = 0, g_lagCounter = 0, g_totalFrameCount = 0; bool g_bRecordingFromSaveState = false; bool g_bPolled = false; int g_numRerecords = 0; std::string g_recordFile = "0.dtm"; +std::string g_tmpRecordFile = "1.dtm"; void FrameUpdate() { g_frameCounter++; + if (IsRecordingInput()) + g_totalFrameCount = g_frameCounter; if(!g_bPolled) g_lagCounter++; @@ -314,12 +316,11 @@ bool PlayInput(const char *filename) g_numPads = header.numControllers; g_numRerecords = header.numRerecords; + g_totalFrameCount = header.frameCount; ChangePads(); g_playMode = MODE_PLAYING; - - strncpy(g_playingFile, filename, 256); return true; @@ -341,8 +342,7 @@ void LoadInput(const char *filename) if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A) { PanicAlertT("Savestate movie %s is corrupted, movie recording stopping...", filename); - strncpy(g_playingFile, "\0", 256); - EndPlayInput(); + EndPlayInput(false); return; } @@ -350,6 +350,7 @@ void LoadInput(const char *filename) g_rerecords = header.numRerecords; g_frameCounter = header.frameCount; + g_totalFrameCount = header.frameCount; g_numPads = header.numControllers; @@ -425,10 +426,10 @@ void PlayController(SPADStatus *PadStatus, int controllerID) PadStatus->substickX = g_padState.CStickX; PadStatus->substickY = g_padState.CStickY; - if(feof(g_recordfd)) + if(feof(g_recordfd) || g_frameCounter >= g_totalFrameCount) { Core::DisplayMessage("Movie End", 2000); - EndPlayInput(); + EndPlayInput(!g_bReadOnly); } } @@ -443,31 +444,37 @@ bool PlayWiimote(int wiimote, u8 *data, s8 &size) fread(data, 1, size, g_recordfd); // TODO: merge this with the above so that there's no duplicate code - if(feof(g_recordfd)) + if(feof(g_recordfd) || g_frameCounter >= g_totalFrameCount) { Core::DisplayMessage("Movie End", 2000); - EndPlayInput(); + EndPlayInput(!g_bReadOnly); } return true; } -void EndPlayInput() { - if (g_recordfd) - fclose(g_recordfd); - - if (!g_bReadOnly && strncmp(g_playingFile, "\0", 1)) +void EndPlayInput(bool cont) +{ + if (cont && g_recordfd) { + // The save and restore here is to resume rerecording + // from the exact point in playback we're at now + // if playback ends before the end of the file. + SaveRecording(g_tmpRecordFile.c_str()); + fclose(g_recordfd); File::Delete(g_recordFile.c_str()); - File::Copy(g_playingFile, g_recordFile.c_str()); + File::Copy(g_tmpRecordFile.c_str(), g_recordFile.c_str()); g_recordfd = fopen(g_recordFile.c_str(), "r+b"); fseeko(g_recordfd, 0, SEEK_END); g_playMode = MODE_RECORDING; + Core::DisplayMessage("Resuming movie recording", 2000); } else { + if (g_recordfd) + fclose(g_recordfd); g_recordfd = NULL; g_numPads = g_rerecords = 0; - g_frameCounter = g_lagCounter = 0; + g_totalFrameCount = g_frameCounter = g_lagCounter = 0; g_playMode = MODE_NONE; } } diff --git a/Source/Core/Core/Src/OnFrame.h b/Source/Core/Core/Src/OnFrame.h index 28d3d07255..15f9496fa1 100644 --- a/Source/Core/Core/Src/OnFrame.h +++ b/Source/Core/Core/Src/OnFrame.h @@ -121,7 +121,7 @@ bool PlayInput(const char *filename); void LoadInput(const char *filename); void PlayController(SPADStatus *PadStatus, int controllerID); bool PlayWiimote(int wiimote, u8* data, s8 &size); -void EndPlayInput(); +void EndPlayInput(bool cont); void SaveRecording(const char *filename); }; diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 3fddd7c536..963d7fd537 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -391,7 +391,7 @@ void LoadStateCallback(u64 userdata, int cyclesLate) if (File::Exists(StringFromFormat("%s.dtm", cur_filename.c_str()).c_str())) Frame::LoadInput(StringFromFormat("%s.dtm", cur_filename.c_str()).c_str()); else if (!Frame::IsRecordingInputFromSaveState()) - Frame::EndPlayInput(); + Frame::EndPlayInput(false); state_op_in_progress = false; diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 73ac176a28..2f9aa2ebdf 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -1044,7 +1044,7 @@ void CFrame::DoStop() if(Frame::IsRecordingInput()) DoRecordingSave(); if(Frame::IsPlayingInput() || Frame::IsRecordingInput()) - Frame::EndPlayInput(); + Frame::EndPlayInput(false); #ifdef __WXGTK__ // Make sure the app doesn't hang waiting on a keystate check