mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
* Rework framework to allow for more types of mouse-to-something emulation and hook up gyro to it * Remove the unnecessary null check now that deltatime is handled differently * Fix toggle key * Basic gyro emulation working for two out of the three dimensions * clang * Added bindable key to hold for switching from looking to the sides to rolling * documentation
112 lines
3.0 KiB
C++
112 lines
3.0 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <cmath>
|
|
|
|
#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
|