input-rec: updates to bulk read implementation

+ Handles edge cases where the file is too small
+ Minor performance optimizations around reserving vector memory space
+ Simpler file seeking
This commit is contained in:
sonicfind 2022-09-23 12:00:09 -05:00 committed by refractionpcsx2
parent 31b7ec7308
commit f699807cae
2 changed files with 26 additions and 20 deletions

View File

@ -365,7 +365,7 @@ bool InputRecordingFile::ReadKeyBuffer(u8& result, const uint frame, const uint
return true;
}
void InputRecordingFile::SetTotalFrames(long frame)
void InputRecordingFile::SetTotalFrames(u32 frame)
{
if (m_recordingFile == nullptr || m_totalFrames >= frame)
{
@ -423,39 +423,45 @@ void InputRecordingFile::logRecordingMetadata()
fmt::format("Undo Count: {}", getUndoCount())});
}
std::vector<PadData> InputRecordingFile::bulkReadPadData(long frameStart, long frameEnd, const uint port)
std::vector<PadData> InputRecordingFile::bulkReadPadData(u32 frameStart, u32 frameEnd, const uint port)
{
std::vector<PadData> data = {};
std::vector<PadData> data;
if (m_recordingFile == nullptr)
if (m_recordingFile == nullptr || frameEnd < frameStart)
{
return data;
}
frameStart = frameStart < 0 ? 0 : frameStart;
const size_t size = static_cast<size_t>(frameEnd - frameStart);
data.reserve(size);
std::array<u8, s_controllerInputBytes> padBytes;
// TODO - there are probably issues here if the file is too small / the frame counters are invalid!
for (int frame = frameStart; frame < frameEnd; frame++)
const size_t seek = getRecordingBlockSeekPoint(frameStart) + s_controllerInputBytes * port;
const size_t skip = s_controllerInputBytes * (s_controllerPortsSupported - port - 1);
fseek(m_recordingFile, seek, SEEK_SET);
for (int frame = 0; frame < size; frame++)
{
const long seek = getRecordingBlockSeekPoint(frame) + s_controllerInputBytes * port;
fseek(m_recordingFile, seek, SEEK_SET);
if (fread(&padBytes, 1, padBytes.size(), m_recordingFile))
if (fread(&padBytes, 1, s_controllerInputBytes, m_recordingFile) != s_controllerInputBytes)
{
PadData frameData;
for (int i = 0; i < padBytes.size(); i++)
{
frameData.UpdateControllerData(i, padBytes.at(i));
}
data.push_back(frameData);
data.shrink_to_fit();
break;
}
PadData frameData;
for (int i = 0; i < padBytes.size(); i++)
{
frameData.UpdateControllerData(i, padBytes.at(i));
}
data.push_back(std::move(frameData));
fseek(m_recordingFile, skip, SEEK_CUR);
}
return data;
}
size_t InputRecordingFile::getRecordingBlockSeekPoint(const long frame) const noexcept
size_t InputRecordingFile::getRecordingBlockSeekPoint(const u32 frame) const noexcept
{
return s_headerSize + sizeof(bool) + frame * s_inputBytesPerFrame;
}

View File

@ -167,7 +167,7 @@ public:
// the current frame's value from the emulator
bool ReadKeyBuffer(u8& result, const uint frame, const uint port, const uint bufIndex);
// Updates the total frame counter and commit it to the recording file
void SetTotalFrames(long frames);
void SetTotalFrames(u32 frames);
// Persist the input recording file header's current state to the file
bool WriteHeader() const;
// Writes the current frame's input data to the file so it can be replayed
@ -181,7 +181,7 @@ public:
unsigned long getUndoCount() const noexcept;
void logRecordingMetadata();
std::vector<PadData> bulkReadPadData(long frameStart, long frameEnd, const uint port);
std::vector<PadData> bulkReadPadData(u32 frameStart, u32 frameEnd, const uint port);
private:
static constexpr size_t s_controllerPortsSupported = 2;
@ -206,7 +206,7 @@ private:
unsigned long m_undoCount = 0;
// Calculates the position of the current frame in the input recording
size_t getRecordingBlockSeekPoint(const long frame) const noexcept;
size_t getRecordingBlockSeekPoint(const u32 frame) const noexcept;
bool verifyRecordingFileHeader();
};