mirror of
https://github.com/libretro/Mesen.git
synced 2025-02-02 06:44:48 +00:00
Rewind: Fixed some edge cases
This commit is contained in:
parent
1852f87934
commit
a7b410666b
@ -2,6 +2,7 @@
|
||||
#include "EmulationSettings.h"
|
||||
#include "Console.h"
|
||||
#include "VsControlManager.h"
|
||||
#include "RewindManager.h"
|
||||
|
||||
//Version 0.8.1
|
||||
uint16_t EmulationSettings::_versionMajor = 0;
|
||||
@ -103,3 +104,13 @@ void EmulationSettings::SetEqualizerBands(double *bands, uint32_t bandCount)
|
||||
}
|
||||
Console::Resume();
|
||||
}
|
||||
|
||||
void EmulationSettings::SetRewindBufferSize(uint32_t seconds)
|
||||
{
|
||||
if(seconds == 0 || _rewindBufferSize == 0) {
|
||||
Console::Pause();
|
||||
RewindManager::ClearBuffer();
|
||||
Console::Resume();
|
||||
}
|
||||
_rewindBufferSize = seconds;
|
||||
}
|
@ -665,10 +665,7 @@ public:
|
||||
return _rewindSpeed;
|
||||
}
|
||||
|
||||
static void SetRewindBufferSize(uint32_t seconds)
|
||||
{
|
||||
_rewindBufferSize = seconds;
|
||||
}
|
||||
static void SetRewindBufferSize(uint32_t seconds);
|
||||
|
||||
static uint32_t GetRewindBufferSize()
|
||||
{
|
||||
|
@ -5,11 +5,13 @@
|
||||
|
||||
void RewindData::LoadState()
|
||||
{
|
||||
unsigned long length = OriginalSaveStateSize;
|
||||
uint8_t* buffer = new uint8_t[length];
|
||||
uncompress(buffer, &length, SaveStateData.data(), (unsigned long)SaveStateData.size());
|
||||
Console::LoadState(buffer, length);
|
||||
delete[] buffer;
|
||||
if(SaveStateData.size() > 0 && OriginalSaveStateSize > 0) {
|
||||
unsigned long length = OriginalSaveStateSize;
|
||||
uint8_t* buffer = new uint8_t[length];
|
||||
uncompress(buffer, &length, SaveStateData.data(), (unsigned long)SaveStateData.size());
|
||||
Console::LoadState(buffer, length);
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void RewindData::CompressState(string stateData, vector<uint8_t>& compressedState)
|
||||
|
@ -6,7 +6,7 @@ class RewindData
|
||||
{
|
||||
private:
|
||||
vector<uint8_t> SaveStateData;
|
||||
uint32_t OriginalSaveStateSize;
|
||||
uint32_t OriginalSaveStateSize = 0;
|
||||
|
||||
void CompressState(string stateData, vector<uint8_t> &compressedState);
|
||||
|
||||
|
@ -25,28 +25,46 @@ RewindManager::~RewindManager()
|
||||
MessageManager::UnregisterNotificationListener(this);
|
||||
}
|
||||
|
||||
void RewindManager::ClearBuffer()
|
||||
{
|
||||
if(_instance) {
|
||||
_instance->_history.clear();
|
||||
_instance->_historyBackup.clear();
|
||||
_instance->_currentHistory = RewindData();
|
||||
_instance->_framesToFastForward = 0;
|
||||
_instance->_videoHistory.clear();
|
||||
_instance->_videoHistoryBuilder.clear();
|
||||
_instance->_audioHistory.clear();
|
||||
_instance->_audioHistoryBuilder.clear();
|
||||
_instance->_rewindState = RewindState::Stopped;
|
||||
_instance->AddHistoryBlock();
|
||||
}
|
||||
}
|
||||
|
||||
void RewindManager::ProcessNotification(ConsoleNotificationType type, void * parameter)
|
||||
{
|
||||
if(type == ConsoleNotificationType::PpuFrameDone) {
|
||||
if(_rewindState >= RewindState::Starting) {
|
||||
_currentHistory.FrameCount--;
|
||||
} else if(_rewindState == RewindState::Stopping) {
|
||||
_framesToFastForward--;
|
||||
_currentHistory.FrameCount++;
|
||||
if(_framesToFastForward == 0) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
size_t numberToRemove = _currentHistory.InputLogs[i].size();
|
||||
_currentHistory.InputLogs[i] = _historyBackup.front().InputLogs[i];
|
||||
for(size_t j = 0; j < numberToRemove; j++) {
|
||||
_currentHistory.InputLogs[i].pop_back();
|
||||
if(EmulationSettings::GetRewindBufferSize() > 0) {
|
||||
if(_rewindState >= RewindState::Starting) {
|
||||
_currentHistory.FrameCount--;
|
||||
} else if(_rewindState == RewindState::Stopping) {
|
||||
_framesToFastForward--;
|
||||
_currentHistory.FrameCount++;
|
||||
if(_framesToFastForward == 0) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
size_t numberToRemove = _currentHistory.InputLogs[i].size();
|
||||
_currentHistory.InputLogs[i] = _historyBackup.front().InputLogs[i];
|
||||
for(size_t j = 0; j < numberToRemove; j++) {
|
||||
_currentHistory.InputLogs[i].pop_back();
|
||||
}
|
||||
}
|
||||
_historyBackup.clear();
|
||||
_rewindState = RewindState::Stopped;
|
||||
EmulationSettings::SetEmulationSpeed(100);
|
||||
}
|
||||
_historyBackup.clear();
|
||||
_rewindState = RewindState::Stopped;
|
||||
EmulationSettings::SetEmulationSpeed(100);
|
||||
} else {
|
||||
_currentHistory.FrameCount++;
|
||||
}
|
||||
} else {
|
||||
_currentHistory.FrameCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,19 +72,15 @@ void RewindManager::ProcessNotification(ConsoleNotificationType type, void * par
|
||||
void RewindManager::AddHistoryBlock()
|
||||
{
|
||||
uint32_t maxHistorySize = EmulationSettings::GetRewindBufferSize() * 120;
|
||||
if(maxHistorySize == 0) {
|
||||
_history.clear();
|
||||
} else {
|
||||
while(_history.size() > maxHistorySize) {
|
||||
_history.pop_front();
|
||||
}
|
||||
|
||||
if(_currentHistory.FrameCount > 0) {
|
||||
_history.push_back(_currentHistory);
|
||||
}
|
||||
_currentHistory = RewindData();
|
||||
_currentHistory.SaveState();
|
||||
while(_history.size() > maxHistorySize) {
|
||||
_history.pop_front();
|
||||
}
|
||||
|
||||
if(_currentHistory.FrameCount > 0) {
|
||||
_history.push_back(_currentHistory);
|
||||
}
|
||||
_currentHistory = RewindData();
|
||||
_currentHistory.SaveState();
|
||||
}
|
||||
|
||||
void RewindManager::PopHistory()
|
||||
@ -114,15 +128,17 @@ void RewindManager::Stop()
|
||||
Console::Pause();
|
||||
if(_rewindState == RewindState::Started) {
|
||||
//Move back to the save state containing the frame currently shown on the screen
|
||||
_framesToFastForward = (uint32_t)_videoHistory.size() + _historyBackup.front().FrameCount;
|
||||
do {
|
||||
_history.push_back(_historyBackup.front());
|
||||
_framesToFastForward -= _historyBackup.front().FrameCount;
|
||||
_historyBackup.pop_front();
|
||||
if(_historyBackup.size() > 1) {
|
||||
_framesToFastForward = (uint32_t)_videoHistory.size() + _historyBackup.front().FrameCount;
|
||||
do {
|
||||
_history.push_back(_historyBackup.front());
|
||||
_framesToFastForward -= _historyBackup.front().FrameCount;
|
||||
_historyBackup.pop_front();
|
||||
|
||||
_currentHistory = _historyBackup.front();
|
||||
_currentHistory = _historyBackup.front();
|
||||
}
|
||||
while(_framesToFastForward > RewindManager::BufferSize && _historyBackup.size() > 1);
|
||||
}
|
||||
while(_framesToFastForward > RewindManager::BufferSize);
|
||||
} else {
|
||||
//We started rewinding, but didn't actually visually rewind anything yet
|
||||
//Move back to the save state containing the frame currently shown on the screen
|
||||
@ -218,7 +234,7 @@ bool RewindManager::ProcessAudio(int16_t * soundBuffer, uint32_t sampleCount, ui
|
||||
|
||||
void RewindManager::RecordInput(uint8_t port, uint8_t input)
|
||||
{
|
||||
if(_instance && _instance->_rewindState == RewindState::Stopped) {
|
||||
if(EmulationSettings::GetRewindBufferSize() > 0 && _instance && _instance->_rewindState == RewindState::Stopped) {
|
||||
_instance->_currentHistory.InputLogs[port].push_back(input);
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
||||
void ProcessEndOfFrame();
|
||||
|
||||
static void ClearBuffer();
|
||||
|
||||
static void RecordInput(uint8_t port, uint8_t input);
|
||||
static uint8_t GetInput(uint8_t port);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user