diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 868c6337e..08689802f 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -166,11 +166,14 @@ void MapleConfigMap::GetAbsCoordinates(int& x, int& y) void MapleConfigMap::GetMouseInput(u8& buttons, int& x, int& y, int& wheel) { - const MapleInputState& inputState = mapleInputState[playerNum()]; + MapleInputState& inputState = mapleInputState[playerNum()]; buttons = inputState.mouseButtons; x = inputState.relPos.x; y = inputState.relPos.y * (invertMouseY ? -1 : 1); wheel = inputState.relPos.wheel; + inputState.relPos.x = 0; + inputState.relPos.y = 0; + inputState.relPos.wheel = 0; } void MapleConfigMap::GetKeyboardInput(u8& shift, u8 keys[6]) diff --git a/core/hw/maple/maple_jvs.cpp b/core/hw/maple/maple_jvs.cpp index fd4702b0b..4824cf33c 100644 --- a/core/hw/maple/maple_jvs.cpp +++ b/core/hw/maple/maple_jvs.cpp @@ -1566,6 +1566,8 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou // I can't think of any naomi multiplayer game that uses rotary encoders rotx += mapleInputState[first_player].relPos.x * 5; roty -= mapleInputState[first_player].relPos.y * 5; + mapleInputState[first_player].relPos.x = 0; + mapleInputState[first_player].relPos.y = 0; LOGJVS("rotenc "); for (int chan = 0; chan < buffer_in[cmdi + 1]; chan++) { diff --git a/core/input/mouse.cpp b/core/input/mouse.cpp index b4629816f..a63b7f0f6 100644 --- a/core/input/mouse.cpp +++ b/core/input/mouse.cpp @@ -26,9 +26,10 @@ // bit 3: Wheel button u8 mo_buttons[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; // Relative mouse coordinates [-512:511] -f32 mo_x_delta[4]; -f32 mo_y_delta[4]; -f32 mo_wheel_delta[4]; +float mo_x_delta[4]; +float mo_y_delta[4]; +float mo_wheel_delta[4]; +std::mutex relPosMutex; // Absolute mouse coordinates // Range [0:639] [0:479] // but may be outside this range if the pointer is offscreen or outside the 4:3 window. @@ -50,6 +51,7 @@ void Mouse::setRelPos(float deltax, float deltay) { } void Mouse::setWheel(int delta) { + std::lock_guard lock(relPosMutex); if (maple_port() >= 0 && maple_port() < (int)ARRAY_SIZE(mo_wheel_delta)) mo_wheel_delta[maple_port()] += delta; } @@ -131,8 +133,9 @@ void SetMousePosition(int x, int y, int width, int height, u32 mouseId) if (mo_x_prev[mouseId] != -1) { - mo_x_delta[mouseId] += (f32)(x - mo_x_prev[mouseId]) * config::MouseSensitivity / 100.f; - mo_y_delta[mouseId] += (f32)(y - mo_y_prev[mouseId]) * config::MouseSensitivity / 100.f; + std::lock_guard lock(relPosMutex); + mo_x_delta[mouseId] += (float)(x - mo_x_prev[mouseId]) * config::MouseSensitivity / 100.f; + mo_y_delta[mouseId] += (float)(y - mo_y_prev[mouseId]) * config::MouseSensitivity / 100.f; } mo_x_prev[mouseId] = x; mo_y_prev[mouseId] = y; @@ -152,8 +155,11 @@ void SetRelativeMousePosition(float xrel, float yrel, u32 mouseId) } float dx = xrel * config::MouseSensitivity / 100.f; float dy = yrel * config::MouseSensitivity / 100.f; - mo_x_delta[mouseId] += dx; - mo_y_delta[mouseId] += dy; + { + std::lock_guard lock(relPosMutex); + mo_x_delta[mouseId] += dx; + mo_y_delta[mouseId] += dy; + } int minX = -width / 32; int minY = -height / 32; int maxX = width + width / 32; diff --git a/core/input/mouse.h b/core/input/mouse.h index 456abb329..d17f8dcf1 100644 --- a/core/input/mouse.h +++ b/core/input/mouse.h @@ -18,14 +18,16 @@ */ #pragma once #include "gamepad_device.h" +#include // Mouse position and buttons extern u8 mo_buttons[4]; extern s32 mo_x_abs[4]; extern s32 mo_y_abs[4]; -extern f32 mo_x_delta[4]; -extern f32 mo_y_delta[4]; -extern f32 mo_wheel_delta[4]; +extern float mo_x_delta[4]; +extern float mo_y_delta[4]; +extern float mo_wheel_delta[4]; +extern std::mutex relPosMutex; extern s32 mo_x_prev[4]; extern s32 mo_y_prev[4]; diff --git a/core/network/ggpo.cpp b/core/network/ggpo.cpp index af71a5f03..5e5bc1010 100644 --- a/core/network/ggpo.cpp +++ b/core/network/ggpo.cpp @@ -34,6 +34,7 @@ static void getLocalInput(MapleInputState inputState[4]) { if (!config::ThreadedRendering) UpdateInputState(); + std::lock_guard lock(relPosMutex); for (int player = 0; player < 4; player++) { MapleInputState& state = inputState[player]; @@ -49,12 +50,15 @@ static void getLocalInput(MapleInputState inputState[4]) state.absPos.y = mo_y_abs[player]; state.keyboard.shift = kb_shift[player]; memcpy(state.keyboard.key, kb_key[player], sizeof(kb_key[player])); - state.relPos.x = std::round(mo_x_delta[player]); - state.relPos.y = std::round(mo_y_delta[player]); - state.relPos.wheel = std::round(mo_wheel_delta[player]); - mo_x_delta[player] -= state.relPos.x; - mo_y_delta[player] -= state.relPos.y; - mo_wheel_delta[player] -= state.relPos.wheel; + int relX = std::round(mo_x_delta[player]); + int relY = std::round(mo_y_delta[player]); + int wheel = std::round(mo_wheel_delta[player]); + state.relPos.x += relX; + state.relPos.y += relY; + state.relPos.wheel += wheel; + mo_x_delta[player] -= relX; + mo_y_delta[player] -= relY; + mo_wheel_delta[player] -= wheel; } } @@ -706,6 +710,7 @@ bool nextFrame() } else if (mouseGame) { + std::lock_guard lock(relPosMutex); inputs.mouseButtons = ~mo_buttons[0]; inputs.u.relPos.x = std::round(mo_x_delta[0]); inputs.u.relPos.y = std::round(mo_y_delta[0]); diff --git a/shell/libretro/libretro.cpp b/shell/libretro/libretro.cpp index ca307108f..9a4f29e7f 100644 --- a/shell/libretro/libretro.cpp +++ b/shell/libretro/libretro.cpp @@ -21,6 +21,7 @@ #ifndef _WIN32 #include #endif +#include #ifdef __SWITCH__ #include @@ -136,9 +137,10 @@ s8 joyrx[4], joyry[4]; // bit 3: Wheel button u8 mo_buttons[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; // Relative mouse coordinates [-512:511] -f32 mo_x_delta[4]; -f32 mo_y_delta[4]; -f32 mo_wheel_delta[4]; +float mo_x_delta[4]; +float mo_y_delta[4]; +float mo_wheel_delta[4]; +std::mutex relPosMutex; // Absolute mouse coordinates // Range [0:639] [0:479] // but may be outside this range if the pointer is offscreen or outside the 4:3 window. @@ -2278,8 +2280,10 @@ static void setDeviceButtonStateDirect(u32 bitmap, u32 port, int deviceType, int static void updateMouseState(u32 port) { - mo_x_delta[port] = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); - mo_y_delta[port] = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); + std::lock_guard lock(relPosMutex); + + mo_x_delta[port] += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); + mo_y_delta[port] += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); bool btn_state = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); if (btn_state)