sceMouseClose, send correct events when no mouse is connected and better state.connected handling (#4599)

This commit is contained in:
kalaposfos13
2026-06-27 16:11:10 +02:00
committed by GitHub
parent bf98eaa982
commit a6025d3131
2 changed files with 33 additions and 8 deletions
+14 -5
View File
@@ -19,10 +19,15 @@ namespace Libraries::Mouse {
RingBufferQueue<OrbisMouseData> mouse_states[2]{{64}, {64}}; RingBufferQueue<OrbisMouseData> mouse_states[2]{{64}, {64}};
s32 mouse_handles[2]{-1, -1}; s32 mouse_handles[2]{-1, -1};
s32 mouse_sdl_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) { 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; return ORBIS_OK;
} }
@@ -57,7 +62,8 @@ int PS4_SYSV_ABI sceMouseGetDeviceInfo() {
} }
int PS4_SYSV_ABI sceMouseInit() { 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_WarpMouseInWindow(g_window->GetSDLWindow(), 1, 1);
SDL_SetWindowRelativeMouseMode(g_window->GetSDLWindow(), true); 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) { int PS4_SYSV_ABI sceMouseRead(s32 handle, OrbisMouseData* pData, s32 num) {
LOG_DEBUG(Lib_Mouse, "(DUMMY) called, h: {}, n: {}", handle, 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; return ORBIS_MOUSE_ERROR_INVALID_ARG;
} }
if (mouse_handles[0] != handle && mouse_handles[1] != handle) { 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; u64 m = mouse_handles[0] == handle ? 0 : 1;
int i = 0; int i = 0;
if (!g_are_mice_enabled) {
pData[0] = {.connected = false};
return 1;
}
for (; i < num; i++) { for (; i < num; i++) {
std::optional<OrbisMouseData> st = mouse_states[m].Pop(); std::optional<OrbisMouseData> st = mouse_states[m].Pop();
if (!st) { if (!st) {
break; break;
} }
pData[i] = *st; pData[i] = *st;
pData[i].connected = mouse_sdl_handles[m] != -1;
} }
return i; return i;
} }
+19 -3
View File
@@ -33,7 +33,7 @@ constexpr u32 OrbisButtonFromSDL(Uint8 button) {
} }
bool PushSDLEvent(SDL_Event const& e) { bool PushSDLEvent(SDL_Event const& e) {
static OrbisMouseData current_state[2]{}; static OrbisMouseData current_state[2]{{.connected = true}, {.connected = true}};
if (!EmulatorSettings.IsMiceUsedAsMice()) { if (!EmulatorSettings.IsMiceUsedAsMice()) {
return false; return false;
} }
@@ -43,6 +43,18 @@ bool PushSDLEvent(SDL_Event const& e) {
switch (e.type) { switch (e.type) {
default: default:
return false; 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: { case SDL_EVENT_MOUSE_REMOVED: {
LOG_INFO(Lib_Mouse, "Mouse removed, id: {}", e.mdevice.which); LOG_INFO(Lib_Mouse, "Mouse removed, id: {}", e.mdevice.which);
if (g_is_merged_mode) { if (g_is_merged_mode) {
@@ -53,17 +65,21 @@ bool PushSDLEvent(SDL_Event const& e) {
return false; return false;
} }
mouse_sdl_handles[index] = -1; mouse_sdl_handles[index] = -1;
current_state[index].connected = false;
mouse_states[index].Push(current_state[index]); mouse_states[index].Push(current_state[index]);
current_state[index].connected = true;
break; break;
} }
case SDL_EVENT_MOUSE_MOTION: { case SDL_EVENT_MOUSE_MOTION: {
u64 index = GetIndexFromSdlHandle(e.motion.which); u64 index = GetIndexFromSdlHandle(e.motion.which);
if (index == 2) { if (index == 2) {
index = GetIndexFromSdlHandle(-1); 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; mouse_sdl_handles[index] = e.motion.which;
else } else {
return false; return false;
}
} }
auto& s = current_state[index]; auto& s = current_state[index];
s.x_axis = (s32)e.motion.xrel; s.x_axis = (s32)e.motion.xrel;