From 7ed4f38bdda9bc22d41a34ad01abe21e67934781 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 23 Jan 2017 09:57:41 -0800 Subject: [PATCH] Qt: Revamp BIOS handling --- include/mgba/core/config.h | 2 + src/core/config.c | 8 + src/gb/core.c | 43 +++- src/gba/core.c | 42 +++- src/platform/qt/GameController.cpp | 34 +-- src/platform/qt/GameController.h | 2 +- src/platform/qt/SettingsView.cpp | 25 ++- src/platform/qt/SettingsView.h | 6 +- src/platform/qt/SettingsView.ui | 334 ++++++++++++++++------------- src/platform/qt/Window.cpp | 28 +-- src/platform/qt/Window.h | 1 - 11 files changed, 314 insertions(+), 211 deletions(-) diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index 6fe37ce6d..2fac1ff37 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -84,6 +84,8 @@ void mCoreConfigSetOverrideIntValue(struct mCoreConfig*, const char* key, int va void mCoreConfigSetOverrideUIntValue(struct mCoreConfig*, const char* key, unsigned value); void mCoreConfigSetOverrideFloatValue(struct mCoreConfig*, const char* key, float value); +void mCoreConfigCopyValue(struct mCoreConfig* config, const struct mCoreConfig* src, const char* key); + void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts); void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts); diff --git a/src/core/config.c b/src/core/config.c index 0a2d146b3..659efd3e8 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -306,6 +306,14 @@ void mCoreConfigSetOverrideFloatValue(struct mCoreConfig* config, const char* ke ConfigurationSetFloatValue(&config->overridesTable, config->port, key, value); } +void mCoreConfigCopyValue(struct mCoreConfig* config, const struct mCoreConfig* src, const char* key) { + const char* value = mCoreConfigGetValue(src, key); + if (!value) { + return; + } + mCoreConfigSetValue(config, key, value); +} + void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts) { _lookupCharValue(config, "bios", &opts->bios); _lookupCharValue(config, "shader", &opts->shader); diff --git a/src/gb/core.c b/src/gb/core.c index a252102cd..df64296c9 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -103,6 +103,8 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf gb->audio.masterVolume = core->opts.volume; } gb->video.frameskip = core->opts.frameskip; + mCoreConfigCopyValue(&core->config, config, "gb.bios"); + mCoreConfigCopyValue(&core->config, config, "gbc.bios"); #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 struct GBCore* gbcore = (struct GBCore*) core; @@ -238,8 +240,8 @@ static void _GBCoreReset(struct mCore* core) { } #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 - struct VFile* bios = NULL; - if (core->opts.useBios) { + if (!gb->biosVf && core->opts.useBios) { + struct VFile* bios = NULL; bool found = false; if (core->opts.bios) { bios = VFileOpen(core->opts.bios, O_RDONLY); @@ -251,8 +253,31 @@ static void _GBCoreReset(struct mCore* core) { } } if (!found) { - char path[PATH_MAX]; GBDetectModel(gb); + const char* configPath; + + switch (gb->model) { + case GB_MODEL_DMG: + case GB_MODEL_SGB: // TODO + configPath = mCoreConfigGetValue(&core->config, "gb.bios"); + break; + case GB_MODEL_CGB: + case GB_MODEL_AGB: + configPath = mCoreConfigGetValue(&core->config, "gbc.bios"); + break; + default: + break; + }; + bios = VFileOpen(configPath, O_RDONLY); + if (bios && GBIsBIOS(bios)) { + found = true; + } else if (bios) { + bios->close(bios); + bios = NULL; + } + } + if (!found) { + char path[PATH_MAX]; mCoreConfigDirectory(path, PATH_MAX); switch (gb->model) { case GB_MODEL_DMG: @@ -267,10 +292,16 @@ static void _GBCoreReset(struct mCore* core) { break; }; bios = VFileOpen(path, O_RDONLY); + if (bios && GBIsBIOS(bios)) { + found = true; + } else if (bios) { + bios->close(bios); + bios = NULL; + } + } + if (bios) { + GBLoadBIOS(gb, bios); } - } - if (bios) { - GBLoadBIOS(gb, bios); } #endif diff --git a/src/gba/core.c b/src/gba/core.c index 6d1944759..41f038427 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -135,6 +135,8 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con } } + mCoreConfigCopyValue(&core->config, config, "gba.bios"); + #ifndef DISABLE_THREADING mCoreConfigGetIntValue(config, "threadedVideo", &gbacore->threadedVideo); #endif @@ -280,19 +282,43 @@ static void _GBACoreReset(struct mCore* core) { } #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 - struct VFile* bios = 0; - if (core->opts.useBios) { - if (!core->opts.bios) { + if (!gba->biosVf && core->opts.useBios) { + struct VFile* bios = NULL; + bool found = false; + if (core->opts.bios) { + bios = VFileOpen(core->opts.bios, O_RDONLY); + if (bios && GBAIsBIOS(bios)) { + found = true; + } else if (bios) { + bios->close(bios); + bios = NULL; + } + } + if (!found) { + const char* configPath = mCoreConfigGetValue(&core->config, "gba.bios"); + bios = VFileOpen(configPath, O_RDONLY); + if (bios && GBAIsBIOS(bios)) { + found = true; + } else if (bios) { + bios->close(bios); + bios = NULL; + } + } + if (!found) { char path[PATH_MAX]; mCoreConfigDirectory(path, PATH_MAX); strncat(path, PATH_SEP "gba_bios.bin", PATH_MAX - strlen(path)); bios = VFileOpen(path, O_RDONLY); - } else { - bios = VFileOpen(core->opts.bios, O_RDONLY); + if (bios && GBIsBIOS(bios)) { + found = true; + } else if (bios) { + bios->close(bios); + bios = NULL; + } + } + if (bios) { + GBALoadBIOS(gba, bios); } - } - if (bios) { - GBALoadBIOS(gba, bios); } #endif diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index a86fbf8ac..8c9f7a3a1 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -394,9 +394,6 @@ void GameController::openGame(bool biosOnly) { if (m_fname.isEmpty()) { biosOnly = true; } - if (biosOnly && (!m_useBios || m_bios.isNull())) { - return; - } if (isLoaded()) { // We need to delay if the game is still cleaning up QTimer::singleShot(10, this, SLOT(openGame())); @@ -405,14 +402,17 @@ void GameController::openGame(bool biosOnly) { cleanGame(); } + m_threadContext.core = nullptr; if (!biosOnly) { if (m_vf) { m_threadContext.core = mCoreFindVF(m_vf); } else { m_threadContext.core = mCoreFind(m_fname.toUtf8().constData()); } +#ifdef M_CORE_GBA } else { m_threadContext.core = GBACoreCreate(); +#endif } if (!m_threadContext.core) { @@ -429,12 +429,17 @@ void GameController::openGame(bool biosOnly) { m_threadContext.sync.audioWait = m_audioSync; } m_threadContext.core->init(m_threadContext.core); + mCoreInitConfig(m_threadContext.core, nullptr); unsigned width, height; m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); m_drawContext = new uint32_t[width * height]; m_frontBuffer = new uint32_t[width * height]; + if (m_config) { + mCoreLoadForeignConfig(m_threadContext.core, m_config); + } + QByteArray bytes; if (!biosOnly) { bytes = m_fname.toUtf8(); @@ -447,28 +452,21 @@ void GameController::openGame(bool biosOnly) { } else { bytes = m_bios.toUtf8(); } + if (bytes.isNull()) { + return; + } + char dirname[PATH_MAX]; separatePath(bytes.constData(), dirname, m_threadContext.core->dirs.baseName, 0); mDirectorySetAttachBase(&m_threadContext.core->dirs, VDirOpen(dirname)); m_threadContext.core->setVideoBuffer(m_threadContext.core, m_drawContext, width); - if (!m_bios.isNull() && m_useBios) { - VFile* bios = VFileDevice::open(m_bios, O_RDONLY); - if (bios && !m_threadContext.core->loadBIOS(m_threadContext.core, bios, 0)) { - bios->close(bios); - } - } - m_inputController->recalibrateAxes(); memset(m_drawContext, 0xF8, width * height * 4); m_threadContext.core->setAVStream(m_threadContext.core, m_stream); - if (m_config) { - mCoreLoadForeignConfig(m_threadContext.core, m_config); - } - if (!biosOnly) { mCoreAutoloadSave(m_threadContext.core); if (!m_patch.isNull()) { @@ -488,14 +486,16 @@ void GameController::openGame(bool biosOnly) { } } -void GameController::loadBIOS(const QString& path) { +void GameController::loadBIOS(int platform, const QString& path) { if (m_bios == path) { return; } - m_bios = path; - if (m_gameOpen) { + if (m_gameOpen && this->platform() == platform) { closeGame(); + m_bios = path; openGame(); + } else if (!m_gameOpen) { + m_bios = path; } } diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index 63383ac23..f98bf92c1 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -114,7 +114,7 @@ signals: public slots: void loadGame(const QString& path); void loadGame(VFile* vf, const QString& base); - void loadBIOS(const QString& path); + void loadBIOS(int platform, const QString& path); void loadSave(const QString& path, bool temporary = true); void yankPak(); void replaceGame(const QString& path); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index d4625e13e..9cd49dcbb 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -127,7 +127,15 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC } #endif - connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios())); + connect(m_ui.gbaBiosBrowse, &QPushButton::clicked, [this]() { + selectBios(m_ui.gbaBios); + }); + connect(m_ui.gbBiosBrowse, &QPushButton::clicked, [this]() { + selectBios(m_ui.gbBios); + }); + connect(m_ui.gbcBiosBrowse, &QPushButton::clicked, [this]() { + selectBios(m_ui.gbcBios); + }); GBAKeyEditor* editor = new GBAKeyEditor(inputController, InputController::KEYBOARD, QString(), this); m_ui.stackedWidget->addWidget(editor); @@ -162,15 +170,17 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC m_ui.tabs->addItem("Shortcuts"); } -void SettingsView::selectBios() { +void SettingsView::selectBios(QLineEdit* bios) { QString filename = GBAApp::app()->getOpenFileName(this, tr("Select BIOS")); if (!filename.isEmpty()) { - m_ui.bios->setText(filename); + bios->setText(filename); } } void SettingsView::updateConfig() { - saveSetting("bios", m_ui.bios); + saveSetting("gba.bios", m_ui.gbaBios); + saveSetting("gb.bios", m_ui.gbBios); + saveSetting("gbc.bios", m_ui.gbcBios); saveSetting("useBios", m_ui.useBios); saveSetting("skipBios", m_ui.skipBios); saveSetting("audioBuffers", m_ui.audioBufferSize); @@ -240,11 +250,14 @@ void SettingsView::updateConfig() { m_controller->write(); emit pathsChanged(); - emit biosLoaded(m_ui.bios->text()); + emit biosLoaded(PLATFORM_GBA, m_ui.gbaBios->text()); } void SettingsView::reloadConfig() { - loadSetting("bios", m_ui.bios); + loadSetting("bios", m_ui.gbaBios); + loadSetting("gba.bios", m_ui.gbaBios); + loadSetting("gb.bios", m_ui.gbBios); + loadSetting("gbc.bios", m_ui.gbcBios); loadSetting("useBios", m_ui.useBios); loadSetting("skipBios", m_ui.skipBios); loadSetting("audioBuffers", m_ui.audioBufferSize); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 352604b32..0de77dbf0 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -8,6 +8,8 @@ #include +#include + #include "ui_SettingsView.h" namespace QGBA { @@ -23,13 +25,13 @@ public: SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, QWidget* parent = nullptr); signals: - void biosLoaded(const QString&); + void biosLoaded(int platform, const QString&); void audioDriverChanged(); void displayDriverChanged(); void pathsChanged(); private slots: - void selectBios(); + void selectBios(QLineEdit*); void updateConfig(); void reloadConfig(); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index c896e9db3..e5f7c5fcb 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -6,8 +6,8 @@ 0 0 - 548 - 431 + 650 + 450 @@ -23,13 +23,6 @@ QLayout::SetFixedSize - - - - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -45,7 +38,7 @@ - 0 + -1 @@ -59,7 +52,7 @@ - Savestates + BIOS @@ -69,12 +62,19 @@ + + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + 0 - + QFormLayout::FieldsStayAtSizeHint @@ -110,7 +110,7 @@ true - + 1536 @@ -176,7 +176,7 @@ true - + 44100 @@ -384,110 +384,108 @@ - + QFormLayout::FieldsStayAtSizeHint - + - BIOS file: + Fast forward speed: - + - - - - 0 - 0 - + + + false + + + × + + + 0.010000000000000 + + + 20.000000000000000 + + + 0.500000000000000 + + + 5.000000000000000 - + - Browse + Unbounded + + + true - - - - Use BIOS file if found - - - true - - - - - - - Skip BIOS intro - - - - + Qt::Horizontal - - + + - Fast forward speed + Enable rewind - - - - false - - - × - - - 0.010000000000000 - - - 20.000000000000000 - - - 0.500000000000000 - - - 5.000000000000000 - - - - - + + - Unbounded - - - true + Rewind history: - + + + + + + 3600 + + + + + + + frames + + + + + + Qt::Horizontal - + + + + Allow opposing input directions + + + + Suspend screensaver @@ -497,21 +495,21 @@ - + Pause when inactive - + - Idle loops + Idle loops: - + @@ -530,28 +528,21 @@ - - - - Allow opposing input directions + + + + Qt::Horizontal - - - - - - QFormLayout::FieldsStayAtSizeHint - - + - Save extra data + Savestate extra data: - + Screenshot @@ -561,7 +552,7 @@ - + Save data @@ -571,7 +562,7 @@ - + Cheat codes @@ -581,21 +572,14 @@ - - - - Qt::Horizontal - - - - + - Load extra data + Load extra data: - + Screenshot @@ -605,54 +589,120 @@ - + Save data - + Cheat codes - - - - Qt::Horizontal - - - - - + + + + + + - Enable rewind + GB BIOS file: - - - - Rewind history: - - - - - + + - - - 3600 + + + + 0 + 0 + - + - frames + Browse + + + + + + + + + Use BIOS file if found + + + true + + + + + + + Skip BIOS intro + + + + + + + + + + 0 + 0 + + + + + + + + Browse + + + + + + + + + GBA BIOS file: + + + + + + + GBC BIOS file: + + + + + + + + + + 0 + 0 + + + + + + + + Browse @@ -660,7 +710,7 @@ - + QFormLayout::FieldsStayAtSizeHint @@ -970,21 +1020,5 @@ - - fastForwardUnbounded - toggled(bool) - fastForwardRatio - setDisabled(bool) - - - 338 - 163 - - - 327 - 135 - - - diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index c4233e017..ebd8c4f9b 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -288,10 +288,6 @@ void Window::reloadConfig() { m_display->lockAspectRatio(opts->lockAspectRatio); m_display->filter(opts->resampleVideo); - if (opts->bios) { - m_controller->loadBIOS(opts->bios); - } - m_inputController.setScreensaverSuspendable(opts->suspendScreensaver); } @@ -412,18 +408,6 @@ void Window::multiplayerChanged() { } } -void Window::selectBIOS() { - QString filename = GBAApp::app()->getOpenFileName(this, tr("Select BIOS")); - if (!filename.isEmpty()) { - QFileInfo info(filename); - m_config->setOption("bios", info.canonicalFilePath()); - m_config->updateOption("bios"); - m_config->setOption("useBios", true); - m_config->updateOption("useBios"); - m_controller->loadBIOS(info.canonicalFilePath()); - } -} - void Window::selectPatch() { QString filename = GBAApp::app()->getOpenFileName(this, tr("Select patch"), tr("Patches (*.ips *.ups *.bps)")); if (!filename.isEmpty()) { @@ -453,7 +437,7 @@ void Window::exportSharkport() { void Window::openSettingsWindow() { SettingsView* settingsWindow = new SettingsView(m_config, &m_inputController, m_shortcutController); - connect(settingsWindow, SIGNAL(biosLoaded(const QString&)), m_controller, SLOT(loadBIOS(const QString&))); + connect(settingsWindow, SIGNAL(biosLoaded(int, const QString&)), m_controller, SLOT(loadBIOS(int, const QString&))); connect(settingsWindow, SIGNAL(audioDriverChanged()), m_controller, SLOT(reloadAudioDriver())); connect(settingsWindow, SIGNAL(displayDriverChanged()), this, SLOT(mustRestart())); connect(settingsWindow, SIGNAL(pathsChanged()), this, SLOT(reloadConfig())); @@ -905,15 +889,19 @@ void Window::setupMenu(QMenuBar* menubar) { addControlledAction(fileMenu, fileMenu->addAction(tr("Load ROM in archive..."), this, SLOT(selectROMInArchive())), "loadROMInArchive"); - addControlledAction(fileMenu, fileMenu->addAction(tr("Load &BIOS..."), this, SLOT(selectBIOS())), "loadBIOS"); - QAction* loadTemporarySave = new QAction(tr("Load temporary save..."), fileMenu); connect(loadTemporarySave, &QAction::triggered, [this]() { this->selectSave(true); }); m_gameActions.append(loadTemporarySave); addControlledAction(fileMenu, loadTemporarySave, "loadTemporarySave"); addControlledAction(fileMenu, fileMenu->addAction(tr("Load &patch..."), this, SLOT(selectPatch())), "loadPatch"); - addControlledAction(fileMenu, fileMenu->addAction(tr("Boot BIOS"), m_controller, SLOT(bootBIOS())), "bootBIOS"); + + QAction* bootBIOS = new QAction(tr("Boot BIOS"), fileMenu); + connect(bootBIOS, &QAction::triggered, [this]() { + m_controller->loadBIOS(PLATFORM_GBA, m_config->getOption("gba.bios")); + m_controller->bootBIOS(); + }); + addControlledAction(fileMenu, bootBIOS, "bootBIOS"); addControlledAction(fileMenu, fileMenu->addAction(tr("Replace ROM..."), this, SLOT(replaceROM())), "replaceROM"); diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 847f78b76..58886a6f6 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -61,7 +61,6 @@ public slots: void selectROMInArchive(); #endif void selectSave(bool temporary); - void selectBIOS(); void selectPatch(); void enterFullScreen(); void exitFullScreen();