From 466916729e8b89cb0a24ed62d6ddc90d69ca54f4 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 13 Jan 2015 01:18:07 -0800 Subject: [PATCH] GBA: Configurable game overrides --- CHANGES | 1 + src/gba/gba-overrides.c | 199 +++++++++++++++++++++++++++++ src/gba/gba-overrides.h | 27 ++++ src/gba/gba-thread.c | 9 ++ src/gba/gba-thread.h | 1 + src/gba/gba.c | 144 --------------------- src/platform/perf-main.c | 1 + src/platform/qt/ConfigController.h | 2 + src/platform/qt/GameController.h | 2 + src/platform/qt/Window.cpp | 1 + src/platform/sdl/main.c | 1 + 11 files changed, 244 insertions(+), 144 deletions(-) create mode 100644 src/gba/gba-overrides.c create mode 100644 src/gba/gba-overrides.h diff --git a/CHANGES b/CHANGES index fd524a2c2..40d00cdb7 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ Features: - Support IPv6 - Save directory of last loaded file - Support BPS patches + - Configurable game overrides 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-overrides.c b/src/gba/gba-overrides.c new file mode 100644 index 000000000..d82ccda8f --- /dev/null +++ b/src/gba/gba-overrides.c @@ -0,0 +1,199 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gba-overrides.h" + +#include "gba.h" +#include "gba-gpio.h" + + #include "util/configuration.h" + +static const struct GBACartridgeOverride _overrides[] = { + // Boktai: The Sun is in Your Hand + { "U3IJ", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + { "U3IE", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + { "U3IP", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + + // Boktai 2: Solar Boy Django + { "U32J", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + { "U32E", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + { "U32P", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + + // Drill Dozer + { "V49J", SAVEDATA_SRAM, GPIO_RUMBLE, -1 }, + { "V49E", SAVEDATA_SRAM, GPIO_RUMBLE, -1 }, + + // Final Fantasy Tactics Advance + { "AFXE", SAVEDATA_FLASH512, GPIO_NONE, 0x8000418 }, + + // Koro Koro Puzzle - Happy Panechu! + { "KHPJ", SAVEDATA_EEPROM, GPIO_TILT, -1 }, + + // Mega Man Battle Network + { "AREE", SAVEDATA_SRAM, GPIO_NONE, 0x800032E }, + + // Pokemon Ruby + { "AXVJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVS", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVD", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXVF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + + // Pokemon Sapphire + { "AXPJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPS", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPD", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "AXPF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + + // Pokemon Emerald + { "BPEJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPEE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPEP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPEI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPES", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPED", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + { "BPEF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, + + // Pokemon Mystery Dungeon + { "B24J", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "B24E", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "B24P", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "B24U", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + + // Pokemon FireRed + { "BPRJ", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "BPRE", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "BPRP", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + + // Pokemon LeafGreen + { "BPGJ", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "BPGE", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "BPGP", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + + // RockMan EXE 4.5 - Real Operation + { "BR4J", SAVEDATA_FLASH512, GPIO_RTC, -1 }, + + // Shin Bokura no Taiyou: Gyakushuu no Sabata + { "U33J", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, + + // Super Mario Advance 4 + { "AX4J", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "AX4E", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + { "AX4P", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, + + // Top Gun - Combat Zones + { "A2YE", SAVEDATA_FORCE_NONE, GPIO_NONE, -1 }, + + // Wario Ware Twisted + { "RZWJ", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, + { "RZWE", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, + { "RZWP", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, + + // Yoshi's Universal Gravitation + { "KYGJ", SAVEDATA_EEPROM, GPIO_TILT, -1 }, + { "KYGE", SAVEDATA_EEPROM, GPIO_TILT, -1 }, + { "KYGP", SAVEDATA_EEPROM, GPIO_TILT, -1 }, + + { { 0, 0, 0, 0 }, 0, 0, -1 } +}; + +bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) { + override->savetype = SAVEDATA_AUTODETECT; + override->hardware = GPIO_NONE; + override->idleLoop = -1; + bool found; + + if (override->id[0] == 'F') { + // Classic NES Series + override->savetype = SAVEDATA_EEPROM; + found = true; + } else { + int i; + for (i = 0; _overrides[i].id[0]; ++i) { + if (memcmp(override->id, _overrides[i].id, sizeof(override->id)) == 0) { + *override = _overrides[i]; + found = true; + break; + } + } + } + + if (config) { + char sectionName[16]; + snprintf(sectionName, sizeof(sectionName), "override.%c%c%c%c", override->id[0], override->id[1], override->id[2], override->id[3]); + const char* savetype = ConfigurationGetValue(config, sectionName, "savetype"); + const char* hardware = ConfigurationGetValue(config, sectionName, "hardware"); + const char* idleLoop = ConfigurationGetValue(config, sectionName, "idleLoop"); + + if (savetype) { + if (strcasecmp(savetype, "SRAM") == 0) { + found = true; + override->savetype = SAVEDATA_SRAM; + } else if (strcasecmp(savetype, "EEPROM") == 0) { + found = true; + override->savetype = SAVEDATA_EEPROM; + } else if (strcasecmp(savetype, "FLASH512") == 0) { + found = true; + override->savetype = SAVEDATA_FLASH512; + } else if (strcasecmp(savetype, "FLASH1M") == 0) { + found = true; + override->savetype = SAVEDATA_FLASH1M; + } else if (strcasecmp(savetype, "NONE") == 0) { + found = true; + override->savetype = SAVEDATA_FORCE_NONE; + } + } + + if (hardware) { + char* end; + long type = strtoul(hardware, &end, 0); + if (end && !*end) { + override->hardware = type; + found = true; + } + } + + if (idleLoop) { + char* end; + uint32_t address = strtoul(idleLoop, &end, 16); + if (end && !*end) { + override->idleLoop = address; + found = true; + } + } + } + return found; +} + +void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* override) { + GBASavedataForceType(&gba->memory.savedata, override->savetype); + + if (override->hardware & GPIO_RTC) { + GBAGPIOInitRTC(&gba->memory.gpio); + } + + if (override->hardware & GPIO_GYRO) { + GBAGPIOInitGyro(&gba->memory.gpio); + } + + if (override->hardware & GPIO_RUMBLE) { + GBAGPIOInitRumble(&gba->memory.gpio); + } + + if (override->hardware & GPIO_LIGHT_SENSOR) { + GBAGPIOInitLightSensor(&gba->memory.gpio); + } + + if (override->hardware & GPIO_TILT) { + GBAGPIOInitTilt(&gba->memory.gpio); + } + + gba->busyLoop = override->idleLoop; +} diff --git a/src/gba/gba-overrides.h b/src/gba/gba-overrides.h new file mode 100644 index 000000000..9dbbfe36e --- /dev/null +++ b/src/gba/gba-overrides.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef GBA_OVERRIDES_H +#define GBA_OVERRIDES_H + +#include "util/common.h" + +#include "gba-savedata.h" + +struct GBACartridgeOverride { + char id[4]; + enum SavedataType savetype; + int hardware; + uint32_t idleLoop; +}; + +struct Configuration; +bool GBAOverrideFind(const struct Configuration*, struct GBACartridgeOverride* override); +bool GBAOverrideSave(struct Configuration*, const struct GBACartridgeOverride* override); + +struct GBA; +void GBAOverrideApply(struct GBA*, const struct GBACartridgeOverride*); + +#endif diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index ce0814acd..5226e1f45 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -8,6 +8,7 @@ #include "arm.h" #include "gba.h" #include "gba-config.h" +#include "gba-overrides.h" #include "gba-serialize.h" #include "debugger/debugger.h" @@ -141,6 +142,14 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { if (threadContext->rom) { GBALoadROM(&gba, threadContext->rom, threadContext->save, threadContext->fname); + + struct GBACartridgeOverride override; + const struct GBACartridge* cart = (const struct GBACartridge*) gba.memory.rom; + memcpy(override.id, &cart->id, sizeof(override.id)); + if (GBAOverrideFind(threadContext->overrides, &override)) { + GBAOverrideApply(&gba, &override); + } + if (threadContext->bios && GBAIsBIOS(threadContext->bios)) { GBALoadBIOS(&gba, threadContext->bios); } diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index 4a923ec75..7c1d6e795 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -70,6 +70,7 @@ struct GBAThread { const char* fname; int activeKeys; struct GBAAVStream* stream; + struct Configuration* overrides; // Run-time options int frameskip; diff --git a/src/gba/gba.c b/src/gba/gba.c index 26dab4876..74cf1203f 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -24,107 +24,6 @@ const uint32_t GBA_COMPONENT_MAGIC = 0x1000000; static const size_t GBA_ROM_MAGIC_OFFSET = 2; static const uint8_t GBA_ROM_MAGIC[] = { 0x00, 0xEA }; -struct GBACartridgeOverride { - const char id[4]; - enum SavedataType type; - int gpio; - uint32_t busyLoop; -}; - -static const struct GBACartridgeOverride _overrides[] = { - // Boktai: The Sun is in Your Hand - { "U3IJ", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - { "U3IE", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - { "U3IP", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - - // Boktai 2: Solar Boy Django - { "U32J", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - { "U32E", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - { "U32P", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - - // Drill Dozer - { "V49J", SAVEDATA_SRAM, GPIO_RUMBLE, -1 }, - { "V49E", SAVEDATA_SRAM, GPIO_RUMBLE, -1 }, - - // Final Fantasy Tactics Advance - { "AFXE", SAVEDATA_FLASH512, GPIO_NONE, 0x8000418 }, - - // Koro Koro Puzzle - Happy Panechu! - { "KHPJ", SAVEDATA_EEPROM, GPIO_TILT, -1 }, - - // Mega Man Battle Network - { "AREE", SAVEDATA_SRAM, GPIO_NONE, 0x800032E }, - - // Pokemon Ruby - { "AXVJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVS", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVD", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXVF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - - // Pokemon Sapphire - { "AXPJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPS", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPD", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "AXPF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - - // Pokemon Emerald - { "BPEJ", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPEE", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPEP", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPEI", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPES", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPED", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - { "BPEF", SAVEDATA_FLASH1M, GPIO_RTC, -1 }, - - // Pokemon Mystery Dungeon - { "B24J", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "B24E", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "B24P", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "B24U", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - - // Pokemon FireRed - { "BPRJ", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "BPRE", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "BPRP", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - - // Pokemon LeafGreen - { "BPGJ", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "BPGE", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "BPGP", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - - // RockMan EXE 4.5 - Real Operation - { "BR4J", SAVEDATA_FLASH512, GPIO_RTC, -1 }, - - // Shin Bokura no Taiyou: Gyakushuu no Sabata - { "U33J", SAVEDATA_EEPROM, GPIO_RTC | GPIO_LIGHT_SENSOR, -1 }, - - // Super Mario Advance 4 - { "AX4J", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "AX4E", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - { "AX4P", SAVEDATA_FLASH1M, GPIO_NONE, -1 }, - - // Top Gun - Combat Zones - { "A2YE", SAVEDATA_FORCE_NONE, GPIO_NONE, -1 }, - - // Wario Ware Twisted - { "RZWJ", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, - { "RZWE", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, - { "RZWP", SAVEDATA_SRAM, GPIO_RUMBLE | GPIO_GYRO, -1 }, - - // Yoshi's Universal Gravitation - { "KYGJ", SAVEDATA_EEPROM, GPIO_TILT, -1 }, - { "KYGE", SAVEDATA_EEPROM, GPIO_TILT, -1 }, - { "KYGP", SAVEDATA_EEPROM, GPIO_TILT, -1 }, - - { { 0, 0, 0, 0 }, 0, 0, -1 } -}; - static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component); static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh); static void GBAProcessEvents(struct ARMCore* cpu); @@ -132,8 +31,6 @@ static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); static void GBAIllegal(struct ARMCore* cpu, uint32_t opcode); -static void _checkOverrides(struct GBA* gba, uint32_t code); - void GBACreate(struct GBA* gba) { gba->d.id = GBA_COMPONENT_MAGIC; gba->d.init = GBAInit; @@ -464,7 +361,6 @@ void GBALoadROM(struct GBA* gba, struct VFile* vf, struct VFile* sav, const char gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize); GBASavedataInit(&gba->memory.savedata, sav); GBAGPIOInit(&gba->memory.gpio, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); - _checkOverrides(gba, ((struct GBACartridge*) gba->memory.rom)->id); // TODO: error check } @@ -739,43 +635,3 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) { ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP); } } - -void _checkOverrides(struct GBA* gba, uint32_t id) { - int i; - gba->busyLoop = -1; - if ((id & 0xFF) == 'F') { - GBALog(gba, GBA_LOG_DEBUG, "Found Classic NES Series game, using EEPROM saves"); - GBASavedataInitEEPROM(&gba->memory.savedata); - return; - } - for (i = 0; _overrides[i].id[0]; ++i) { - const uint32_t* overrideId = (const uint32_t*) _overrides[i].id; - if (*overrideId == id) { - GBALog(gba, GBA_LOG_DEBUG, "Found override for game %s!", _overrides[i].id); - GBASavedataForceType(&gba->memory.savedata, _overrides[i].type); - - if (_overrides[i].gpio & GPIO_RTC) { - GBAGPIOInitRTC(&gba->memory.gpio); - } - - if (_overrides[i].gpio & GPIO_GYRO) { - GBAGPIOInitGyro(&gba->memory.gpio); - } - - if (_overrides[i].gpio & GPIO_RUMBLE) { - GBAGPIOInitRumble(&gba->memory.gpio); - } - - if (_overrides[i].gpio & GPIO_LIGHT_SENSOR) { - GBAGPIOInitLightSensor(&gba->memory.gpio); - } - - if (_overrides[i].gpio & GPIO_TILT) { - GBAGPIOInitTilt(&gba->memory.gpio); - } - - gba->busyLoop = _overrides[i].busyLoop; - return; - } - } -} diff --git a/src/platform/perf-main.c b/src/platform/perf-main.c index 27ad38e37..d7487af53 100644 --- a/src/platform/perf-main.c +++ b/src/platform/perf-main.c @@ -76,6 +76,7 @@ int main(int argc, char** argv) { } context.debugger = createDebugger(&args, &context); + context.overrides = &config.configTable; char gameCode[5] = { 0 }; GBAConfigMap(&config, &opts); diff --git a/src/platform/qt/ConfigController.h b/src/platform/qt/ConfigController.h index af9da687b..5b8ed80b3 100644 --- a/src/platform/qt/ConfigController.h +++ b/src/platform/qt/ConfigController.h @@ -75,6 +75,8 @@ public: QList getMRU() const; void setMRU(const QList& mru); + Configuration* overrides() { return &m_config.configTable; } // TODO: Make this not return the whole table + public slots: void setOption(const char* key, bool value); void setOption(const char* key, int value); diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index fc91a8868..453500f32 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -22,6 +22,7 @@ extern "C" { struct GBAAudio; struct GBAVideoSoftwareRenderer; +struct Configuration; class QThread; @@ -53,6 +54,7 @@ public: bool videoSync() const { return m_videoSync; } void setInputController(InputController* controller) { m_inputController = controller; } + void setOverrides(Configuration* overrides) { m_threadContext.overrides = overrides; } #ifdef USE_GDB_STUB ARMDebugger* debugger(); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 44f7a6efb..2da102fbf 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -56,6 +56,7 @@ Window::Window(ConfigController* config, QWidget* parent) setFocusPolicy(Qt::StrongFocus); m_controller = new GameController(this); m_controller->setInputController(&m_inputController); + m_controller->setOverrides(m_config->overrides()); QGLFormat format(QGLFormat(QGL::Rgba | QGL::DoubleBuffer)); format.setSwapInterval(1); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 978a803e4..50331adb1 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -103,6 +103,7 @@ int main(int argc, char** argv) { GBASDLInitBindings(&inputMap); GBASDLInitEvents(&renderer.events); GBASDLEventsLoadConfig(&renderer.events, &config.configTable); // TODO: Don't use this directly + context.overrides = &config.configTable; GBAThreadStart(&context);