all repos — mgba @ 60577e83948647d36a2e6a8b4ec8f8556df3f72f

mGBA Game Boy Advance Emulator

Tools: Allow for separate fast forward ratios for held/toggled speedup

The current implementation allows for a toggle or hold of fast forward. This, however, means that there is no way to do something similar to snes9x in which there is a increase speed/decrease speed hotkey as well as a "turbo" hotkey (which just uncaps the fps).

I have implemented a separate setting to control the speedup ratio when the fast forward button is held, and the logic to allow the user to (for example):
1. Set the toggled fast forward speed to 200%
2. Set the "held" fast forward speed to uncapped
3. Toggle fast forward on (press shift tab) and play at 2x speed
4. Hold fast forward (tab) to uncap
5. Let go of fast forward (tab) to go back to 2x speed
6. Toggle fast forward off (press shift tab) and go back to 1x speed
Brian Smith briaguya@gmail.com
Tue, 22 Jan 2019 17:48:19 -0600
commit

60577e83948647d36a2e6a8b4ec8f8556df3f72f

parent

9b1c3e53964a7c5afe704c57dbd656e4cfe801d1

M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -238,6 +238,7 @@ Interrupter interrupter(this);

m_loadStateFlags = config->getOption("loadStateExtdata", m_loadStateFlags).toInt(); m_saveStateFlags = config->getOption("saveStateExtdata", m_saveStateFlags).toInt(); m_fastForwardRatio = config->getOption("fastForwardRatio", m_fastForwardRatio).toFloat(); + m_fastForwardHeldRatio = config->getOption("fastForwardHeldRatio", m_fastForwardRatio).toFloat(); m_videoSync = config->getOption("videoSync", m_videoSync).toInt(); m_audioSync = config->getOption("audioSync", m_audioSync).toInt(); m_fpsTarget = config->getOption("fpsTarget").toFloat();

@@ -812,6 +813,8 @@ QMetaObject::invokeMethod(this, "frameAvailable");

} void CoreController::updateFastForward() { + // If we have "Fast forward" checked in the menu (m_fastForwardForced) + // or are holding the fast forward button (m_fastForward): if (m_fastForward || m_fastForwardForced) { if (m_fastForwardVolume >= 0) { m_threadContext.core->opts.volume = m_fastForwardVolume;

@@ -819,10 +822,25 @@ }

if (m_fastForwardMute >= 0) { m_threadContext.core->opts.mute = m_fastForwardMute; } - if (m_fastForwardRatio > 0) { - m_threadContext.impl->sync.fpsTarget = m_fpsTarget * m_fastForwardRatio; + + // If we aren't holding the fast forward button + // then use the non "(held)" ratio + if(!m_fastForward) { + if (m_fastForwardRatio > 0) { + m_threadContext.impl->sync.fpsTarget = m_fpsTarget * m_fastForwardRatio; + setSync(true); + } else { + setSync(false); + } } else { - setSync(false); + // If we are holding the fast forward button, + // then use the held ratio + if (m_fastForwardHeldRatio > 0) { + m_threadContext.impl->sync.fpsTarget = m_fpsTarget * m_fastForwardHeldRatio; + setSync(true); + } else { + setSync(false); + } } } else { if (!mCoreConfigGetIntValue(&m_threadContext.core->config, "volume", &m_threadContext.core->opts.volume)) {
M src/platform/qt/CoreController.hsrc/platform/qt/CoreController.h

@@ -207,6 +207,7 @@ int m_fastForwardForced = false;

int m_fastForwardVolume = -1; int m_fastForwardMute = -1; float m_fastForwardRatio = -1.f; + float m_fastForwardHeldRatio = -1.f; float m_fpsTarget; InputController* m_inputController = nullptr;
M src/platform/qt/SettingsView.cppsrc/platform/qt/SettingsView.cpp

@@ -396,6 +396,12 @@ } else {

saveSetting("fastForwardRatio", m_ui.fastForwardRatio); } + if (m_ui.fastForwardHeldUnbounded->isChecked()) { + saveSetting("fastForwardHeldRatio", "-1"); + } else { + saveSetting("fastForwardHeldRatio", m_ui.fastForwardHeldRatio); + } + switch (m_ui.idleOptimization->currentIndex() + IDLE_LOOP_IGNORE) { case IDLE_LOOP_IGNORE: saveSetting("idleOptimization", "ignore");

@@ -532,6 +538,16 @@ } else {

m_ui.fastForwardUnbounded->setChecked(false); m_ui.fastForwardRatio->setEnabled(true); m_ui.fastForwardRatio->setValue(fastForwardRatio); + } + + double fastForwardHeldRatio = loadSetting("fastForwardHeldRatio").toDouble(); + if (fastForwardHeldRatio <= 0) { + m_ui.fastForwardHeldUnbounded->setChecked(true); + m_ui.fastForwardHeldRatio->setEnabled(false); + } else { + m_ui.fastForwardHeldUnbounded->setChecked(false); + m_ui.fastForwardHeldRatio->setEnabled(true); + m_ui.fastForwardHeldRatio->setValue(fastForwardHeldRatio); } QString idleOptimization = loadSetting("idleOptimization");
M src/platform/qt/SettingsView.uisrc/platform/qt/SettingsView.ui

@@ -658,13 +658,56 @@ </item>

</layout> </item> <item row="1" column="0"> + <widget class="QLabel" name="label_181"> + <property name="text"> + <string>Fast forward (held) speed:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_51"> + <item> + <widget class="QDoubleSpinBox" name="fastForwardHeldRatio"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string>×</string> + </property> + <property name="minimum"> + <double>0.010000000000000</double> + </property> + <property name="maximum"> + <double>20.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.500000000000000</double> + </property> + <property name="value"> + <double>5.000000000000000</double> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="fastForwardHeldUnbounded"> + <property name="text"> + <string>Unbounded</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="0"> <widget class="QLabel" name="label_31"> <property name="text"> <string>Autofire interval:</string> </property> </widget> </item> - <item row="1" column="1"> + <item row="2" column="1"> <widget class="QSpinBox" name="autofireThreshold"> <property name="minimum"> <number>1</number>

@@ -674,28 +717,28 @@ <number>60</number>

</property> </widget> </item> - <item row="2" column="0" colspan="2"> + <item row="3" column="0" colspan="2"> <widget class="Line" name="line"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="3" column="1"> + <item row="4" column="1"> <widget class="QCheckBox" name="rewind"> <property name="text"> <string>Enable rewind</string> </property> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Rewind history:</string> </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_13"> <item> <widget class="QSpinBox" name="rewindCapacity">

@@ -713,21 +756,21 @@ </widget>

</item> </layout> </item> - <item row="5" column="0" colspan="2"> + <item row="6" column="0" colspan="2"> <widget class="Line" name="line_3"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="6" column="0"> + <item row="7" column="0"> <widget class="QLabel" name="label_15"> <property name="text"> <string>Idle loops:</string> </property> </widget> </item> - <item row="6" column="1"> + <item row="7" column="1"> <widget class="QComboBox" name="idleOptimization"> <item> <property name="text">

@@ -746,28 +789,28 @@ </property>

</item> </widget> </item> - <item row="7" column="1"> + <item row="8" column="1"> <widget class="QCheckBox" name="preload"> <property name="text"> <string>Preload entire ROM into memory</string> </property> </widget> </item> - <item row="8" column="0" colspan="2"> + <item row="9" column="0" colspan="2"> <widget class="Line" name="line_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="9" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_24"> <property name="text"> <string>Savestate extra data:</string> </property> </widget> </item> - <item row="9" column="1"> + <item row="10" column="1"> <widget class="QCheckBox" name="saveStateScreenshot"> <property name="text"> <string>Screenshot</string>

@@ -777,7 +820,7 @@ <bool>true</bool>

</property> </widget> </item> - <item row="10" column="1"> + <item row="11" column="1"> <widget class="QCheckBox" name="saveStateSave"> <property name="text"> <string>Save data</string>

@@ -787,7 +830,7 @@ <bool>true</bool>

</property> </widget> </item> - <item row="11" column="1"> + <item row="12" column="1"> <widget class="QCheckBox" name="saveStateCheats"> <property name="text"> <string>Cheat codes</string>

@@ -797,21 +840,21 @@ <bool>true</bool>

</property> </widget> </item> - <item row="12" column="0" colspan="2"> + <item row="13" column="0" colspan="2"> <widget class="Line" name="line_9"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="13" column="0"> + <item row="14" column="0"> <widget class="QLabel" name="label_25"> <property name="text"> <string>Load extra data:</string> </property> </widget> </item> - <item row="13" column="1"> + <item row="14" column="1"> <widget class="QCheckBox" name="loadStateScreenshot"> <property name="text"> <string>Screenshot</string>

@@ -821,14 +864,14 @@ <bool>true</bool>

</property> </widget> </item> - <item row="14" column="1"> + <item row="15" column="1"> <widget class="QCheckBox" name="loadStateSave"> <property name="text"> <string>Save data</string> </property> </widget> </item> - <item row="15" column="1"> + <item row="16" column="1"> <widget class="QCheckBox" name="loadStateCheats"> <property name="text"> <string>Cheat codes</string>

@@ -1816,6 +1859,12 @@ <x>349</x>

<y>38</y> </hint> </hints> + </connection> + <connection> + <sender>fastForwardHeldUnbounded</sender> + <signal>toggled(bool)</signal> + <receiver>fastForwardHeldRatio</receiver> + <slot>setDisabled(bool)</slot> </connection> </connections> </ui>