diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 7ee90c8d..83e3e3d4 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -9,6 +9,7 @@ set(SOURCES_QT_SDL Window.cpp EmuInstance.cpp EmuInstanceAudio.cpp + EmuInstanceInput.cpp EmuThread.cpp CheatsDialog.cpp Config.cpp @@ -30,7 +31,6 @@ set(SOURCES_QT_SDL ROMInfoDialog.cpp RAMInfoDialog.cpp TitleManagerDialog.cpp - Input.cpp LAN_PCap.cpp LAN_Socket.cpp LocalMP.cpp diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp index 8109a69b..119ec4e2 100644 --- a/src/frontend/qt_sdl/Config.cpp +++ b/src/frontend/qt_sdl/Config.cpp @@ -28,7 +28,7 @@ #include "Platform.h" #include "Config.h" #include "FrontendUtil.h" -#include "Screen.h" +#include "main.h" using namespace std::string_literals; @@ -37,14 +37,6 @@ namespace Config { using namespace melonDS; -int KeyMapping[12]; -int JoyMapping[12]; - -int HKKeyMapping[HK_MAX]; -int HKJoyMapping[HK_MAX]; - -int JoystickID; - int WindowWidth; int WindowHeight; bool WindowMaximized; diff --git a/src/frontend/qt_sdl/Config.h b/src/frontend/qt_sdl/Config.h index fb3eb9a1..66f6dd1d 100644 --- a/src/frontend/qt_sdl/Config.h +++ b/src/frontend/qt_sdl/Config.h @@ -35,45 +35,6 @@ class value; } #endif -enum -{ - HK_Lid = 0, - HK_Mic, - HK_Pause, - HK_Reset, - HK_FastForward, - HK_FastForwardToggle, - HK_FullscreenToggle, - HK_SwapScreens, - HK_SwapScreenEmphasis, - HK_SolarSensorDecrease, - HK_SolarSensorIncrease, - HK_FrameStep, - HK_PowerButton, - HK_VolumeUp, - HK_VolumeDown, - HK_MAX -}; - -enum -{ - micInputType_Silence, - micInputType_External, - micInputType_Noise, - micInputType_Wav, - micInputType_MAX, -}; - -enum -{ - renderer3D_Software = 0, -#ifdef OGLRENDERER_ENABLED - renderer3D_OpenGL, - renderer3D_OpenGLCompute, -#endif - renderer3D_Max, -}; - namespace Config { @@ -188,14 +149,6 @@ private: }; -extern int KeyMapping[12]; -extern int JoyMapping[12]; - -extern int HKKeyMapping[HK_MAX]; -extern int HKJoyMapping[HK_MAX]; - -extern int JoystickID; - extern int WindowWidth; extern int WindowHeight; extern bool WindowMaximized; diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index 5a234995..e35738ad 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -72,6 +72,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst), updateConsole(nullptr, nullptr); audioInit(); + inputInit(); emuThread = new EmuThread(this); @@ -96,6 +97,7 @@ EmuInstance::~EmuInstance() delete emuThread; audioDeInit(); + inputDeInit(); } diff --git a/src/frontend/qt_sdl/EmuInstance.h b/src/frontend/qt_sdl/EmuInstance.h index 9c031d7a..cbe71569 100644 --- a/src/frontend/qt_sdl/EmuInstance.h +++ b/src/frontend/qt_sdl/EmuInstance.h @@ -29,6 +29,48 @@ const int kMaxWindows = 16; +enum +{ + HK_Lid = 0, + HK_Mic, + HK_Pause, + HK_Reset, + HK_FastForward, + HK_FastForwardToggle, + HK_FullscreenToggle, + HK_SwapScreens, + HK_SwapScreenEmphasis, + HK_SolarSensorDecrease, + HK_SolarSensorIncrease, + HK_FrameStep, + HK_PowerButton, + HK_VolumeUp, + HK_VolumeDown, + HK_MAX +}; + +enum +{ + micInputType_Silence, + micInputType_External, + micInputType_Noise, + micInputType_Wav, + micInputType_MAX, +}; + +enum +{ + renderer3D_Software = 0, +#ifdef OGLRENDERER_ENABLED + renderer3D_OpenGL, + renderer3D_OpenGLCompute, +#endif + renderer3D_Max, +}; + +bool isRightModKey(QKeyEvent* event); +int getEventKeyVal(QKeyEvent* event); + class EmuInstance { public: @@ -61,6 +103,17 @@ public: melonDS::u32 (&animatedIconRef)[64][32*32], std::vector &animatedSequenceRef); + static const char* buttonNames[12]; + static const char* hotkeyNames[HK_MAX]; + + void inputInit(); + void inputDeInit(); + void inputLoadConfig(); + + void setJoystick(int id); + int getJoystickID() { return joystickID; } + SDL_Joystick* getJoystick() { return joystick; } + private: static int lastSep(const std::string& path); std::string getAssetPath(bool gba, const std::string& configpath, const std::string& ext, const std::string& file); @@ -130,6 +183,20 @@ private: static void audioCallback(void* data, Uint8* stream, int len); static void micCallback(void* data, Uint8* stream, int len); + void onKeyPress(QKeyEvent* event); + void onKeyRelease(QKeyEvent* event); + void keyReleaseAll(); + + void openJoystick(); + void closeJoystick(); + bool joystickButtonDown(int val); + + void inputProcess(); + + bool hotkeyDown(int id) { return hotkeyMask & (1< +#include + +#include "main.h" +#include "Config.h" + +using namespace melonDS; + +const char* EmuInstance::buttonNames[12] = +{ + "A", + "B", + "Select", + "Start", + "Right", + "Left", + "Up", + "Down", + "R", + "L", + "X", + "Y" +}; + +const char* EmuInstance::hotkeyNames[HK_MAX] = +{ + "HK_Lid", + "HK_Mic", + "HK_Pause", + "HK_Reset", + "HK_FastForward", + "HK_FastForwardToggle", + "HK_FullscreenToggle", + "HK_SwapScreens", + "HK_SwapScreenEmphasis", + "HK_SolarSensorDecrease", + "HK_SolarSensorIncrease", + "HK_FrameStep", + "HK_PowerButton", + "HK_VolumeUp", + "HK_VolumeDown" +}; + + +void EmuInstance::inputInit() +{ + keyInputMask = 0xFFF; + joyInputMask = 0xFFF; + inputMask = 0xFFF; + + keyHotkeyMask = 0; + joyHotkeyMask = 0; + hotkeyMask = 0; + lastHotkeyMask = 0; + + joystick = nullptr; + inputLoadConfig(); +} + +void EmuInstance::inputDeInit() +{ + closeJoystick(); +} + +void EmuInstance::inputLoadConfig() +{ + Config::Table keycfg = localCfg.GetTable("Keyboard"); + Config::Table joycfg = localCfg.GetTable("Joystick"); + + for (int i = 0; i < 12; i++) + { + keyMapping[i] = keycfg.GetInt(buttonNames[i]); + joyMapping[i] = joycfg.GetInt(buttonNames[i]); + } + + for (int i = 0; i < HK_MAX; i++) + { + hkKeyMapping[i] = keycfg.GetInt(hotkeyNames[i]); + hkJoyMapping[i] = joycfg.GetInt(hotkeyNames[i]); + } + + setJoystick(localCfg.GetInt("JoystickID")); +} + + +void EmuInstance::setJoystick(int id) +{ + joystickID = id; + openJoystick(); +} + +void EmuInstance::openJoystick() +{ + if (joystick) SDL_JoystickClose(joystick); + + int num = SDL_NumJoysticks(); + if (num < 1) + { + joystick = nullptr; + return; + } + + if (joystickID >= num) + joystickID = 0; + + joystick = SDL_JoystickOpen(joystickID); +} + +void EmuInstance::closeJoystick() +{ + if (joystick) + { + SDL_JoystickClose(joystick); + joystick = nullptr; + } +} + + +// distinguish between left and right modifier keys (Ctrl, Alt, Shift) +// Qt provides no real cross-platform way to do this, so here we go +// for Windows and Linux we can distinguish via scancodes (but both +// provide different scancodes) +bool isRightModKey(QKeyEvent* event) +{ +#ifdef __WIN32__ + quint32 scan = event->nativeScanCode(); + return (scan == 0x11D || scan == 0x138 || scan == 0x36); +#elif __APPLE__ + quint32 scan = event->nativeVirtualKey(); + return (scan == 0x36 || scan == 0x3C || scan == 0x3D || scan == 0x3E); +#else + quint32 scan = event->nativeScanCode(); + return (scan == 0x69 || scan == 0x6C || scan == 0x3E); +#endif +} + +int getEventKeyVal(QKeyEvent* event) +{ + int key = event->key(); + int mod = event->modifiers(); + bool ismod = (key == Qt::Key_Control || + key == Qt::Key_Alt || + key == Qt::Key_AltGr || + key == Qt::Key_Shift || + key == Qt::Key_Meta); + + if (!ismod) + key |= mod; + else if (isRightModKey(event)) + key |= (1<<31); + + return key; +} + + +void EmuInstance::onKeyPress(QKeyEvent* event) +{ + int keyHK = getEventKeyVal(event); + int keyKP = keyHK; + if (event->modifiers() != Qt::KeypadModifier) + keyKP &= ~event->modifiers(); + + for (int i = 0; i < 12; i++) + if (keyKP == keyMapping[i]) + keyInputMask &= ~(1<modifiers() != Qt::KeypadModifier) + keyKP &= ~event->modifiers(); + + for (int i = 0; i < 12; i++) + if (keyKP == keyMapping[i]) + keyInputMask |= (1<> 4) & 0xF; + int hatdir = val & 0xF; + Uint8 hatval = SDL_JoystickGetHat(joystick, hatnum); + + bool pressed = false; + if (hatdir == 0x1) pressed = (hatval & SDL_HAT_UP); + else if (hatdir == 0x4) pressed = (hatval & SDL_HAT_DOWN); + else if (hatdir == 0x2) pressed = (hatval & SDL_HAT_RIGHT); + else if (hatdir == 0x8) pressed = (hatval & SDL_HAT_LEFT); + + if (pressed) return true; + } + else + { + int btnnum = val & 0xFFFF; + Uint8 btnval = SDL_JoystickGetButton(joystick, btnnum); + + if (btnval) return true; + } + } + + if (val & 0x10000) + { + int axisnum = (val >> 24) & 0xF; + int axisdir = (val >> 20) & 0xF; + Sint16 axisval = SDL_JoystickGetAxis(joystick, axisnum); + + switch (axisdir) + { + case 0: // positive + if (axisval > 16384) return true; + break; + + case 1: // negative + if (axisval < -16384) return true; + break; + + case 2: // trigger + if (axisval > 0) return true; + break; + } + } + + return false; +} + +void EmuInstance::inputProcess() +{ + SDL_JoystickUpdate(); + + if (joystick) + { + if (!SDL_JoystickGetAttached(joystick)) + { + SDL_JoystickClose(joystick); + joystick = nullptr; + } + } + if (!joystick && (SDL_NumJoysticks() > 0)) + { + openJoystick(); + } + + joyInputMask = 0xFFF; + if (joystick) + { + for (int i = 0; i < 12; i++) + if (joystickButtonDown(joyMapping[i])) + joyInputMask &= ~(1 << i); + } + + inputMask = keyInputMask & joyInputMask; + + joyHotkeyMask = 0; + if (joystick) + { + for (int i = 0; i < HK_MAX; i++) + if (joystickButtonDown(hkJoyMapping[i])) + joyHotkeyMask |= (1 << i); + } + + hotkeyMask = keyHotkeyMask | joyHotkeyMask; + hotkeyPress = hotkeyMask & ~lastHotkeyMask; + hotkeyRelease = lastHotkeyMask & ~hotkeyMask; + lastHotkeyMask = hotkeyMask; +} diff --git a/src/frontend/qt_sdl/EmuThread.cpp b/src/frontend/qt_sdl/EmuThread.cpp index 83d02b15..beba17b5 100644 --- a/src/frontend/qt_sdl/EmuThread.cpp +++ b/src/frontend/qt_sdl/EmuThread.cpp @@ -29,7 +29,6 @@ #include #include "main.h" -#include "Input.h" #include "types.h" #include "version.h" @@ -172,8 +171,6 @@ void EmuThread::run() updateRenderer(); - Input::Init(); - u32 nframes = 0; double perfCountsSec = 1.0 / SDL_GetPerformanceFrequency(); double lastTime = SDL_GetPerformanceCounter() * perfCountsSec; @@ -196,25 +193,25 @@ void EmuThread::run() while (EmuRunning != emuStatus_Exit) { - Input::Process(); + emuInstance->inputProcess(); - if (Input::HotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange(); + if (emuInstance->hotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange(); - if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause(); - if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset(); - if (Input::HotkeyPressed(HK_FrameStep)) emit windowEmuFrameStep(); + if (emuInstance->hotkeyPressed(HK_Pause)) emit windowEmuPause(); + if (emuInstance->hotkeyPressed(HK_Reset)) emit windowEmuReset(); + if (emuInstance->hotkeyPressed(HK_FrameStep)) emit windowEmuFrameStep(); - if (Input::HotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle(); + if (emuInstance->hotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle(); - if (Input::HotkeyPressed(HK_SwapScreens)) emit swapScreensToggle(); - if (Input::HotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle(); + if (emuInstance->hotkeyPressed(HK_SwapScreens)) emit swapScreensToggle(); + if (emuInstance->hotkeyPressed(HK_SwapScreenEmphasis)) emit screenEmphasisToggle(); if (EmuRunning == emuStatus_Running || EmuRunning == emuStatus_FrameStep) { EmuStatus = emuStatus_Running; if (EmuRunning == emuStatus_FrameStep) EmuRunning = emuStatus_Paused; - if (Input::HotkeyPressed(HK_SolarSensorDecrease)) + if (emuInstance->hotkeyPressed(HK_SolarSensorDecrease)) { int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorDown, true); if (level != -1) @@ -222,7 +219,7 @@ void EmuThread::run() //mainWindow->osdAddMessage(0, "Solar sensor level: %d", level); } } - if (Input::HotkeyPressed(HK_SolarSensorIncrease)) + if (emuInstance->hotkeyPressed(HK_SolarSensorIncrease)) { int level = emuInstance->nds->GBACartSlot.SetInput(GBACart::Input_SolarSensorUp, true); if (level != -1) @@ -237,30 +234,30 @@ void EmuThread::run() double currentTime = SDL_GetPerformanceCounter() * perfCountsSec; // Handle power button - if (Input::HotkeyDown(HK_PowerButton)) + if (emuInstance->hotkeyDown(HK_PowerButton)) { dsi->I2C.GetBPTWL()->SetPowerButtonHeld(currentTime); } - else if (Input::HotkeyReleased(HK_PowerButton)) + else if (emuInstance->hotkeyReleased(HK_PowerButton)) { dsi->I2C.GetBPTWL()->SetPowerButtonReleased(currentTime); } // Handle volume buttons - if (Input::HotkeyDown(HK_VolumeUp)) + if (emuInstance->hotkeyDown(HK_VolumeUp)) { dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Up); } - else if (Input::HotkeyReleased(HK_VolumeUp)) + else if (emuInstance->hotkeyReleased(HK_VolumeUp)) { dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Up); } - if (Input::HotkeyDown(HK_VolumeDown)) + if (emuInstance->hotkeyDown(HK_VolumeDown)) { dsi->I2C.GetBPTWL()->SetVolumeSwitchHeld(DSi_BPTWL::volumeKey_Down); } - else if (Input::HotkeyReleased(HK_VolumeDown)) + else if (emuInstance->hotkeyReleased(HK_VolumeDown)) { dsi->I2C.GetBPTWL()->SetVolumeSwitchReleased(DSi_BPTWL::volumeKey_Down); } @@ -275,7 +272,7 @@ void EmuThread::run() // HACK: // once the fast forward hotkey is released, we need to update vsync // to the old setting again - if (videoSettingsDirty || Input::HotkeyReleased(HK_FastForward)) + if (videoSettingsDirty || emuInstance->hotkeyReleased(HK_FastForward)) { if (useOpenGL) { @@ -297,9 +294,9 @@ void EmuThread::run() } // process input and hotkeys - emuInstance->nds->SetKeyMask(Input::InputMask); + emuInstance->nds->SetKeyMask(emuInstance->inputMask); - if (Input::HotkeyPressed(HK_Lid)) + if (emuInstance->hotkeyPressed(HK_Lid)) { bool lid = !emuInstance->nds->IsLidClosed(); emuInstance->nds->SetLidClosed(lid); @@ -388,7 +385,7 @@ void EmuThread::run() winUpdateCount = 0; } - bool fastforward = Input::HotkeyDown(HK_FastForward); + bool fastforward = emuInstance->hotkeyDown(HK_FastForward); if (fastforward && useOpenGL && Config::ScreenVSync) { diff --git a/src/frontend/qt_sdl/Input.cpp b/src/frontend/qt_sdl/Input.cpp deleted file mode 100644 index 7ebd7e2a..00000000 --- a/src/frontend/qt_sdl/Input.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - Copyright 2016-2023 melonDS team - - This file is part of melonDS. - - melonDS is free software: you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - melonDS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -#include -#include - -#include "Input.h" -#include "Config.h" - -using namespace melonDS; - -namespace Input -{ - -int JoystickID; -SDL_Joystick* Joystick = nullptr; - -u32 KeyInputMask, JoyInputMask; -u32 KeyHotkeyMask, JoyHotkeyMask; -u32 HotkeyMask, LastHotkeyMask; -u32 HotkeyPress, HotkeyRelease; - -u32 InputMask; - - -void Init() -{ - KeyInputMask = 0xFFF; - JoyInputMask = 0xFFF; - InputMask = 0xFFF; - - KeyHotkeyMask = 0; - JoyHotkeyMask = 0; - HotkeyMask = 0; - LastHotkeyMask = 0; -} - - -void OpenJoystick() -{ - if (Joystick) SDL_JoystickClose(Joystick); - - int num = SDL_NumJoysticks(); - if (num < 1) - { - Joystick = nullptr; - return; - } - - if (JoystickID >= num) - JoystickID = 0; - - Joystick = SDL_JoystickOpen(JoystickID); -} - -void CloseJoystick() -{ - if (Joystick) - { - SDL_JoystickClose(Joystick); - Joystick = nullptr; - } -} - - -int GetEventKeyVal(QKeyEvent* event) -{ - int key = event->key(); - int mod = event->modifiers(); - bool ismod = (key == Qt::Key_Control || - key == Qt::Key_Alt || - key == Qt::Key_AltGr || - key == Qt::Key_Shift || - key == Qt::Key_Meta); - - if (!ismod) - key |= mod; - else if (Input::IsRightModKey(event)) - key |= (1<<31); - - return key; -} - -void KeyPress(QKeyEvent* event) -{ - int keyHK = GetEventKeyVal(event); - int keyKP = keyHK; - if (event->modifiers() != Qt::KeypadModifier) - keyKP &= ~event->modifiers(); - - for (int i = 0; i < 12; i++) - if (keyKP == Config::KeyMapping[i]) - KeyInputMask &= ~(1<modifiers() != Qt::KeypadModifier) - keyKP &= ~event->modifiers(); - - for (int i = 0; i < 12; i++) - if (keyKP == Config::KeyMapping[i]) - KeyInputMask |= (1<> 4) & 0xF; - int hatdir = val & 0xF; - Uint8 hatval = SDL_JoystickGetHat(Joystick, hatnum); - - bool pressed = false; - if (hatdir == 0x1) pressed = (hatval & SDL_HAT_UP); - else if (hatdir == 0x4) pressed = (hatval & SDL_HAT_DOWN); - else if (hatdir == 0x2) pressed = (hatval & SDL_HAT_RIGHT); - else if (hatdir == 0x8) pressed = (hatval & SDL_HAT_LEFT); - - if (pressed) return true; - } - else - { - int btnnum = val & 0xFFFF; - Uint8 btnval = SDL_JoystickGetButton(Joystick, btnnum); - - if (btnval) return true; - } - } - - if (val & 0x10000) - { - int axisnum = (val >> 24) & 0xF; - int axisdir = (val >> 20) & 0xF; - Sint16 axisval = SDL_JoystickGetAxis(Joystick, axisnum); - - switch (axisdir) - { - case 0: // positive - if (axisval > 16384) return true; - break; - - case 1: // negative - if (axisval < -16384) return true; - break; - - case 2: // trigger - if (axisval > 0) return true; - break; - } - } - - return false; -} - -void Process() -{ - SDL_JoystickUpdate(); - - if (Joystick) - { - if (!SDL_JoystickGetAttached(Joystick)) - { - SDL_JoystickClose(Joystick); - Joystick = NULL; - } - } - if (!Joystick && (SDL_NumJoysticks() > 0)) - { - JoystickID = Config::JoystickID; - OpenJoystick(); - } - - JoyInputMask = 0xFFF; - if (Joystick) - { - for (int i = 0; i < 12; i++) - if (JoystickButtonDown(Config::JoyMapping[i])) - JoyInputMask &= ~(1 << i); - } - - InputMask = KeyInputMask & JoyInputMask; - - JoyHotkeyMask = 0; - if (Joystick) - { - for (int i = 0; i < HK_MAX; i++) - if (JoystickButtonDown(Config::HKJoyMapping[i])) - JoyHotkeyMask |= (1 << i); - } - - HotkeyMask = KeyHotkeyMask | JoyHotkeyMask; - HotkeyPress = HotkeyMask & ~LastHotkeyMask; - HotkeyRelease = LastHotkeyMask & ~HotkeyMask; - LastHotkeyMask = HotkeyMask; -} - - -bool HotkeyDown(int id) { return HotkeyMask & (1<nativeScanCode(); - return (scan == 0x11D || scan == 0x138 || scan == 0x36); -} -#elif __APPLE__ -bool IsRightModKey(QKeyEvent* event) -{ - quint32 scan = event->nativeVirtualKey(); - return (scan == 0x36 || scan == 0x3C || scan == 0x3D || scan == 0x3E); -} -#else -bool IsRightModKey(QKeyEvent* event) -{ - quint32 scan = event->nativeScanCode(); - return (scan == 0x69 || scan == 0x6C || scan == 0x3E); -} -#endif - -} diff --git a/src/frontend/qt_sdl/Input.h b/src/frontend/qt_sdl/Input.h deleted file mode 100644 index e2f5a63f..00000000 --- a/src/frontend/qt_sdl/Input.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright 2016-2023 melonDS team - - This file is part of melonDS. - - melonDS is free software: you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - melonDS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -#ifndef INPUT_H -#define INPUT_H - -#include -#include - -#include "types.h" - -namespace Input -{ - -using namespace melonDS; -extern int JoystickID; -extern SDL_Joystick* Joystick; - -extern u32 InputMask; - -void Init(); - -// set joystickID before calling openJoystick() -void OpenJoystick(); -void CloseJoystick(); - -void KeyPress(QKeyEvent* event); -void KeyRelease(QKeyEvent* event); -void KeyReleaseAll(); - -void Process(); - -bool HotkeyDown(int id); -bool HotkeyPressed(int id); -bool HotkeyReleased(int id); - -bool IsRightModKey(QKeyEvent* event); - -} - -#endif // INPUT_H diff --git a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp index 02a76bb7..fd433f34 100644 --- a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp @@ -26,10 +26,9 @@ #include "types.h" #include "Platform.h" -#include "MapButton.h" -#include "Input.h" #include "InputConfigDialog.h" #include "ui_InputConfigDialog.h" +#include "MapButton.h" using namespace melonDS; @@ -43,31 +42,42 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); + emuInstance = ((MainWindow*)parent)->getEmuInstance(); + + Config::Table& instcfg = emuInstance->getLocalConfig(); + Config::Table keycfg = instcfg.GetTable("Keyboard"); + Config::Table joycfg = instcfg.GetTable("Joystick"); + for (int i = 0; i < keypad_num; i++) { - keypadKeyMap[i] = Config::KeyMapping[dskeyorder[i]]; - keypadJoyMap[i] = Config::JoyMapping[dskeyorder[i]]; + const char* btn = EmuInstance::buttonNames[dskeyorder[i]]; + keypadKeyMap[i] = keycfg.GetInt(btn); + keypadJoyMap[i] = joycfg.GetInt(btn); } int i = 0; for (int hotkey : hk_addons) { - addonsKeyMap[i] = Config::HKKeyMapping[hotkey]; - addonsJoyMap[i] = Config::HKJoyMapping[hotkey]; + const char* btn = EmuInstance::hotkeyNames[hotkey]; + addonsKeyMap[i] = keycfg.GetInt(btn); + addonsJoyMap[i] = joycfg.GetInt(btn); i++; } i = 0; for (int hotkey : hk_general) { - hkGeneralKeyMap[i] = Config::HKKeyMapping[hotkey]; - hkGeneralJoyMap[i] = Config::HKJoyMapping[hotkey]; + const char* btn = EmuInstance::hotkeyNames[hotkey]; + hkGeneralKeyMap[i] = keycfg.GetInt(btn); + hkGeneralJoyMap[i] = joycfg.GetInt(btn); i++; } populatePage(ui->tabAddons, hk_addons_labels, addonsKeyMap, addonsJoyMap); populatePage(ui->tabHotkeysGeneral, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap); + joystickID = instcfg.GetInt("JoystickID"); + int njoy = SDL_NumJoysticks(); if (njoy > 0) { @@ -76,7 +86,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new const char* name = SDL_JoystickNameForIndex(i); ui->cbxJoystick->addItem(QString(name)); } - ui->cbxJoystick->setCurrentIndex(Input::JoystickID); + ui->cbxJoystick->setCurrentIndex(joystickID); } else { @@ -86,7 +96,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new setupKeypadPage(); - int inst = Platform::InstanceID(); + int inst = emuInstance->getInstanceID(); if (inst > 0) ui->lblInstanceNum->setText(QString("Configuring mappings for instance %1").arg(inst+1)); else @@ -174,38 +184,47 @@ void InputConfigDialog::populatePage(QWidget* page, void InputConfigDialog::on_InputConfigDialog_accepted() { + Config::Table& instcfg = emuInstance->getLocalConfig(); + Config::Table keycfg = instcfg.GetTable("Keyboard"); + Config::Table joycfg = instcfg.GetTable("Joystick"); + for (int i = 0; i < keypad_num; i++) { - Config::KeyMapping[dskeyorder[i]] = keypadKeyMap[i]; - Config::JoyMapping[dskeyorder[i]] = keypadJoyMap[i]; + const char* btn = EmuInstance::buttonNames[dskeyorder[i]]; + keycfg.SetInt(btn, keypadKeyMap[i]); + joycfg.SetInt(btn, keypadJoyMap[i]); } int i = 0; for (int hotkey : hk_addons) { - Config::HKKeyMapping[hotkey] = addonsKeyMap[i]; - Config::HKJoyMapping[hotkey] = addonsJoyMap[i]; + const char* btn = EmuInstance::hotkeyNames[hotkey]; + keycfg.SetInt(btn, addonsKeyMap[i]); + joycfg.SetInt(btn, addonsJoyMap[i]); i++; } i = 0; for (int hotkey : hk_general) { - Config::HKKeyMapping[hotkey] = hkGeneralKeyMap[i]; - Config::HKJoyMapping[hotkey] = hkGeneralJoyMap[i]; + const char* btn = EmuInstance::hotkeyNames[hotkey]; + keycfg.SetInt(btn, hkGeneralKeyMap[i]); + joycfg.SetInt(btn, hkGeneralJoyMap[i]); i++; } - Config::JoystickID = Input::JoystickID; + instcfg.SetInt("JoystickID", joystickID); Config::Save(); + emuInstance->inputLoadConfig(); + closeDlg(); } void InputConfigDialog::on_InputConfigDialog_rejected() { - Input::JoystickID = Config::JoystickID; - Input::OpenJoystick(); + Config::Table& instcfg = emuInstance->getLocalConfig(); + emuInstance->setJoystick(instcfg.GetInt("JoystickID")); closeDlg(); } @@ -225,6 +244,11 @@ void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id) // prevent a spurious change if (ui->cbxJoystick->count() < 2) return; - Input::JoystickID = id; - Input::OpenJoystick(); + joystickID = id; + emuInstance->setJoystick(id); +} + +SDL_Joystick* InputConfigDialog::getJoystick() +{ + return emuInstance->getJoystick(); } diff --git a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h index 8d4f882a..50ad1802 100644 --- a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h +++ b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h @@ -24,6 +24,7 @@ #include #include "Config.h" +#include "EmuInstance.h" static constexpr int keypad_num = 12; @@ -89,6 +90,8 @@ public: explicit InputConfigDialog(QWidget* parent); ~InputConfigDialog(); + SDL_Joystick* getJoystick(); + static InputConfigDialog* currentDlg; static InputConfigDialog* openDlg(QWidget* parent) { @@ -123,9 +126,12 @@ private: Ui::InputConfigDialog* ui; + EmuInstance* emuInstance; + int keypadKeyMap[12], keypadJoyMap[12]; int addonsKeyMap[hk_addons.size()], addonsJoyMap[hk_addons.size()]; int hkGeneralKeyMap[hk_general.size()], hkGeneralJoyMap[hk_general.size()]; + int joystickID; }; diff --git a/src/frontend/qt_sdl/InputConfig/MapButton.h b/src/frontend/qt_sdl/InputConfig/MapButton.h index 5d4fb3eb..2162cb06 100644 --- a/src/frontend/qt_sdl/InputConfig/MapButton.h +++ b/src/frontend/qt_sdl/InputConfig/MapButton.h @@ -23,8 +23,10 @@ #include -#include "Input.h" #include "Platform.h" +#include "EmuInstance.h" + +class InputConfigDialog; class KeyMapButton : public QPushButton { @@ -76,7 +78,7 @@ protected: if (!ismod) key |= mod; - else if (Input::IsRightModKey(event)) + else if (isRightModKey(event)) key |= (1<<31); *mapping = key; @@ -162,6 +164,9 @@ public: this->mapping = mapping; this->isHotkey = hotkey; + // the parent will be set later when this button is added to a layout + parentDialog = nullptr; + setCheckable(true); setText(mappingText()); setFocusPolicy(Qt::StrongFocus); //Fixes binding keys in macOS @@ -176,6 +181,20 @@ public: } protected: + void showEvent(QShowEvent* event) override + { + if (event->spontaneous()) return; + + QWidget* w = parentWidget(); + for (;;) + { + parentDialog = qobject_cast(w); + if (parentDialog) break; + w = w->parentWidget(); + if (!w) break; + } + } + void keyPressEvent(QKeyEvent* event) override { if (!isChecked()) return QPushButton::keyPressEvent(event); @@ -203,7 +222,7 @@ protected: void timerEvent(QTimerEvent* event) override { - SDL_Joystick* joy = Input::Joystick; + SDL_Joystick* joy = parentDialog->getJoystick(); if (!joy) { click(); return; } if (!SDL_JoystickGetAttached(joy)) { click(); return; } @@ -279,13 +298,15 @@ private slots: timerID = startTimer(50); memset(axesRest, 0, sizeof(axesRest)); - if (Input::Joystick && SDL_JoystickGetAttached(Input::Joystick)) + + SDL_Joystick* joy = parentDialog->getJoystick(); + if (joy && SDL_JoystickGetAttached(joy)) { - int naxes = SDL_JoystickNumAxes(Input::Joystick); + int naxes = SDL_JoystickNumAxes(joy); if (naxes > 16) naxes = 16; for (int a = 0; a < naxes; a++) { - axesRest[a] = SDL_JoystickGetAxis(Input::Joystick, a); + axesRest[a] = SDL_JoystickGetAxis(joy, a); } } } @@ -349,6 +370,8 @@ private: return str; } + InputConfigDialog* parentDialog; + int* mapping; bool isHotkey; diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 714707b8..cb593226 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -24,6 +24,7 @@ #include "Platform.h" #include "Config.h" #include "GPU.h" +#include "main.h" #include "VideoSettingsDialog.h" #include "ui_VideoSettingsDialog.h" diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp index 50c11515..40509bba 100644 --- a/src/frontend/qt_sdl/Window.cpp +++ b/src/frontend/qt_sdl/Window.cpp @@ -51,7 +51,6 @@ #endif #include "main.h" -#include "Input.h" #include "CheatsDialog.h" #include "DateTimeDialog.h" #include "EmuSettingsDialog.h" @@ -846,14 +845,14 @@ void MainWindow::keyPressEvent(QKeyEvent* event) // TODO!! REMOVE ME IN RELEASE BUILDS!! //if (event->key() == Qt::Key_F11) emuThread->NDS->debug(0); - Input::KeyPress(event); + emuInstance->onKeyPress(event); } void MainWindow::keyReleaseEvent(QKeyEvent* event) { if (event->isAutoRepeat()) return; - Input::KeyRelease(event); + emuInstance->onKeyRelease(event); } @@ -955,7 +954,7 @@ void MainWindow::onAppStateChanged(Qt::ApplicationState state) { if (state == Qt::ApplicationInactive) { - Input::KeyReleaseAll(); + emuInstance->keyReleaseAll(); if (Config::PauseLostFocus && emuThread->emuIsRunning()) emuThread->emuPause(); } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 326ad99b..db678cce 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -56,48 +56,19 @@ #include "duckstation/gl/context.h" #include "main.h" -#include "Input.h" #include "CheatsDialog.h" #include "DateTimeDialog.h" #include "EmuSettingsDialog.h" #include "InputConfig/InputConfigDialog.h" #include "VideoSettingsDialog.h" -#include "CameraSettingsDialog.h" -#include "AudioSettingsDialog.h" -#include "FirmwareSettingsDialog.h" -#include "PathSettingsDialog.h" -#include "MPSettingsDialog.h" -#include "WifiSettingsDialog.h" -#include "InterfaceSettingsDialog.h" #include "ROMInfoDialog.h" #include "RAMInfoDialog.h" -#include "TitleManagerDialog.h" #include "PowerManagement/PowerManagementDialog.h" -#include "types.h" #include "version.h" -#include "FrontendUtil.h" - -#include "Args.h" -#include "NDS.h" -#include "NDSCart.h" -#include "GBACart.h" -#include "GPU.h" -#include "SPU.h" -#include "Wifi.h" -#include "Platform.h" -#include "LocalMP.h" #include "Config.h" -#include "RTC.h" #include "DSi.h" -#include "DSi_I2C.h" -#include "GPU3D_Soft.h" -#include "GPU3D_OpenGL.h" - -#include "Savestate.h" - -//#include "main_shaders.h" #include "EmuInstance.h" #include "ArchiveUtil.h" @@ -369,9 +340,6 @@ int main(int argc, char** argv) QApplication::setStyle(QString::fromStdString(Config::UITheme)); } - Input::JoystickID = Config::JoystickID; - Input::OpenJoystick(); - /* mainWindow = new MainWindow(); if (options->fullscreen) ToggleFullscreen(mainWindow); @@ -422,8 +390,6 @@ int main(int argc, char** argv) delete emuThread;*/ delete testinst; - Input::CloseJoystick(); - //AudioInOut::DeInit(); delete camManager[0]; delete camManager[1];