From a6025d3131927ef4fa51a97d49b25eb3f802fda6 Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Sat, 27 Jun 2026 16:11:10 +0200 Subject: [PATCH] sceMouseClose, send correct events when no mouse is connected and better state.connected handling (#4599) --- src/core/libraries/mouse/mouse.cpp | 19 ++++++++++++++----- src/core/libraries/mouse/sdl_mouse.cpp | 22 +++++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/core/libraries/mouse/mouse.cpp b/src/core/libraries/mouse/mouse.cpp index fc447f284..e44d56d14 100644 --- a/src/core/libraries/mouse/mouse.cpp +++ b/src/core/libraries/mouse/mouse.cpp @@ -19,10 +19,15 @@ namespace Libraries::Mouse { RingBufferQueue mouse_states[2]{{64}, {64}}; s32 mouse_handles[2]{-1, -1}; s32 mouse_sdl_handles[2]{-1, -1}; -bool g_lib_init = false, g_is_merged_mode = false; +bool g_lib_init = false, g_is_merged_mode = false, g_are_mice_enabled; int PS4_SYSV_ABI sceMouseClose(s32 handle) { - LOG_ERROR(Lib_Mouse, "(STUBBED) called"); + LOG_INFO(Lib_Mouse, "(DUMMY) called, handle: {}", handle); + if (mouse_handles[0] != handle && mouse_handles[1] != handle) { + return ORBIS_MOUSE_ERROR_INVALID_HANDLE; + } + u64 m = mouse_handles[0] == handle ? 0 : 1; + mouse_handles[m] = -1; return ORBIS_OK; } @@ -57,7 +62,8 @@ int PS4_SYSV_ABI sceMouseGetDeviceInfo() { } int PS4_SYSV_ABI sceMouseInit() { - if (EmulatorSettings.IsMiceUsedAsMice()) { + g_are_mice_enabled = EmulatorSettings.IsMiceUsedAsMice(); + if (g_are_mice_enabled) { SDL_WarpMouseInWindow(g_window->GetSDLWindow(), 1, 1); SDL_SetWindowRelativeMouseMode(g_window->GetSDLWindow(), true); } @@ -103,7 +109,7 @@ int PS4_SYSV_ABI sceMouseOpen(Libraries::UserService::OrbisUserServiceUserId use int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num) { LOG_DEBUG(Lib_Mouse, "(DUMMY) called, h: {}, n: {}", handle, num); - if (!pData || num > 64) { + if (!pData || num < 1 || num > 64) { return ORBIS_MOUSE_ERROR_INVALID_ARG; } if (mouse_handles[0] != handle && mouse_handles[1] != handle) { @@ -111,13 +117,16 @@ int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num) { } u64 m = mouse_handles[0] == handle ? 0 : 1; int i = 0; + if (!g_are_mice_enabled) { + pData[0] = {.connected = false}; + return 1; + } for (; i < num; i++) { std::optional st = mouse_states[m].Pop(); if (!st) { break; } pData[i] = *st; - pData[i].connected = mouse_sdl_handles[m] != -1; } return i; } diff --git a/src/core/libraries/mouse/sdl_mouse.cpp b/src/core/libraries/mouse/sdl_mouse.cpp index 48d3dc163..e9a135065 100644 --- a/src/core/libraries/mouse/sdl_mouse.cpp +++ b/src/core/libraries/mouse/sdl_mouse.cpp @@ -33,7 +33,7 @@ constexpr u32 OrbisButtonFromSDL(Uint8 button) { } bool PushSDLEvent(SDL_Event const& e) { - static OrbisMouseData current_state[2]{}; + static OrbisMouseData current_state[2]{{.connected = true}, {.connected = true}}; if (!EmulatorSettings.IsMiceUsedAsMice()) { return false; } @@ -43,6 +43,18 @@ bool PushSDLEvent(SDL_Event const& e) { switch (e.type) { default: return false; + case SDL_EVENT_MOUSE_ADDED: { + LOG_INFO(Lib_Mouse, "Mouse added, id: {}", e.mdevice.which); + u64 index = GetIndexFromSdlHandle(e.mdevice.which); + if (index != 2) { + return true; + } + auto new_index = GetIndexFromSdlHandle(-1); + if (new_index < 2) { + mouse_sdl_handles[(GetIndexFromSdlHandle(-1))] = e.mdevice.which; + } + break; + } case SDL_EVENT_MOUSE_REMOVED: { LOG_INFO(Lib_Mouse, "Mouse removed, id: {}", e.mdevice.which); if (g_is_merged_mode) { @@ -53,17 +65,21 @@ bool PushSDLEvent(SDL_Event const& e) { return false; } mouse_sdl_handles[index] = -1; + current_state[index].connected = false; mouse_states[index].Push(current_state[index]); + current_state[index].connected = true; break; } case SDL_EVENT_MOUSE_MOTION: { u64 index = GetIndexFromSdlHandle(e.motion.which); if (index == 2) { index = GetIndexFromSdlHandle(-1); - if (index < 2) + if (index < 2) { + LOG_INFO(Lib_Mouse, "mouse {} = sdl id {}", index, e.motion.which); mouse_sdl_handles[index] = e.motion.which; - else + } else { return false; + } } auto& s = current_state[index]; s.x_axis = (s32)e.motion.xrel;