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

View File

@ -167,7 +167,7 @@ public:
// the current frame's value from the emulator // the current frame's value from the emulator
bool ReadKeyBuffer(u8& result, const uint frame, const uint port, const uint bufIndex); 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 // 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 // Persist the input recording file header's current state to the file
bool WriteHeader() const; bool WriteHeader() const;
// Writes the current frame's input data to the file so it can be replayed // 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; unsigned long getUndoCount() const noexcept;
void logRecordingMetadata(); 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: private:
static constexpr size_t s_controllerPortsSupported = 2; static constexpr size_t s_controllerPortsSupported = 2;
@ -206,7 +206,7 @@ private:
unsigned long m_undoCount = 0; unsigned long m_undoCount = 0;
// Calculates the position of the current frame in the input recording // 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(); bool verifyRecordingFileHeader();
}; };