mirror of https://github.com/mgba-emu/mgba.git
All: Add option for whether rewinding restores save games
This commit is contained in:
parent
d2016e382a
commit
f302df9178
1
CHANGES
1
CHANGES
|
@ -9,6 +9,7 @@ Features:
|
|||
- GB: LR35902/GB-Z80 disassembler
|
||||
- Configuration of gamepad hats
|
||||
- Qt: Spanish translation (by Kevin López)
|
||||
- Add option for whether rewinding restores save games
|
||||
Bugfixes:
|
||||
- LR35902: Fix core never exiting with certain event patterns
|
||||
- GB Timer: Improve DIV reset behavior
|
||||
|
|
|
@ -27,6 +27,7 @@ struct mCoreOptions {
|
|||
int frameskip;
|
||||
bool rewindEnable;
|
||||
int rewindBufferCapacity;
|
||||
bool rewindSave;
|
||||
float fpsTarget;
|
||||
size_t audioBuffers;
|
||||
unsigned sampleRate;
|
||||
|
|
|
@ -19,6 +19,7 @@ struct mCoreRewindContext {
|
|||
struct mCoreRewindPatches patchMemory;
|
||||
size_t current;
|
||||
size_t size;
|
||||
int stateFlags;
|
||||
struct VFile* previousState;
|
||||
struct VFile* currentState;
|
||||
};
|
||||
|
|
|
@ -321,6 +321,7 @@ void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts)
|
|||
_lookupIntValue(config, "frameskip", &opts->frameskip);
|
||||
_lookupIntValue(config, "volume", &opts->volume);
|
||||
_lookupIntValue(config, "rewindBufferCapacity", &opts->rewindBufferCapacity);
|
||||
_lookupIntValue(config, "rewindSave", &opts->rewindSave);
|
||||
_lookupFloatValue(config, "fpsTarget", &opts->fpsTarget);
|
||||
unsigned audioBuffers;
|
||||
if (_lookupUIntValue(config, "audioBuffers", &audioBuffers)) {
|
||||
|
@ -376,6 +377,7 @@ void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptio
|
|||
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, "rewindSave", opts->rewindSave);
|
||||
ConfigurationSetFloatValue(&config->defaultsTable, 0, "fpsTarget", opts->fpsTarget);
|
||||
ConfigurationSetUIntValue(&config->defaultsTable, 0, "audioBuffers", opts->audioBuffers);
|
||||
ConfigurationSetUIntValue(&config->defaultsTable, 0, "sampleRate", opts->sampleRate);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/core/rewind.h>
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/serialize.h>
|
||||
#include <mgba-util/patch/fast.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
|
@ -20,6 +21,7 @@ void mCoreRewindContextInit(struct mCoreRewindContext* context, size_t entries)
|
|||
context->previousState = VFileMemChunk(0, 0);
|
||||
context->currentState = VFileMemChunk(0, 0);
|
||||
context->size = 0;
|
||||
context->stateFlags = SAVESTATE_SAVEDATA;
|
||||
}
|
||||
|
||||
void mCoreRewindContextDeinit(struct mCoreRewindContext* context) {
|
||||
|
@ -41,7 +43,7 @@ void mCoreRewindAppend(struct mCoreRewindContext* context, struct mCore* core) {
|
|||
if (context->current >= mCoreRewindPatchesSize(&context->patchMemory)) {
|
||||
context->current = 0;
|
||||
}
|
||||
mCoreSaveStateNamed(core, nextState, 0);
|
||||
mCoreSaveStateNamed(core, nextState, context->stateFlags);
|
||||
struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current);
|
||||
size_t size2 = nextState->size(nextState);
|
||||
size_t size = context->currentState->size(context->currentState);
|
||||
|
@ -75,7 +77,7 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core)
|
|||
patch->d.applyPatch(&patch->d, current, size, previous, size);
|
||||
context->currentState->unmap(context->currentState, current, size);
|
||||
context->previousState->unmap(context->previousState, previous, size);
|
||||
mCoreLoadStateNamed(core, context->previousState, 0);
|
||||
mCoreLoadStateNamed(core, context->previousState, context->stateFlags);
|
||||
struct VFile* nextState = context->previousState;
|
||||
context->previousState = context->currentState;
|
||||
context->currentState = nextState;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/core/thread.h>
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/serialize.h>
|
||||
#include <mgba-util/patch.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
|
@ -148,6 +149,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
|
|||
|
||||
if (core->opts.rewindEnable && core->opts.rewindBufferCapacity > 0) {
|
||||
mCoreRewindContextInit(&threadContext->rewind, core->opts.rewindBufferCapacity);
|
||||
threadContext->rewind.stateFlags = core->opts.rewindSave ? SAVESTATE_SAVEDATA : 0;
|
||||
}
|
||||
|
||||
_changeState(threadContext, THREAD_RUNNING, true);
|
||||
|
|
|
@ -110,6 +110,7 @@ ConfigController::ConfigController(QObject* parent)
|
|||
m_opts.logLevel = mLOG_WARN | mLOG_ERROR | mLOG_FATAL;
|
||||
m_opts.rewindEnable = false;
|
||||
m_opts.rewindBufferCapacity = 300;
|
||||
m_opts.rewindSave = true;
|
||||
m_opts.useBios = true;
|
||||
m_opts.suspendScreensaver = true;
|
||||
m_opts.lockAspectRatio = true;
|
||||
|
|
|
@ -731,7 +731,7 @@ void GameController::frameAdvance() {
|
|||
}
|
||||
}
|
||||
|
||||
void GameController::setRewind(bool enable, int capacity) {
|
||||
void GameController::setRewind(bool enable, int capacity, bool rewindSave) {
|
||||
if (m_gameOpen) {
|
||||
Interrupter interrupter(this);
|
||||
if (m_threadContext.core->opts.rewindEnable && m_threadContext.core->opts.rewindBufferCapacity > 0) {
|
||||
|
@ -739,8 +739,10 @@ void GameController::setRewind(bool enable, int capacity) {
|
|||
}
|
||||
m_threadContext.core->opts.rewindEnable = enable;
|
||||
m_threadContext.core->opts.rewindBufferCapacity = capacity;
|
||||
m_threadContext.core->opts.rewindSave = rewindSave;
|
||||
if (enable && capacity > 0) {
|
||||
mCoreRewindContextInit(&m_threadContext.rewind, capacity);
|
||||
m_threadContext.rewind.stateFlags = rewindSave ? SAVESTATE_SAVEDATA : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ public slots:
|
|||
void setPaused(bool paused);
|
||||
void reset();
|
||||
void frameAdvance();
|
||||
void setRewind(bool enable, int capacity);
|
||||
void setRewind(bool enable, int capacity, bool rewindSave);
|
||||
void rewind(int states = 0);
|
||||
void startRewinding();
|
||||
void stopRewinding();
|
||||
|
|
|
@ -194,6 +194,7 @@ void SettingsView::updateConfig() {
|
|||
saveSetting("mute", m_ui.mute);
|
||||
saveSetting("rewindEnable", m_ui.rewind);
|
||||
saveSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
||||
saveSetting("rewindSave", m_ui.rewindSave);
|
||||
saveSetting("resampleVideo", m_ui.resampleVideo);
|
||||
saveSetting("allowOpposingDirections", m_ui.allowOpposingDirections);
|
||||
saveSetting("suspendScreensaver", m_ui.suspendScreensaver);
|
||||
|
@ -272,6 +273,7 @@ void SettingsView::reloadConfig() {
|
|||
loadSetting("mute", m_ui.mute);
|
||||
loadSetting("rewindEnable", m_ui.rewind);
|
||||
loadSetting("rewindBufferCapacity", m_ui.rewindCapacity);
|
||||
loadSetting("rewindSave", m_ui.rewindSave);
|
||||
loadSetting("resampleVideo", m_ui.resampleVideo);
|
||||
loadSetting("allowOpposingDirections", m_ui.allowOpposingDirections);
|
||||
loadSetting("suspendScreensaver", m_ui.suspendScreensaver);
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
<item row="1" column="1">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="av">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
|
@ -535,21 +535,21 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Idle loops:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="idleOptimization">
|
||||
<item>
|
||||
<property name="text">
|
||||
|
@ -568,21 +568,21 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Savestate extra data:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="saveStateScreenshot">
|
||||
<property name="text">
|
||||
<string>Screenshot</string>
|
||||
|
@ -592,7 +592,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="saveStateSave">
|
||||
<property name="text">
|
||||
<string>Save data</string>
|
||||
|
@ -602,7 +602,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="saveStateCheats">
|
||||
<property name="text">
|
||||
<string>Cheat codes</string>
|
||||
|
@ -612,14 +612,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Load extra data:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QCheckBox" name="loadStateScreenshot">
|
||||
<property name="text">
|
||||
<string>Screenshot</string>
|
||||
|
@ -629,27 +629,37 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="loadStateSave">
|
||||
<property name="text">
|
||||
<string>Save data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<item row="14" column="1">
|
||||
<widget class="QCheckBox" name="loadStateCheats">
|
||||
<property name="text">
|
||||
<string>Cheat codes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="Line" name="line_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="rewindSave">
|
||||
<property name="text">
|
||||
<string>Rewind affects save data</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="bios">
|
||||
|
|
|
@ -1439,12 +1439,17 @@ void Window::setupMenu(QMenuBar* menubar) {
|
|||
|
||||
ConfigOption* rewindEnable = m_config->addOption("rewindEnable");
|
||||
rewindEnable->connect([this](const QVariant& value) {
|
||||
m_controller->setRewind(value.toBool(), m_config->getOption("rewindBufferCapacity").toInt());
|
||||
m_controller->setRewind(value.toBool(), m_config->getOption("rewindBufferCapacity").toInt(), m_config->getOption("rewindSave").toInt());
|
||||
}, this);
|
||||
|
||||
ConfigOption* rewindBufferCapacity = m_config->addOption("rewindBufferCapacity");
|
||||
rewindBufferCapacity->connect([this](const QVariant& value) {
|
||||
m_controller->setRewind(m_config->getOption("rewindEnable").toInt(), value.toInt());
|
||||
m_controller->setRewind(m_config->getOption("rewindEnable").toInt(), value.toInt(), m_config->getOption("rewindSave").toInt());
|
||||
}, this);
|
||||
|
||||
ConfigOption* rewindSave = m_config->addOption("rewindSave");
|
||||
rewindBufferCapacity->connect([this](const QVariant& value) {
|
||||
m_controller->setRewind(m_config->getOption("rewindEnable").toInt(), m_config->getOption("rewindBufferCapacity").toInt(), value.toBool());
|
||||
}, this);
|
||||
|
||||
ConfigOption* allowOpposingDirections = m_config->addOption("allowOpposingDirections");
|
||||
|
|
|
@ -43,6 +43,7 @@ int main(int argc, char** argv) {
|
|||
.useBios = true,
|
||||
.rewindEnable = true,
|
||||
.rewindBufferCapacity = 600,
|
||||
.rewindSave = true,
|
||||
.audioBuffers = 1024,
|
||||
.videoSync = false,
|
||||
.audioSync = true,
|
||||
|
|
Loading…
Reference in New Issue