Qt: Ability to cap fast forward speed (fixes B#218)

This commit is contained in:
Jeffrey Pfau 2015-05-23 22:59:07 -07:00
parent 9085bbb8a4
commit 7bc834526a
4 changed files with 48 additions and 2 deletions

View File

@ -17,6 +17,7 @@ Features:
- Screensaver can now be suspended while a game is running - Screensaver can now be suspended while a game is running
- Load/save the most recent savestate slot - Load/save the most recent savestate slot
- Support varible speed (PWM) rumble - Support varible speed (PWM) rumble
- Ability to cap fast forward speed
Bugfixes: Bugfixes:
- ARM7: Fix SWI and IRQ timings - ARM7: Fix SWI and IRQ timings
- GBA Audio: Force audio FIFOs to 32-bit - GBA Audio: Force audio FIFOs to 32-bit

View File

@ -41,8 +41,10 @@ GameController::GameController(QObject* parent)
, m_audioProcessor(AudioProcessor::create()) , m_audioProcessor(AudioProcessor::create())
, m_videoSync(VIDEO_SYNC) , m_videoSync(VIDEO_SYNC)
, m_audioSync(AUDIO_SYNC) , m_audioSync(AUDIO_SYNC)
, m_fpsTarget(-1)
, m_turbo(false) , m_turbo(false)
, m_turboForced(false) , m_turboForced(false)
, m_turboSpeed(-1)
, m_inputController(nullptr) , m_inputController(nullptr)
, m_multiplayer(nullptr) , m_multiplayer(nullptr)
, m_stateSlot(1) , m_stateSlot(1)
@ -99,6 +101,7 @@ GameController::GameController(QObject* parent)
context->gba->rtcSource = &controller->m_rtc; context->gba->rtcSource = &controller->m_rtc;
context->gba->rumble = controller->m_inputController->rumble(); context->gba->rumble = controller->m_inputController->rumble();
context->gba->rotationSource = controller->m_inputController->rotationSource(); context->gba->rotationSource = controller->m_inputController->rotationSource();
controller->m_fpsTarget = context->fpsTarget;
controller->gameStarted(context); controller->gameStarted(context);
}; };
@ -487,7 +490,11 @@ void GameController::setAudioBufferSamples(int samples) {
void GameController::setFPSTarget(float fps) { void GameController::setFPSTarget(float fps) {
threadInterrupt(); threadInterrupt();
m_fpsTarget = fps;
m_threadContext.fpsTarget = fps; m_threadContext.fpsTarget = fps;
if (m_turbo && m_turboSpeed > 0) {
m_threadContext.fpsTarget *= m_turboSpeed;
}
redoSamples(m_audioProcessor->getBufferSamples()); redoSamples(m_audioProcessor->getBufferSamples());
threadContinue(); threadContinue();
QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged"); QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged");
@ -577,9 +584,30 @@ void GameController::setTurbo(bool set, bool forced) {
} }
m_turbo = set; m_turbo = set;
m_turboForced = set && forced; m_turboForced = set && forced;
enableTurbo();
}
void GameController::setTurboSpeed(float ratio) {
m_turboSpeed = ratio;
enableTurbo();
}
void GameController::enableTurbo() {
threadInterrupt(); threadInterrupt();
m_threadContext.sync.audioWait = set ? false : m_audioSync; if (!m_turbo) {
m_threadContext.sync.videoFrameWait = set ? false : m_videoSync; m_threadContext.fpsTarget = m_fpsTarget;
m_threadContext.sync.audioWait = m_audioSync;
m_threadContext.sync.videoFrameWait = m_videoSync;
redoSamples(m_audioProcessor->getBufferSamples());
} else if (m_turboSpeed <= 0) {
m_threadContext.sync.audioWait = false;
m_threadContext.sync.videoFrameWait = false;
} else {
m_threadContext.fpsTarget = m_fpsTarget * m_turboSpeed;
m_threadContext.sync.audioWait = true;
m_threadContext.sync.videoFrameWait = false;
redoSamples(m_audioProcessor->getBufferSamples());
}
threadContinue(); threadContinue();
} }

View File

@ -121,6 +121,7 @@ public slots:
void setVolume(int); void setVolume(int);
void setMute(bool); void setMute(bool);
void setTurbo(bool, bool forced = true); void setTurbo(bool, bool forced = true);
void setTurboSpeed(float ratio = -1);
void setAVStream(GBAAVStream*); void setAVStream(GBAAVStream*);
void clearAVStream(); void clearAVStream();
void reloadAudioDriver(); void reloadAudioDriver();
@ -151,6 +152,7 @@ private slots:
private: private:
void updateKeys(); void updateKeys();
void redoSamples(int samples); void redoSamples(int samples);
void enableTurbo();
uint32_t* m_drawContext; uint32_t* m_drawContext;
GBAThread m_threadContext; GBAThread m_threadContext;
@ -177,8 +179,10 @@ private:
bool m_videoSync; bool m_videoSync;
bool m_audioSync; bool m_audioSync;
float m_fpsTarget;
bool m_turbo; bool m_turbo;
bool m_turboForced; bool m_turboForced;
float m_turboSpeed;
int m_stateSlot; int m_stateSlot;

View File

@ -787,6 +787,19 @@ void Window::setupMenu(QMenuBar* menubar) {
connect(turbo, SIGNAL(triggered(bool)), m_controller, SLOT(setTurbo(bool))); connect(turbo, SIGNAL(triggered(bool)), m_controller, SLOT(setTurbo(bool)));
addControlledAction(emulationMenu, turbo, "fastForward"); addControlledAction(emulationMenu, turbo, "fastForward");
QMenu* ffspeedMenu = emulationMenu->addMenu(tr("Fast forward speed"));
ConfigOption* ffspeed = m_config->addOption("fastForwardRatio");
ffspeed->connect([this](const QVariant& value) {
m_controller->setTurboSpeed(value.toFloat());
}, this);
ffspeed->addValue(tr("Unbounded"), -1.0f, ffspeedMenu);
ffspeed->setValue(QVariant(-1.0f));
ffspeedMenu->addSeparator();
for (i = 2; i < 6; ++i) {
ffspeed->addValue(tr("%0x").arg(i), i, ffspeedMenu);
}
m_config->updateOption("fastForwardRatio");
QAction* rewind = new QAction(tr("Re&wind"), emulationMenu); QAction* rewind = new QAction(tr("Re&wind"), emulationMenu);
rewind->setShortcut(tr("`")); rewind->setShortcut(tr("`"));
connect(rewind, SIGNAL(triggered()), m_controller, SLOT(rewind())); connect(rewind, SIGNAL(triggered()), m_controller, SLOT(rewind()));