diff --git a/src/gba/gba-config.c b/src/gba/gba-config.c index d647ca113..9c1abd6f2 100644 --- a/src/gba/gba-config.c +++ b/src/gba/gba-config.c @@ -205,6 +205,9 @@ void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) { if (_lookupIntValue(config, "skipBios", &fakeBool)) { opts->skipBios = fakeBool; } + if (_lookupIntValue(config, "rewindEnable", &fakeBool)) { + opts->rewindEnable = fakeBool; + } _lookupIntValue(config, "fullscreen", &opts->fullscreen); _lookupIntValue(config, "width", &opts->width); @@ -216,6 +219,7 @@ void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* op ConfigurationSetIntValue(&config->defaultsTable, 0, "skipBios", opts->skipBios); ConfigurationSetIntValue(&config->defaultsTable, 0, "logLevel", opts->logLevel); ConfigurationSetIntValue(&config->defaultsTable, 0, "frameskip", opts->frameskip); + ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindEnable", opts->rewindEnable); ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferCapacity", opts->rewindBufferCapacity); ConfigurationSetIntValue(&config->defaultsTable, 0, "rewindBufferInterval", opts->rewindBufferInterval); ConfigurationSetFloatValue(&config->defaultsTable, 0, "fpsTarget", opts->fpsTarget); diff --git a/src/gba/gba-config.h b/src/gba/gba-config.h index 776aed75d..93d68b219 100644 --- a/src/gba/gba-config.h +++ b/src/gba/gba-config.h @@ -21,6 +21,7 @@ struct GBAOptions { bool skipBios; int logLevel; int frameskip; + bool rewindEnable; int rewindBufferCapacity; int rewindBufferInterval; float fpsTarget; diff --git a/src/gba/gba-serialize.c b/src/gba/gba-serialize.c index 95ed22aab..c59a9d938 100644 --- a/src/gba/gba-serialize.c +++ b/src/gba/gba-serialize.c @@ -249,6 +249,28 @@ void GBARecordFrame(struct GBAThread* thread) { thread->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity; } +void GBARewindSettingsChanged(struct GBAThread* threadContext, int newCapacity, int newInterval) { + if (newCapacity == threadContext->rewindBufferCapacity && newInterval == threadContext->rewindBufferInterval) { + return; + } + threadContext->rewindBufferInterval = newInterval; + threadContext->rewindBufferNext = threadContext->rewindBufferInterval; + threadContext->rewindBufferSize = 0; + if (threadContext->rewindBuffer) { + int i; + for (i = 0; i < threadContext->rewindBufferCapacity; ++i) { + GBADeallocateState(threadContext->rewindBuffer[i]); + } + free(threadContext->rewindBuffer); + } + threadContext->rewindBufferCapacity = newCapacity; + if (threadContext->rewindBufferCapacity > 0) { + threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(struct GBASerializedState*)); + } else { + threadContext->rewindBuffer = 0; + } +} + void GBARewind(struct GBAThread* thread, int nStates) { if (nStates > thread->rewindBufferSize || nStates < 0) { nStates = thread->rewindBufferSize; @@ -268,3 +290,7 @@ void GBARewind(struct GBAThread* thread, int nStates) { thread->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity; GBADeserialize(thread->gba, state); } + +void GBARewindAll(struct GBAThread* thread) { + GBARewind(thread, thread->rewindBufferSize); +} diff --git a/src/gba/gba-serialize.h b/src/gba/gba-serialize.h index 4d724a1ff..def9c98dc 100644 --- a/src/gba/gba-serialize.h +++ b/src/gba/gba-serialize.h @@ -298,6 +298,8 @@ void GBADeallocateState(struct GBASerializedState* state); struct GBAThread; void GBARecordFrame(struct GBAThread* thread); +void GBARewindSettingsChanged(struct GBAThread* thread, int newCapacity, int newInterval); void GBARewind(struct GBAThread* thread, int nStates); +void GBARewindAll(struct GBAThread* thread); #endif diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index 6171b4e00..807edf001 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -240,8 +240,12 @@ void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* thr threadContext->bios = VFileOpen(opts->bios, O_RDONLY); threadContext->frameskip = opts->frameskip; threadContext->logLevel = opts->logLevel; - threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; - threadContext->rewindBufferInterval = opts->rewindBufferInterval; + if (opts->rewindEnable) { + threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; + threadContext->rewindBufferInterval = opts->rewindBufferInterval; + } else { + threadContext->rewindBufferCapacity = 0; + } threadContext->skipBios = opts->skipBios; threadContext->sync.audioWait = opts->audioSync; threadContext->sync.videoFrameWait = opts->videoSync; @@ -276,13 +280,12 @@ bool GBAThreadStart(struct GBAThread* threadContext) { threadContext->sync.videoFrameOn = true; threadContext->sync.videoFrameSkip = 0; - threadContext->rewindBufferNext = threadContext->rewindBufferInterval; - threadContext->rewindBufferSize = 0; - if (threadContext->rewindBufferCapacity) { - threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(void*)); - } else { - threadContext->rewindBuffer = 0; - } + threadContext->rewindBuffer = 0; + int newCapacity = threadContext->rewindBufferCapacity; + int newInterval = threadContext->rewindBufferInterval; + threadContext->rewindBufferCapacity = 0; + threadContext->rewindBufferInterval = 0; + GBARewindSettingsChanged(threadContext, newCapacity, newInterval); if (!threadContext->fpsTarget) { threadContext->fpsTarget = _defaultFPSTarget; diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 79de083f1..42203bde1 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -96,6 +96,9 @@ ConfigController::ConfigController(QObject* parent) m_opts.fpsTarget = 60; m_opts.audioBuffers = 2048; m_opts.logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL; + m_opts.rewindEnable = false; + m_opts.rewindBufferInterval = 0; + m_opts.rewindBufferCapacity = 0; GBAConfigLoadDefaults(&m_config, &m_opts); GBAConfigLoad(&m_config); GBAConfigMap(&m_config, &m_opts); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index c4a6437a9..1ba5c35f5 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -45,6 +45,7 @@ int main(int argc, char** argv) { struct GBAOptions opts = { .width = VIDEO_HORIZONTAL_PIXELS, .height = VIDEO_VERTICAL_PIXELS, + .rewindEnable = true, .audioBuffers = 512, .videoSync = false, .audioSync = true,