// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include #include "common/assert.h" #include "common/types.h" #include "input/controller.h" #include "input_mouse.h" #include "SDL3/SDL.h" namespace Input { int mouse_joystick_binding = 0; float mouse_deadzone_offset = 0.5, mouse_speed = 1, mouse_speed_offset = 0.1250; bool mouse_gyro_roll_mode = false; Uint32 mouse_polling_id = 0; MouseMode mouse_mode = MouseMode::Off; // Switches mouse to a set mode or turns mouse emulation off if it was already in that mode. // Returns whether the mode is turned on. bool ToggleMouseModeTo(MouseMode m) { if (mouse_mode == m) { mouse_mode = MouseMode::Off; } else { mouse_mode = m; } return mouse_mode == m; } void SetMouseToJoystick(int joystick) { mouse_joystick_binding = joystick; } void SetMouseParams(float mdo, float ms, float mso) { mouse_deadzone_offset = mdo; mouse_speed = ms; mouse_speed_offset = mso; } void SetMouseGyroRollMode(bool mode) { mouse_gyro_roll_mode = mode; } void EmulateJoystick(GameController* controller, u32 interval) { Axis axis_x, axis_y; switch (mouse_joystick_binding) { case 1: axis_x = Axis::LeftX; axis_y = Axis::LeftY; break; case 2: axis_x = Axis::RightX; axis_y = Axis::RightY; break; default: return; // no update needed } float d_x = 0, d_y = 0; SDL_GetRelativeMouseState(&d_x, &d_y); float output_speed = SDL_clamp((sqrt(d_x * d_x + d_y * d_y) + mouse_speed_offset * 128) * mouse_speed, mouse_deadzone_offset * 128, 128.0); float angle = atan2(d_y, d_x); float a_x = cos(angle) * output_speed, a_y = sin(angle) * output_speed; if (d_x != 0 || d_y != 0) { controller->Axis(0, axis_x, GetAxis(-0x80, 0x7f, a_x)); controller->Axis(0, axis_y, GetAxis(-0x80, 0x7f, a_y)); } else { controller->Axis(0, axis_x, GetAxis(-0x80, 0x7f, 0)); controller->Axis(0, axis_y, GetAxis(-0x80, 0x7f, 0)); } } constexpr float constant_down_accel[3] = {0.0f, 10.0f, 0.0f}; void EmulateGyro(GameController* controller, u32 interval) { // LOG_INFO(Input, "todo gyro"); float d_x = 0, d_y = 0; SDL_GetRelativeMouseState(&d_x, &d_y); controller->Acceleration(1, constant_down_accel); float gyro_from_mouse[3] = {-d_y / 100, -d_x / 100, 0.0f}; if (mouse_gyro_roll_mode) { gyro_from_mouse[1] = 0.0f; gyro_from_mouse[2] = -d_x / 100; } controller->Gyro(1, gyro_from_mouse); } Uint32 MousePolling(void* param, Uint32 id, Uint32 interval) { auto* controller = (GameController*)param; switch (mouse_mode) { case MouseMode::Joystick: EmulateJoystick(controller, interval); break; case MouseMode::Gyro: EmulateGyro(controller, interval); break; default: break; } return interval; } } // namespace Input