From 9a0640f8346a76e9e6b68d1eaca15eb068541337 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 21 Dec 2014 17:48:36 -0800 Subject: [PATCH] GBA: Add option to skip BIOS start screen --- CHANGES | 1 + src/gba/gba-config.c | 4 ++++ src/gba/gba-config.h | 1 + src/gba/gba-thread.c | 7 +++++++ src/gba/gba-thread.h | 2 ++ src/gba/gba.c | 10 ++++++++++ src/gba/gba.h | 1 + src/platform/qt/GameController.cpp | 6 ++++++ src/platform/qt/GameController.h | 1 + src/platform/qt/SettingsView.cpp | 2 ++ src/platform/qt/SettingsView.ui | 3 --- src/platform/qt/Window.cpp | 4 ++++ 12 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 0a68166af..9019d46b6 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Features: - Better audio resampling via FFmpeg - Settings window - Bilinear resampling option + - Add option to skip BIOS start screen Bugfixes: - Qt: Fix issue with set frame sizes being the wrong height - Qt: Fix emulator crashing when full screen if a game is not running diff --git a/src/gba/gba-config.c b/src/gba/gba-config.c index 88ff83300..d647ca113 100644 --- a/src/gba/gba-config.c +++ b/src/gba/gba-config.c @@ -202,6 +202,9 @@ void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) { if (_lookupIntValue(config, "resampleVideo", &fakeBool)) { opts->resampleVideo = fakeBool; } + if (_lookupIntValue(config, "skipBios", &fakeBool)) { + opts->skipBios = fakeBool; + } _lookupIntValue(config, "fullscreen", &opts->fullscreen); _lookupIntValue(config, "width", &opts->width); @@ -210,6 +213,7 @@ void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) { void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* opts) { ConfigurationSetValue(&config->defaultsTable, 0, "bios", opts->bios); + 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, "rewindBufferCapacity", opts->rewindBufferCapacity); diff --git a/src/gba/gba-config.h b/src/gba/gba-config.h index d07b21981..776aed75d 100644 --- a/src/gba/gba-config.h +++ b/src/gba/gba-config.h @@ -18,6 +18,7 @@ struct GBAConfig { struct GBAOptions { char* bios; + bool skipBios; int logLevel; int frameskip; int rewindBufferCapacity; diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index cb8909a6f..11ab2eb97 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -156,6 +156,9 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { } ARMReset(&cpu); + if (threadContext->skipBios) { + GBASkipBIOS(&cpu); + } if (threadContext->debugger) { threadContext->debugger->log = GBADebuggerLogShim; @@ -208,6 +211,9 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { MutexUnlock(&threadContext->stateMutex); if (resetScheduled) { ARMReset(&cpu); + if (threadContext->skipBios) { + GBASkipBIOS(&cpu); + } } } @@ -236,6 +242,7 @@ void GBAMapOptionsToContext(const struct GBAOptions* opts, struct GBAThread* thr threadContext->logLevel = opts->logLevel; threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; threadContext->rewindBufferInterval = opts->rewindBufferInterval; + threadContext->skipBios = opts->skipBios; threadContext->sync.audioWait = opts->audioSync; threadContext->sync.videoFrameWait = opts->videoSync; diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index e047d5137..5039d3941 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -98,6 +98,8 @@ struct GBAThread { int rewindBufferNext; struct GBASerializedState** rewindBuffer; int rewindBufferWriteOffset; + + bool skipBios; }; void GBAMapOptionsToContext(const struct GBAOptions*, struct GBAThread*); diff --git a/src/gba/gba.c b/src/gba/gba.c index 643782aae..398d603a4 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -11,6 +11,8 @@ #include "gba-sio.h" #include "gba-thread.h" +#include "isa-inlines.h" + #include "util/crc32.h" #include "util/memory.h" #include "util/patch.h" @@ -220,6 +222,14 @@ void GBAReset(struct ARMCore* cpu) { memset(gba->timers, 0, sizeof(gba->timers)); } +void GBASkipBIOS(struct ARMCore* cpu) { + if (cpu->gprs[ARM_PC] == BASE_RESET + WORD_SIZE_ARM) { + cpu->gprs[ARM_PC] = BASE_CART0; + int currentCycles = 0; + ARM_WRITE_PC; + } +} + static void GBAProcessEvents(struct ARMCore* cpu) { do { struct GBA* gba = (struct GBA*) cpu->master; diff --git a/src/gba/gba.h b/src/gba/gba.h index 5dadb216f..5f104278e 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -147,6 +147,7 @@ void GBACreate(struct GBA* gba); void GBADestroy(struct GBA* gba); void GBAReset(struct ARMCore* cpu); +void GBASkipBIOS(struct ARMCore* cpu); void GBATimerUpdateRegister(struct GBA* gba, int timer); void GBATimerWriteTMCNT_LO(struct GBA* gba, int timer, uint16_t value); diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index b999fcba1..aa5970e73 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -295,6 +295,12 @@ void GameController::setFPSTarget(float fps) { QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged"); } +void GameController::setSkipBIOS(bool set) { + threadInterrupt(); + m_threadContext.skipBios = set; + threadContinue(); +} + void GameController::loadState(int slot) { threadInterrupt(); GBALoadState(m_threadContext.gba, m_threadContext.stateDir, slot); diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index b3b89ca19..b4b1d55c8 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -72,6 +72,7 @@ signals: public slots: void loadGame(const QString& path, bool dirmode = false); void loadBIOS(const QString& path); + void setSkipBIOS(bool); void loadPatch(const QString& path); void openGame(); void closeGame(); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index ae837f7af..b698cc4d6 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -18,6 +18,7 @@ SettingsView::SettingsView(ConfigController* controller, QWidget* parent) m_ui.setupUi(this); loadSetting("bios", m_ui.bios); + loadSetting("skipBios", m_ui.skipBios); loadSetting("audioBuffers", m_ui.audioBufferSize); loadSetting("videoSync", m_ui.videoSync); loadSetting("audioSync", m_ui.audioSync); @@ -40,6 +41,7 @@ void SettingsView::selectBios() { void SettingsView::updateConfig() { saveSetting("bios", m_ui.bios); + saveSetting("skipBios", m_ui.skipBios); saveSetting("audioBuffers", m_ui.audioBufferSize); saveSetting("videoSync", m_ui.videoSync); saveSetting("audioSync", m_ui.audioSync); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index aea709d89..c5c200db5 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -49,9 +49,6 @@ - - false - Skip BIOS intro diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index b6dde5a31..4cd277b51 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -137,6 +137,7 @@ void Window::loadConfig() { m_controller->setFrameskip(opts->frameskip); m_controller->setAudioSync(opts->audioSync); m_controller->setVideoSync(opts->videoSync); + m_controller->setSkipBIOS(opts->skipBios); m_display->lockAspectRatio(opts->lockAspectRatio); m_display->filter(opts->resampleVideo); @@ -611,6 +612,9 @@ void Window::setupMenu(QMenuBar* menubar) { debuggingMenu->addAction(gdbWindow); #endif + ConfigOption* skipBios = m_config->addOption("skipBios"); + skipBios->connect([this](const QVariant& value) { m_controller->setSkipBIOS(value.toBool()); }); + foreach (QAction* action, m_gameActions) { action->setDisabled(true); }