From 713739bbc7ab87d6be517ede54ee16d80b5bc1d0 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 24 Feb 2024 21:33:40 +0100 Subject: [PATCH] sdl: support multiple mice when allowed by the platform --- core/sdl/sdl.cpp | 63 +++++++++++++++++++++++++----------------- core/sdl/sdl_gamepad.h | 12 ++++++-- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp index da9164107e..85cf106a20 100644 --- a/core/sdl/sdl.cpp +++ b/core/sdl/sdl.cpp @@ -37,7 +37,7 @@ static u32 windowFlags; #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 -static std::shared_ptr sdl_mouse; +static std::unordered_map> sdl_mice; static std::shared_ptr sdl_keyboard; static bool window_fullscreen; static bool window_maximized; @@ -140,14 +140,15 @@ static void emuEventCallback(Event event, void *) static void checkRawInput() { #if defined(_WIN32) && !defined(TARGET_UWP) - if ((bool)config::UseRawInput != (bool)sdl_mouse) + if ((bool)config::UseRawInput != (bool)sdl_keyboard) return; if (config::UseRawInput) { GamepadDevice::Unregister(sdl_keyboard); sdl_keyboard = nullptr; - GamepadDevice::Unregister(sdl_mouse); - sdl_mouse = nullptr; + for (auto& it : sdl_mice) + GamepadDevice::Unregister(it.second); + sdl_mice.clear(); rawinput::init(); } else @@ -155,8 +156,6 @@ static void checkRawInput() rawinput::term(); sdl_keyboard = std::make_shared(0); GamepadDevice::Register(sdl_keyboard); - sdl_mouse = std::make_shared(); - GamepadDevice::Register(sdl_mouse); } #else if (!sdl_keyboard) @@ -164,11 +163,6 @@ static void checkRawInput() sdl_keyboard = std::make_shared(0); GamepadDevice::Register(sdl_keyboard); } - if (!sdl_mouse) - { - sdl_mouse = std::make_shared(); - GamepadDevice::Register(sdl_mouse); - } #endif } @@ -251,6 +245,17 @@ inline void SDLMouse::setAbsPos(int x, int y) { Mouse::setAbsPos(x, y, width, height); } +static std::shared_ptr getMouse(u64 mouseId) +{ + auto& mouse = sdl_mice[mouseId]; + if (mouse == nullptr) + { + mouse = std::make_shared(mouseId); + GamepadDevice::Register(mouse); + } + return mouse; +} + void input_sdl_handle() { SDLGamepad::UpdateRumble(); @@ -422,10 +427,11 @@ void input_sdl_handle() checkRawInput(); if (!config::UseRawInput) { + auto mouse = getMouse(event.motion.which); if (mouseCaptured && gameRunning) - sdl_mouse->setRelPos(event.motion.xrel, event.motion.yrel); + mouse->setRelPos(event.motion.xrel, event.motion.yrel); else - sdl_mouse->setAbsPos(event.motion.x, event.motion.y); + mouse->setAbsPos(event.motion.x, event.motion.y); } else if (mouseCaptured && gameRunning) { @@ -451,24 +457,25 @@ void input_sdl_handle() checkRawInput(); if (!config::UseRawInput) { + auto mouse = getMouse(event.button.which); if (!mouseCaptured || !gameRunning) - sdl_mouse->setAbsPos(event.button.x, event.button.y); + mouse->setAbsPos(event.button.x, event.button.y); bool pressed = event.button.state == SDL_PRESSED; switch (event.button.button) { case SDL_BUTTON_LEFT: - sdl_mouse->setButton(Mouse::LEFT_BUTTON, pressed); + mouse->setButton(Mouse::LEFT_BUTTON, pressed); break; case SDL_BUTTON_RIGHT: - sdl_mouse->setButton(Mouse::RIGHT_BUTTON, pressed); + mouse->setButton(Mouse::RIGHT_BUTTON, pressed); break; case SDL_BUTTON_MIDDLE: - sdl_mouse->setButton(Mouse::MIDDLE_BUTTON, pressed); + mouse->setButton(Mouse::MIDDLE_BUTTON, pressed); break; case SDL_BUTTON_X1: - sdl_mouse->setButton(Mouse::BUTTON_4, pressed); + mouse->setButton(Mouse::BUTTON_4, pressed); break; case SDL_BUTTON_X2: - sdl_mouse->setButton(Mouse::BUTTON_5, pressed); + mouse->setButton(Mouse::BUTTON_5, pressed); break; } } @@ -478,8 +485,10 @@ void input_sdl_handle() case SDL_MOUSEWHEEL: gui_set_mouse_wheel(-event.wheel.y * 35); checkRawInput(); - if (!config::UseRawInput) - sdl_mouse->setWheel(-event.wheel.y); + if (!config::UseRawInput) { + auto mouse = getMouse(event.wheel.which); + mouse->setWheel(-event.wheel.y); + } break; case SDL_JOYDEVICEADDED: @@ -498,6 +507,7 @@ void input_sdl_handle() case SDL_FINGERDOWN: case SDL_FINGERMOTION: { + auto mouse = getMouse(0); int x = event.tfinger.x * settings.display.width; int y = event.tfinger.y * settings.display.height; gui_set_mouse_position(x, y); @@ -505,24 +515,25 @@ void input_sdl_handle() { int dx = event.tfinger.dx * settings.display.width; int dy = event.tfinger.dy * settings.display.height; - sdl_mouse->setRelPos(dx, dy); + mouse->setRelPos(dx, dy); } else - sdl_mouse->setAbsPos(x, y); + mouse->setAbsPos(x, y); if (event.type == SDL_FINGERDOWN) { - sdl_mouse->setButton(Mouse::LEFT_BUTTON, true); + mouse->setButton(Mouse::LEFT_BUTTON, true); gui_set_mouse_button(0, true); } } break; case SDL_FINGERUP: { + auto mouse = getMouse(0); int x = event.tfinger.x * settings.display.width; int y = event.tfinger.y * settings.display.height; gui_set_mouse_position(x, y); gui_set_mouse_button(0, false); - sdl_mouse->setAbsPos(x, y); - sdl_mouse->setButton(Mouse::LEFT_BUTTON, false); + mouse->setAbsPos(x, y); + mouse->setButton(Mouse::LEFT_BUTTON, false); } break; } diff --git a/core/sdl/sdl_gamepad.h b/core/sdl/sdl_gamepad.h index 33d9e83dd9..6bb9e7f992 100644 --- a/core/sdl/sdl_gamepad.h +++ b/core/sdl/sdl_gamepad.h @@ -426,10 +426,16 @@ std::map> SDLGamepad::sdl_gamepads; class SDLMouse : public Mouse { public: - SDLMouse() : Mouse("SDL") + SDLMouse(u64 mouseId) : Mouse("SDL") { - this->_name = "Default Mouse"; - this->_unique_id = "sdl_mouse"; + if (mouseId == 0) { + this->_name = "Default Mouse"; + this->_unique_id = "sdl_mouse"; + } + else { + this->_name = "Mouse " + std::to_string(mouseId); + this->_unique_id = "sdl_mouse_" + std::to_string(mouseId); + } loadMapping(); }