Merge pull request #5784 from leoetlino/movie-buffer
Movie: Get rid of the manual buffer management
This commit is contained in:
commit
37e06586b8
|
@ -66,9 +66,8 @@ static PlayMode s_playMode = MODE_NONE;
|
|||
static u8 s_controllers = 0;
|
||||
static ControllerState s_padState;
|
||||
static DTMHeader tmpHeader;
|
||||
static u8* tmpInput = nullptr;
|
||||
static size_t tmpInputAllocated = 0;
|
||||
static u64 s_currentByte = 0, s_totalBytes = 0;
|
||||
static std::vector<u8> s_temp_input;
|
||||
static u64 s_currentByte = 0;
|
||||
static u64 s_currentFrame = 0, s_totalFrames = 0; // VI
|
||||
static u64 s_currentLagCount = 0;
|
||||
static u64 s_totalLagCount = 0; // just stats
|
||||
|
@ -105,28 +104,6 @@ static WiiManipFunction s_wii_manip_func;
|
|||
|
||||
static std::string s_current_file_name;
|
||||
|
||||
// NOTE: Host / CPU Thread
|
||||
static void EnsureTmpInputSize(size_t bound)
|
||||
{
|
||||
if (tmpInputAllocated >= bound)
|
||||
return;
|
||||
// The buffer expands in powers of two of DTM_BASE_LENGTH
|
||||
// (standard exponential buffer growth).
|
||||
size_t newAlloc = DTM_BASE_LENGTH;
|
||||
while (newAlloc < bound)
|
||||
newAlloc *= 2;
|
||||
|
||||
u8* newTmpInput = new u8[newAlloc];
|
||||
tmpInputAllocated = newAlloc;
|
||||
if (tmpInput != nullptr)
|
||||
{
|
||||
if (s_totalBytes > 0)
|
||||
memcpy(newTmpInput, tmpInput, (size_t)s_totalBytes);
|
||||
delete[] tmpInput;
|
||||
}
|
||||
tmpInput = newTmpInput;
|
||||
}
|
||||
|
||||
static bool IsMovieHeader(u8 magic[4])
|
||||
{
|
||||
return magic[0] == 'D' && magic[1] == 'T' && magic[2] == 'M' && magic[3] == 0x1A;
|
||||
|
@ -621,9 +598,9 @@ bool BeginRecordingInput(int controllers)
|
|||
|
||||
s_playMode = MODE_RECORDING;
|
||||
s_author = SConfig::GetInstance().m_strMovieAuthor;
|
||||
EnsureTmpInputSize(1);
|
||||
s_temp_input.clear();
|
||||
|
||||
s_currentByte = s_totalBytes = 0;
|
||||
s_currentByte = 0;
|
||||
|
||||
if (Core::IsRunning())
|
||||
Core::UpdateWantDeterminism();
|
||||
|
@ -887,10 +864,9 @@ void RecordInput(GCPadStatus* PadStatus, int controllerID)
|
|||
|
||||
CheckPadStatus(PadStatus, controllerID);
|
||||
|
||||
EnsureTmpInputSize((size_t)(s_currentByte + sizeof(ControllerState)));
|
||||
memcpy(&tmpInput[s_currentByte], &s_padState, sizeof(ControllerState));
|
||||
s_temp_input.resize(s_currentByte + sizeof(ControllerState));
|
||||
memcpy(&s_temp_input[s_currentByte], &s_padState, sizeof(ControllerState));
|
||||
s_currentByte += sizeof(ControllerState);
|
||||
s_totalBytes = s_currentByte;
|
||||
}
|
||||
|
||||
// NOTE: CPU Thread
|
||||
|
@ -909,11 +885,10 @@ void RecordWiimote(int wiimote, u8* data, u8 size)
|
|||
return;
|
||||
|
||||
InputUpdate();
|
||||
EnsureTmpInputSize((size_t)(s_currentByte + size + 1));
|
||||
tmpInput[s_currentByte++] = size;
|
||||
memcpy(&(tmpInput[s_currentByte]), data, size);
|
||||
s_temp_input.resize(s_currentByte + size + 1);
|
||||
s_temp_input[s_currentByte++] = size;
|
||||
memcpy(&s_temp_input[s_currentByte], data, size);
|
||||
s_currentByte += size;
|
||||
s_totalBytes = s_currentByte;
|
||||
}
|
||||
|
||||
// NOTE: EmuThread / Host Thread
|
||||
|
@ -986,9 +961,8 @@ bool PlayInput(const std::string& filename)
|
|||
|
||||
Core::UpdateWantDeterminism();
|
||||
|
||||
s_totalBytes = recording_file.GetSize() - 256;
|
||||
EnsureTmpInputSize((size_t)s_totalBytes);
|
||||
recording_file.ReadArray(tmpInput, (size_t)s_totalBytes);
|
||||
s_temp_input.resize(recording_file.GetSize() - 256);
|
||||
recording_file.ReadBytes(s_temp_input.data(), s_temp_input.size());
|
||||
s_currentByte = 0;
|
||||
recording_file.Close();
|
||||
|
||||
|
@ -1063,38 +1037,37 @@ void LoadInput(const std::string& filename)
|
|||
afterEnd = true;
|
||||
}
|
||||
|
||||
if (!s_bReadOnly || tmpInput == nullptr)
|
||||
if (!s_bReadOnly || s_temp_input.empty())
|
||||
{
|
||||
s_totalFrames = tmpHeader.frameCount;
|
||||
s_totalLagCount = tmpHeader.lagCount;
|
||||
s_totalInputCount = tmpHeader.inputCount;
|
||||
s_totalTickCount = s_tickCountAtLastInput = tmpHeader.tickCount;
|
||||
|
||||
EnsureTmpInputSize((size_t)totalSavedBytes);
|
||||
s_totalBytes = totalSavedBytes;
|
||||
t_record.ReadArray(tmpInput, (size_t)s_totalBytes);
|
||||
s_temp_input.resize(static_cast<size_t>(totalSavedBytes));
|
||||
t_record.ReadBytes(s_temp_input.data(), s_temp_input.size());
|
||||
}
|
||||
else if (s_currentByte > 0)
|
||||
{
|
||||
if (s_currentByte > totalSavedBytes)
|
||||
{
|
||||
}
|
||||
else if (s_currentByte > s_totalBytes)
|
||||
else if (s_currentByte > s_temp_input.size())
|
||||
{
|
||||
afterEnd = true;
|
||||
PanicAlertT("Warning: You loaded a save that's after the end of the current movie. (byte %u "
|
||||
"> %u) (input %u > %u). You should load another save before continuing, or load "
|
||||
"> %zu) (input %u > %u). You should load another save before continuing, or load "
|
||||
"this state with read-only mode off.",
|
||||
(u32)s_currentByte + 256, (u32)s_totalBytes + 256, (u32)s_currentInputCount,
|
||||
(u32)s_currentByte + 256, s_temp_input.size() + 256, (u32)s_currentInputCount,
|
||||
(u32)s_totalInputCount);
|
||||
}
|
||||
else if (s_currentByte > 0 && s_totalBytes > 0)
|
||||
else if (s_currentByte > 0 && !s_temp_input.empty())
|
||||
{
|
||||
// verify identical from movie start to the save's current frame
|
||||
std::vector<u8> movInput(s_currentByte);
|
||||
t_record.ReadArray(movInput.data(), movInput.size());
|
||||
|
||||
const auto result = std::mismatch(movInput.begin(), movInput.end(), tmpInput);
|
||||
const auto result = std::mismatch(movInput.begin(), movInput.end(), s_temp_input.begin());
|
||||
|
||||
if (result.first != movInput.end())
|
||||
{
|
||||
|
@ -1113,15 +1086,17 @@ void LoadInput(const std::string& filename)
|
|||
"read-only mode off. Otherwise you'll probably get a desync.",
|
||||
byte_offset, byte_offset);
|
||||
|
||||
std::copy(movInput.begin(), movInput.end(), tmpInput);
|
||||
std::copy(movInput.begin(), movInput.end(), s_temp_input.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
const ptrdiff_t frame = mismatch_index / sizeof(ControllerState);
|
||||
ControllerState curPadState;
|
||||
memcpy(&curPadState, &tmpInput[frame * sizeof(ControllerState)], sizeof(ControllerState));
|
||||
memcpy(&curPadState, &s_temp_input[frame * sizeof(ControllerState)],
|
||||
sizeof(ControllerState));
|
||||
ControllerState movPadState;
|
||||
memcpy(&movPadState, &movInput[frame * sizeof(ControllerState)], sizeof(ControllerState));
|
||||
memcpy(&movPadState, &s_temp_input[frame * sizeof(ControllerState)],
|
||||
sizeof(ControllerState));
|
||||
PanicAlertT(
|
||||
"Warning: You loaded a save whose movie mismatches on frame %td. You should load "
|
||||
"another save before continuing, or load this state with read-only mode off. "
|
||||
|
@ -1186,7 +1161,7 @@ void LoadInput(const std::string& filename)
|
|||
// NOTE: CPU Thread
|
||||
static void CheckInputEnd()
|
||||
{
|
||||
if (s_currentByte >= s_totalBytes ||
|
||||
if (s_currentByte >= s_temp_input.size() ||
|
||||
(CoreTiming::GetTicks() > s_totalTickCount && !IsRecordingInputFromSaveState()))
|
||||
{
|
||||
EndPlayInput(!s_bReadOnly);
|
||||
|
@ -1198,13 +1173,13 @@ void PlayController(GCPadStatus* PadStatus, int controllerID)
|
|||
{
|
||||
// Correct playback is entirely dependent on the emulator polling the controllers
|
||||
// in the same order done during recording
|
||||
if (!IsPlayingInput() || !IsUsingPad(controllerID) || tmpInput == nullptr)
|
||||
if (!IsPlayingInput() || !IsUsingPad(controllerID) || s_temp_input.empty())
|
||||
return;
|
||||
|
||||
if (s_currentByte + sizeof(ControllerState) > s_totalBytes)
|
||||
if (s_currentByte + sizeof(ControllerState) > s_temp_input.size())
|
||||
{
|
||||
PanicAlertT("Premature movie end in PlayController. %u + %zu > %u", (u32)s_currentByte,
|
||||
sizeof(ControllerState), (u32)s_totalBytes);
|
||||
PanicAlertT("Premature movie end in PlayController. %u + %zu > %zu", (u32)s_currentByte,
|
||||
sizeof(ControllerState), s_temp_input.size());
|
||||
EndPlayInput(!s_bReadOnly);
|
||||
return;
|
||||
}
|
||||
|
@ -1215,7 +1190,7 @@ void PlayController(GCPadStatus* PadStatus, int controllerID)
|
|||
memset(PadStatus, 0, sizeof(GCPadStatus));
|
||||
PadStatus->err = e;
|
||||
|
||||
memcpy(&s_padState, &tmpInput[s_currentByte], sizeof(ControllerState));
|
||||
memcpy(&s_padState, &s_temp_input[s_currentByte], sizeof(ControllerState));
|
||||
s_currentByte += sizeof(ControllerState);
|
||||
|
||||
PadStatus->triggerLeft = s_padState.TriggerL;
|
||||
|
@ -1299,20 +1274,20 @@ void PlayController(GCPadStatus* PadStatus, int controllerID)
|
|||
bool PlayWiimote(int wiimote, u8* data, const WiimoteEmu::ReportFeatures& rptf, int ext,
|
||||
const wiimote_key key)
|
||||
{
|
||||
if (!IsPlayingInput() || !IsUsingWiimote(wiimote) || tmpInput == nullptr)
|
||||
if (!IsPlayingInput() || !IsUsingWiimote(wiimote) || s_temp_input.empty())
|
||||
return false;
|
||||
|
||||
if (s_currentByte > s_totalBytes)
|
||||
if (s_currentByte > s_temp_input.size())
|
||||
{
|
||||
PanicAlertT("Premature movie end in PlayWiimote. %u > %u", (u32)s_currentByte,
|
||||
(u32)s_totalBytes);
|
||||
PanicAlertT("Premature movie end in PlayWiimote. %u > %zu", (u32)s_currentByte,
|
||||
s_temp_input.size());
|
||||
EndPlayInput(!s_bReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 size = rptf.size;
|
||||
|
||||
u8 sizeInMovie = tmpInput[s_currentByte];
|
||||
u8 sizeInMovie = s_temp_input[s_currentByte];
|
||||
|
||||
if (size != sizeInMovie)
|
||||
{
|
||||
|
@ -1328,15 +1303,15 @@ bool PlayWiimote(int wiimote, u8* data, const WiimoteEmu::ReportFeatures& rptf,
|
|||
|
||||
s_currentByte++;
|
||||
|
||||
if (s_currentByte + size > s_totalBytes)
|
||||
if (s_currentByte + size > s_temp_input.size())
|
||||
{
|
||||
PanicAlertT("Premature movie end in PlayWiimote. %u + %d > %u", (u32)s_currentByte, size,
|
||||
(u32)s_totalBytes);
|
||||
PanicAlertT("Premature movie end in PlayWiimote. %u + %d > %zu", (u32)s_currentByte, size,
|
||||
s_temp_input.size());
|
||||
EndPlayInput(!s_bReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, &(tmpInput[s_currentByte]), size);
|
||||
memcpy(data, &s_temp_input[s_currentByte], size);
|
||||
s_currentByte += size;
|
||||
|
||||
s_currentInputCount++;
|
||||
|
@ -1440,7 +1415,7 @@ void SaveRecording(const std::string& filename)
|
|||
|
||||
save_record.WriteArray(&header, 1);
|
||||
|
||||
bool success = save_record.WriteArray(tmpInput, (size_t)s_totalBytes);
|
||||
bool success = save_record.WriteBytes(s_temp_input.data(), s_temp_input.size());
|
||||
|
||||
if (success && s_bRecordingFromSaveState)
|
||||
{
|
||||
|
@ -1600,10 +1575,7 @@ static void GetMD5()
|
|||
// NOTE: EmuThread
|
||||
void Shutdown()
|
||||
{
|
||||
s_currentInputCount = s_totalInputCount = s_totalFrames = s_totalBytes = s_tickCountAtLastInput =
|
||||
0;
|
||||
delete[] tmpInput;
|
||||
tmpInput = nullptr;
|
||||
tmpInputAllocated = 0;
|
||||
s_currentInputCount = s_totalInputCount = s_totalFrames = s_tickCountAtLastInput = 0;
|
||||
s_temp_input.clear();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue