diff --git a/src/gba/gba-input.c b/src/gba/gba-input.c index 31d0feb26..0a41bd9ad 100644 --- a/src/gba/gba-input.c +++ b/src/gba/gba-input.c @@ -45,9 +45,9 @@ void GBAInputMapDeinit(struct GBAInputMap* map) { map->numMaps = 0; } -enum GBAKey GBAInputMapKey(struct GBAInputMap* map, uint32_t type, int key) { +enum GBAKey GBAInputMapKey(const struct GBAInputMap* map, uint32_t type, int key) { size_t m; - struct GBAInputMapImpl* impl = 0; + const struct GBAInputMapImpl* impl = 0; for (m = 0; m < map->numMaps; ++m) { if (map->maps[m].type == type) { impl = &map->maps[m]; diff --git a/src/gba/gba-input.h b/src/gba/gba-input.h index 3fa3b9bd9..2f785540b 100644 --- a/src/gba/gba-input.h +++ b/src/gba/gba-input.h @@ -13,7 +13,7 @@ struct GBAInputMap { void GBAInputMapInit(struct GBAInputMap*); void GBAInputMapDeinit(struct GBAInputMap*); -enum GBAKey GBAInputMapKey(struct GBAInputMap*, uint32_t type, int key); +enum GBAKey GBAInputMapKey(const struct GBAInputMap*, uint32_t type, int key); void GBAInputBindKey(struct GBAInputMap*, uint32_t type, int key, enum GBAKey input); void GBAInputMapLoad(struct GBAInputMap*, uint32_t type, const struct Configuration*); diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index 38a63d943..9a2673a21 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -390,8 +390,6 @@ void GBAThreadJoin(struct GBAThread* threadContext) { } free(threadContext->rewindBuffer); - GBAInputMapDeinit(&threadContext->inputMap); - if (threadContext->rom) { threadContext->rom->close(threadContext->rom); threadContext->rom = 0; diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index a16846af1..cde49d378 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -63,7 +63,6 @@ struct GBAThread { struct VFile* patch; const char* fname; int activeKeys; - struct GBAInputMap inputMap; struct GBAAVStream* stream; // Run-time options diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 37f49ffd5..c044c4591 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -35,6 +35,7 @@ set(SOURCE_FILES Display.cpp GBAApp.cpp GameController.cpp + InputController.cpp LoadSaveState.cpp LogView.cpp SavestateButton.cpp diff --git a/src/platform/qt/ConfigController.h b/src/platform/qt/ConfigController.h index 81b1036d9..a817f7bf1 100644 --- a/src/platform/qt/ConfigController.h +++ b/src/platform/qt/ConfigController.h @@ -57,6 +57,9 @@ public: const GBAOptions* options() const { return &m_opts; } bool parseArguments(GBAArguments* args, int argc, char* argv[]); + const Configuration* configuration() const { return &m_config.configTable; } + const Configuration* defaults() const { return &m_config.defaultsTable; } + ConfigOption* addOption(const char* key); void updateOption(const char* key); diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index cad0bb746..ab602738f 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -14,6 +14,10 @@ GBAApp::GBAApp(int& argc, char* argv[]) : QApplication(argc, argv) , m_window(&m_configController) { +#ifdef BUILD_SDL + SDL_Init(SDL_INIT_NOPARACHUTE); +#endif + QApplication::setApplicationName(PROJECT_NAME); QApplication::setApplicationVersion(PROJECT_VERSION); diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index 6c28edfe7..fac8578b7 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -1,6 +1,7 @@ #include "GameController.h" #include "AudioProcessor.h" +#include "InputController.h" #include @@ -26,6 +27,7 @@ GameController::GameController(QObject* parent) , m_audioSync(AUDIO_SYNC) , m_turbo(false) , m_turboForced(false) + , m_inputController(nullptr) { m_renderer = new GBAVideoSoftwareRenderer; GBAVideoSoftwareRendererCreate(m_renderer); @@ -40,15 +42,6 @@ GameController::GameController(QObject* parent) m_threadContext.rewindBufferCapacity = 0; m_threadContext.logLevel = -1; - GBAInputMapInit(&m_threadContext.inputMap); - -#ifdef BUILD_SDL - SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE); - m_sdlEvents.bindings = &m_threadContext.inputMap; - GBASDLInitEvents(&m_sdlEvents); - SDL_JoystickEventState(SDL_QUERY); -#endif - m_threadContext.startCallback = [] (GBAThread* context) { GameController* controller = static_cast(context->userData); controller->m_audioProcessor->setInput(context); @@ -94,7 +87,6 @@ GameController::~GameController() { m_audioThread->wait(); disconnect(); closeGame(); - GBAInputMapDeinit(&m_threadContext.inputMap); delete m_renderer; delete[] m_drawContext; } @@ -352,36 +344,11 @@ void GameController::updateKeys() { #ifdef BUILD_SDL void GameController::testSDLEvents() { - SDL_Joystick* joystick = m_sdlEvents.joystick; - SDL_JoystickUpdate(); - int numButtons = SDL_JoystickNumButtons(joystick); - m_activeButtons = 0; - int i; - for (i = 0; i < numButtons; ++i) { - GBAKey key = GBAInputMapKey(&m_threadContext.inputMap, SDL_BINDING_BUTTON, i); - if (key == GBA_KEY_NONE) { - continue; - } - if (SDL_JoystickGetButton(joystick, i)) { - m_activeButtons |= 1 << key; - } - } - int numHats = SDL_JoystickNumHats(joystick); - for (i = 0; i < numHats; ++i) { - int hat = SDL_JoystickGetHat(joystick, i); - if (hat & SDL_HAT_UP) { - m_activeButtons |= 1 << GBA_KEY_UP; - } - if (hat & SDL_HAT_LEFT) { - m_activeButtons |= 1 << GBA_KEY_LEFT; - } - if (hat & SDL_HAT_DOWN) { - m_activeButtons |= 1 << GBA_KEY_DOWN; - } - if (hat & SDL_HAT_RIGHT) { - m_activeButtons |= 1 << GBA_KEY_RIGHT; - } + if (!m_inputController) { + return; } + + m_activeButtons = m_inputController->testSDLEvents(); updateKeys(); } #endif diff --git a/src/platform/qt/GameController.h b/src/platform/qt/GameController.h index 9db10c165..d90903e70 100644 --- a/src/platform/qt/GameController.h +++ b/src/platform/qt/GameController.h @@ -22,6 +22,7 @@ class QThread; namespace QGBA { class AudioProcessor; +class InputController; class GameController : public QObject { Q_OBJECT @@ -42,6 +43,8 @@ public: bool audioSync() const { return m_audioSync; } bool videoSync() const { return m_videoSync; } + void setInputController(InputController* controller) { m_inputController = controller; } + #ifdef USE_GDB_STUB ARMDebugger* debugger(); void setDebugger(ARMDebugger*); @@ -113,6 +116,8 @@ private: bool m_audioSync; bool m_turbo; bool m_turboForced; + + InputController* m_inputController; }; } diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp new file mode 100644 index 000000000..4470e16e9 --- /dev/null +++ b/src/platform/qt/InputController.cpp @@ -0,0 +1,89 @@ +#include "InputController.h" + +#include + +extern "C" { +#include "util/configuration.h" +} + +using namespace QGBA; + +InputController::InputController() { + GBAInputMapInit(&m_inputMap); + +#ifdef BUILD_SDL + m_sdlEvents.bindings = &m_inputMap; + GBASDLInitEvents(&m_sdlEvents); + SDL_JoystickEventState(SDL_QUERY); +#endif + + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_A, GBA_KEY_L); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_S, GBA_KEY_R); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Return, GBA_KEY_START); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Backspace, GBA_KEY_SELECT); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Up, GBA_KEY_UP); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Down, GBA_KEY_DOWN); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Left, GBA_KEY_LEFT); + GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Right, GBA_KEY_RIGHT); +} + +InputController::~InputController() { + GBAInputMapDeinit(&m_inputMap); + +#ifdef BUILD_SDL + GBASDLDeinitEvents(&m_sdlEvents); +#endif +} + +void InputController::loadDefaultConfiguration(const Configuration* config) { + loadConfiguration(KEYBOARD, config); +#ifdef BUILD_SDL + loadConfiguration(SDL_BINDING_BUTTON, config); +#endif +} + +void InputController::loadConfiguration(uint32_t type, const Configuration* config) { + GBAInputMapLoad(&m_inputMap, type, config); +} + +GBAKey InputController::mapKeyboard(int key) const { + return GBAInputMapKey(&m_inputMap, KEYBOARD, key); +} + +#ifdef BUILD_SDL +int InputController::testSDLEvents() { + SDL_Joystick* joystick = m_sdlEvents.joystick; + SDL_JoystickUpdate(); + int numButtons = SDL_JoystickNumButtons(joystick); + int activeButtons = 0; + int i; + for (i = 0; i < numButtons; ++i) { + GBAKey key = GBAInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i); + if (key == GBA_KEY_NONE) { + continue; + } + if (SDL_JoystickGetButton(joystick, i)) { + activeButtons |= 1 << key; + } + } + int numHats = SDL_JoystickNumHats(joystick); + for (i = 0; i < numHats; ++i) { + int hat = SDL_JoystickGetHat(joystick, i); + if (hat & SDL_HAT_UP) { + activeButtons |= 1 << GBA_KEY_UP; + } + if (hat & SDL_HAT_LEFT) { + activeButtons |= 1 << GBA_KEY_LEFT; + } + if (hat & SDL_HAT_DOWN) { + activeButtons |= 1 << GBA_KEY_DOWN; + } + if (hat & SDL_HAT_RIGHT) { + activeButtons |= 1 << GBA_KEY_RIGHT; + } + } + return activeButtons; +} +#endif diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h new file mode 100644 index 000000000..fb4593341 --- /dev/null +++ b/src/platform/qt/InputController.h @@ -0,0 +1,42 @@ +#ifndef QGBA_INPUT_CONTROLLER_H +#define QGBA_INPUT_CONTROLLER_H + +extern "C" { +#include "gba-input.h" + +#ifdef BUILD_SDL +#include "platform/sdl/sdl-events.h" +#endif +} + +struct Configuration; + +namespace QGBA { + +class InputController { +public: + static const uint32_t KEYBOARD = 0x51545F4B; + + InputController(); + ~InputController(); + + void loadDefaultConfiguration(const Configuration* config); + void loadConfiguration(uint32_t type, const Configuration* config); + + GBAKey mapKeyboard(int key) const; + +#ifdef BUILD_SDL + int testSDLEvents(); +#endif + +private: + GBAInputMap m_inputMap; + +#ifdef BUILD_SDL + GBASDLEvents m_sdlEvents; +#endif +}; + +} + +#endif diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index e8d0deb27..e59624d90 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -36,6 +36,7 @@ Window::Window(ConfigController* config, QWidget* parent) { setWindowTitle(PROJECT_NAME); m_controller = new GameController(this); + m_controller->setInputController(&m_inputController); QGLFormat format(QGLFormat(QGL::Rgba | QGL::DoubleBuffer)); format.setSwapInterval(1); @@ -66,43 +67,6 @@ Window::~Window() { delete m_videoView; } -GBAKey Window::mapKey(int qtKey) { - switch (qtKey) { - case Qt::Key_Z: - return GBA_KEY_A; - break; - case Qt::Key_X: - return GBA_KEY_B; - break; - case Qt::Key_A: - return GBA_KEY_L; - break; - case Qt::Key_S: - return GBA_KEY_R; - break; - case Qt::Key_Return: - return GBA_KEY_START; - break; - case Qt::Key_Backspace: - return GBA_KEY_SELECT; - break; - case Qt::Key_Up: - return GBA_KEY_UP; - break; - case Qt::Key_Down: - return GBA_KEY_DOWN; - break; - case Qt::Key_Left: - return GBA_KEY_LEFT; - break; - case Qt::Key_Right: - return GBA_KEY_RIGHT; - break; - default: - return GBA_KEY_NONE; - } -} - void Window::argumentsPassed(GBAArguments* args) { loadConfig(); @@ -143,6 +107,8 @@ void Window::loadConfig() { if (opts->width && opts->height) { m_screenWidget->setSizeHint(QSize(opts->width, opts->height)); } + + m_inputController.loadDefaultConfiguration(m_config->configuration()); } void Window::saveConfig() { @@ -202,7 +168,7 @@ void Window::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Tab) { m_controller->setTurbo(true, false); } - GBAKey key = mapKey(event->key()); + GBAKey key = m_inputController.mapKeyboard(event->key()); if (key == GBA_KEY_NONE) { QWidget::keyPressEvent(event); return; @@ -219,7 +185,7 @@ void Window::keyReleaseEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Tab) { m_controller->setTurbo(false, false); } - GBAKey key = mapKey(event->key()); + GBAKey key = m_inputController.mapKeyboard(event->key()); if (key == GBA_KEY_NONE) { QWidget::keyPressEvent(event); return; diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 41c05e8c0..a6e7fb350 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -10,6 +10,7 @@ extern "C" { #include "GDBController.h" #include "Display.h" +#include "InputController.h" #include "LoadSaveState.h" struct GBAOptions; @@ -32,8 +33,6 @@ public: GameController* controller() { return m_controller; } - static GBAKey mapKey(int qtKey); - void setConfig(ConfigController*); void argumentsPassed(GBAArguments*); @@ -85,6 +84,7 @@ private: WindowBackground* m_screenWidget; QPixmap m_logo; ConfigController* m_config; + InputController m_inputController; #ifdef USE_FFMPEG VideoView* m_videoView; diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 12d55d168..4620abbfb 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -31,6 +31,9 @@ int main(int argc, char** argv) { struct SDLSoftwareRenderer renderer; GBAVideoSoftwareRendererCreate(&renderer.d); + struct GBAInputMap inputMap; + GBAInputMapInit(&inputMap); + struct GBAConfig config; GBAConfigInit(&config, PORT); GBAConfigLoad(&config); @@ -88,7 +91,8 @@ int main(int argc, char** argv) { renderer.audio.samples = context.audioBuffers; GBASDLInitAudio(&renderer.audio); - renderer.events.bindings = &context.inputMap; + renderer.events.bindings = &inputMap; + GBASDLInitindings(&inputMap); GBASDLInitEvents(&renderer.events); GBASDLEventsLoadConfig(&renderer.events, &config.configTable); // TODO: Don't use this directly @@ -101,6 +105,7 @@ int main(int argc, char** argv) { GBAConfigFreeOpts(&opts); GBAConfigDeinit(&config); free(context.debugger); + GBAInputMapDeinit(&inputMap); _GBASDLDeinit(&renderer); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 67d39cb47..328ff5632 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -14,52 +14,56 @@ #define GUI_MOD KMOD_CTRL #endif +static int _openContexts = 0; + bool GBASDLInitEvents(struct GBASDLEvents* context) { - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { + if (!_openContexts && SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { return false; } + ++_openContexts; SDL_JoystickEventState(SDL_ENABLE); context->joystick = SDL_JoystickOpen(0); #if !SDL_VERSION_ATLEAST(2, 0, 0) SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); #endif + return true; +} +void GBASDLInitindings(struct GBAInputMap* inputMap) { #if SDL_VERSION_ATLEAST(2, 0, 0) - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_X, GBA_KEY_A); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_Z, GBA_KEY_B); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_A, GBA_KEY_L); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_S, GBA_KEY_R); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_RETURN, GBA_KEY_START); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_BACKSPACE, GBA_KEY_SELECT); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_UP, GBA_KEY_UP); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_DOWN, GBA_KEY_DOWN); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_LEFT, GBA_KEY_LEFT); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDL_SCANCODE_RIGHT, GBA_KEY_RIGHT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_X, GBA_KEY_A); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_Z, GBA_KEY_B); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_A, GBA_KEY_L); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_S, GBA_KEY_R); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RETURN, GBA_KEY_START); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_BACKSPACE, GBA_KEY_SELECT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_UP, GBA_KEY_UP); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_DOWN, GBA_KEY_DOWN); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_LEFT, GBA_KEY_LEFT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDL_SCANCODE_RIGHT, GBA_KEY_RIGHT); #else - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_s, GBA_KEY_R); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_RETURN, GBA_KEY_START); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_BACKSPACE, GBA_KEY_SELECT); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); - GBAInputBindKey(context->bindings, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_s, GBA_KEY_R); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RETURN, GBA_KEY_START); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_BACKSPACE, GBA_KEY_SELECT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); + GBAInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); #endif - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 13, GBA_KEY_A); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 14, GBA_KEY_B); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 10, GBA_KEY_L); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 11, GBA_KEY_R); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 3, GBA_KEY_START); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 0, GBA_KEY_SELECT); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 4, GBA_KEY_UP); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 6, GBA_KEY_DOWN); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 7, GBA_KEY_LEFT); - GBAInputBindKey(context->bindings, SDL_BINDING_BUTTON, 5, GBA_KEY_RIGHT); - - return true; + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 13, GBA_KEY_A); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 14, GBA_KEY_B); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 10, GBA_KEY_L); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 11, GBA_KEY_R); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 3, GBA_KEY_START); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 0, GBA_KEY_SELECT); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 4, GBA_KEY_UP); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 6, GBA_KEY_DOWN); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 7, GBA_KEY_LEFT); + GBAInputBindKey(inputMap, SDL_BINDING_BUTTON, 5, GBA_KEY_RIGHT); } void GBASDLEventsLoadConfig(struct GBASDLEvents* context, const struct Configuration* config) { @@ -69,7 +73,11 @@ void GBASDLEventsLoadConfig(struct GBASDLEvents* context, const struct Configura void GBASDLDeinitEvents(struct GBASDLEvents* context) { SDL_JoystickClose(context->joystick); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + + --_openContexts; + if (!_openContexts) { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } } static void _pauseAfterFrame(struct GBAThread* context) { @@ -81,9 +89,9 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents enum GBAKey key = GBA_KEY_NONE; if (!event->keysym.mod) { #if SDL_VERSION_ATLEAST(2, 0, 0) - key = GBAInputMapKey(&context->inputMap, SDL_BINDING_KEY, event->keysym.scancode); + key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.scancode); #else - key = GBAInputMapKey(&context->inputMap, SDL_BINDING_KEY, event->keysym.sym); + key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_KEY, event->keysym.sym); #endif } if (key != GBA_KEY_NONE) { @@ -225,9 +233,9 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents } } -static void _GBASDLHandleJoyButton(struct GBAThread* context, const struct SDL_JoyButtonEvent* event) { +static void _GBASDLHandleJoyButton(struct GBAThread* context, struct GBASDLEvents* sdlContext, const struct SDL_JoyButtonEvent* event) { enum GBAKey key = 0; - key = GBAInputMapKey(&context->inputMap, SDL_BINDING_BUTTON, event->button); + key = GBAInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button); if (key == GBA_KEY_NONE) { return; } @@ -286,7 +294,7 @@ void GBASDLHandleEvent(struct GBAThread* context, struct GBASDLEvents* sdlContex break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: - _GBASDLHandleJoyButton(context, &event->jbutton); + _GBASDLHandleJoyButton(context, sdlContext, &event->jbutton); break; case SDL_JOYHATMOTION: _GBASDLHandleJoyHat(context, &event->jhat); diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index cf261df7f..186b31ed5 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -26,6 +26,7 @@ struct GBASDLEvents { bool GBASDLInitEvents(struct GBASDLEvents*); void GBASDLDeinitEvents(struct GBASDLEvents*); +void GBASDLInitindings(struct GBAInputMap* inputMap); void GBASDLEventsLoadConfig(struct GBASDLEvents*, const struct Configuration*); void GBASDLHandleEvent(struct GBAThread* context, struct GBASDLEvents* sdlContext, const union SDL_Event* event);