input_common: Split mouse input into individual devices
This commit is contained in:
parent
57aaf00a0c
commit
17207939e5
10 changed files with 114 additions and 31 deletions
|
@ -23,7 +23,8 @@ void EmulatedConsole::SetTouchParams() {
|
||||||
|
|
||||||
// We can't use mouse as touch if native mouse is enabled
|
// We can't use mouse as touch if native mouse is enabled
|
||||||
if (!Settings::values.mouse_enabled) {
|
if (!Settings::values.mouse_enabled) {
|
||||||
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
touch_params[index++] =
|
||||||
|
Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
|
||||||
}
|
}
|
||||||
|
|
||||||
touch_params[index++] =
|
touch_params[index++] =
|
||||||
|
|
|
@ -34,9 +34,12 @@ void EmulatedDevices::ReloadInput() {
|
||||||
// First two axis are reserved for mouse position
|
// First two axis are reserved for mouse position
|
||||||
key_index = 2;
|
key_index = 2;
|
||||||
for (auto& mouse_device : mouse_analog_devices) {
|
for (auto& mouse_device : mouse_analog_devices) {
|
||||||
|
// Mouse axis are only mapped on port 1, pad 0
|
||||||
Common::ParamPackage mouse_params;
|
Common::ParamPackage mouse_params;
|
||||||
mouse_params.Set("engine", "mouse");
|
mouse_params.Set("engine", "mouse");
|
||||||
mouse_params.Set("axis", static_cast<int>(key_index));
|
mouse_params.Set("axis", static_cast<int>(key_index));
|
||||||
|
mouse_params.Set("port", 1);
|
||||||
|
mouse_params.Set("pad", 0);
|
||||||
mouse_device = Common::Input::CreateInputDevice(mouse_params);
|
mouse_device = Common::Input::CreateInputDevice(mouse_params);
|
||||||
key_index++;
|
key_index++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,23 +15,39 @@ constexpr int mouse_axis_y = 1;
|
||||||
constexpr int wheel_axis_x = 2;
|
constexpr int wheel_axis_x = 2;
|
||||||
constexpr int wheel_axis_y = 3;
|
constexpr int wheel_axis_y = 3;
|
||||||
constexpr int motion_wheel_y = 4;
|
constexpr int motion_wheel_y = 4;
|
||||||
constexpr int touch_axis_x = 10;
|
|
||||||
constexpr int touch_axis_y = 11;
|
|
||||||
constexpr PadIdentifier identifier = {
|
constexpr PadIdentifier identifier = {
|
||||||
.guid = Common::UUID{},
|
.guid = Common::UUID{},
|
||||||
.port = 0,
|
.port = 0,
|
||||||
.pad = 0,
|
.pad = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr PadIdentifier real_mouse_identifier = {
|
||||||
|
.guid = Common::UUID{},
|
||||||
|
.port = 1,
|
||||||
|
.pad = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr PadIdentifier touch_identifier = {
|
||||||
|
.guid = Common::UUID{},
|
||||||
|
.port = 2,
|
||||||
|
.pad = 0,
|
||||||
|
};
|
||||||
|
|
||||||
Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
||||||
PreSetController(identifier);
|
PreSetController(identifier);
|
||||||
|
PreSetController(real_mouse_identifier);
|
||||||
|
PreSetController(touch_identifier);
|
||||||
|
|
||||||
|
// Initialize all mouse axis
|
||||||
PreSetAxis(identifier, mouse_axis_x);
|
PreSetAxis(identifier, mouse_axis_x);
|
||||||
PreSetAxis(identifier, mouse_axis_y);
|
PreSetAxis(identifier, mouse_axis_y);
|
||||||
PreSetAxis(identifier, wheel_axis_x);
|
PreSetAxis(identifier, wheel_axis_x);
|
||||||
PreSetAxis(identifier, wheel_axis_y);
|
PreSetAxis(identifier, wheel_axis_y);
|
||||||
PreSetAxis(identifier, motion_wheel_y);
|
PreSetAxis(identifier, motion_wheel_y);
|
||||||
PreSetAxis(identifier, touch_axis_x);
|
PreSetAxis(real_mouse_identifier, mouse_axis_x);
|
||||||
PreSetAxis(identifier, touch_axis_y);
|
PreSetAxis(real_mouse_identifier, mouse_axis_y);
|
||||||
|
PreSetAxis(touch_identifier, mouse_axis_x);
|
||||||
|
PreSetAxis(touch_identifier, mouse_axis_y);
|
||||||
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
|
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +55,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||||
Common::SetCurrentThreadName("Mouse");
|
Common::SetCurrentThreadName("Mouse");
|
||||||
constexpr int update_time = 10;
|
constexpr int update_time = 10;
|
||||||
while (!stop_token.stop_requested()) {
|
while (!stop_token.stop_requested()) {
|
||||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
if (Settings::values.mouse_panning) {
|
||||||
// Slow movement by 4%
|
// Slow movement by 4%
|
||||||
last_mouse_change *= 0.96f;
|
last_mouse_change *= 0.96f;
|
||||||
const float sensitivity =
|
const float sensitivity =
|
||||||
|
@ -57,17 +73,7 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y) {
|
void Mouse::Move(int x, int y, int center_x, int center_y) {
|
||||||
// If native mouse is enabled just set the screen coordinates
|
|
||||||
if (Settings::values.mouse_enabled) {
|
|
||||||
SetAxis(identifier, mouse_axis_x, touch_x);
|
|
||||||
SetAxis(identifier, mouse_axis_y, touch_y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAxis(identifier, touch_axis_x, touch_x);
|
|
||||||
SetAxis(identifier, touch_axis_y, touch_y);
|
|
||||||
|
|
||||||
if (Settings::values.mouse_panning) {
|
if (Settings::values.mouse_panning) {
|
||||||
auto mouse_change =
|
auto mouse_change =
|
||||||
(Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
|
(Common::MakeVec(x, y) - Common::MakeVec(center_x, center_y)).Cast<float>();
|
||||||
|
@ -113,20 +119,41 @@ void Mouse::MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mouse::PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button) {
|
void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
|
||||||
SetAxis(identifier, touch_axis_x, touch_x);
|
SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
|
||||||
SetAxis(identifier, touch_axis_y, touch_y);
|
SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mouse::TouchMove(f32 touch_x, f32 touch_y) {
|
||||||
|
SetAxis(touch_identifier, mouse_axis_x, touch_x);
|
||||||
|
SetAxis(touch_identifier, mouse_axis_y, touch_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mouse::PressButton(int x, int y, MouseButton button) {
|
||||||
SetButton(identifier, static_cast<int>(button), true);
|
SetButton(identifier, static_cast<int>(button), true);
|
||||||
|
|
||||||
// Set initial analog parameters
|
// Set initial analog parameters
|
||||||
mouse_origin = {x, y};
|
mouse_origin = {x, y};
|
||||||
last_mouse_position = {x, y};
|
last_mouse_position = {x, y};
|
||||||
button_pressed = true;
|
button_pressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mouse::PressMouseButton(MouseButton button) {
|
||||||
|
SetButton(real_mouse_identifier, static_cast<int>(button), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mouse::PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button) {
|
||||||
|
SetAxis(touch_identifier, mouse_axis_x, touch_x);
|
||||||
|
SetAxis(touch_identifier, mouse_axis_y, touch_y);
|
||||||
|
SetButton(touch_identifier, static_cast<int>(button), true);
|
||||||
|
}
|
||||||
|
|
||||||
void Mouse::ReleaseButton(MouseButton button) {
|
void Mouse::ReleaseButton(MouseButton button) {
|
||||||
SetButton(identifier, static_cast<int>(button), false);
|
SetButton(identifier, static_cast<int>(button), false);
|
||||||
|
SetButton(real_mouse_identifier, static_cast<int>(button), false);
|
||||||
|
SetButton(touch_identifier, static_cast<int>(button), false);
|
||||||
|
|
||||||
if (!Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
if (!Settings::values.mouse_panning) {
|
||||||
SetAxis(identifier, mouse_axis_x, 0);
|
SetAxis(identifier, mouse_axis_x, 0);
|
||||||
SetAxis(identifier, mouse_axis_y, 0);
|
SetAxis(identifier, mouse_axis_y, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,43 @@ public:
|
||||||
* @param center_x the x-coordinate of the middle of the screen
|
* @param center_x the x-coordinate of the middle of the screen
|
||||||
* @param center_y the y-coordinate of the middle of the screen
|
* @param center_y the y-coordinate of the middle of the screen
|
||||||
*/
|
*/
|
||||||
void MouseMove(int x, int y, f32 touch_x, f32 touch_y, int center_x, int center_y);
|
void Move(int x, int y, int center_x, int center_y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the status of all buttons bound with the key to pressed
|
* Signals that real mouse has moved.
|
||||||
* @param key_code the code of the key to press
|
* @param x the absolute position on the touchscreen of the cursor
|
||||||
|
* @param y the absolute position on the touchscreen of the cursor
|
||||||
*/
|
*/
|
||||||
void PressButton(int x, int y, f32 touch_x, f32 touch_y, MouseButton button);
|
void MouseMove(f32 touch_x, f32 touch_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that touch finger has moved.
|
||||||
|
* @param x the absolute position on the touchscreen of the cursor
|
||||||
|
* @param y the absolute position on the touchscreen of the cursor
|
||||||
|
*/
|
||||||
|
void TouchMove(f32 touch_x, f32 touch_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of a button to pressed
|
||||||
|
* @param x the x-coordinate of the cursor
|
||||||
|
* @param y the y-coordinate of the cursor
|
||||||
|
* @param button the id of the button to press
|
||||||
|
*/
|
||||||
|
void PressButton(int x, int y, MouseButton button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of a mouse button to pressed
|
||||||
|
* @param button the id of the button to press
|
||||||
|
*/
|
||||||
|
void PressMouseButton(MouseButton button);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of touch finger to pressed
|
||||||
|
* @param x the absolute position on the touchscreen of the cursor
|
||||||
|
* @param y the absolute position on the touchscreen of the cursor
|
||||||
|
* @param button the id of the button to press
|
||||||
|
*/
|
||||||
|
void PressTouchButton(f32 touch_x, f32 touch_y, MouseButton button);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the status of all buttons bound with the key to released
|
* Sets the status of all buttons bound with the key to released
|
||||||
|
|
|
@ -194,6 +194,10 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
|
||||||
if (data.engine == "keyboard" && data.pad.port != 0) {
|
if (data.engine == "keyboard" && data.pad.port != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Only port 0 can be mapped on the mouse
|
||||||
|
if (data.engine == "mouse" && data.pad.port != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// To prevent mapping with two devices we disable any UDP except motion
|
// To prevent mapping with two devices we disable any UDP except motion
|
||||||
if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
|
if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
|
||||||
data.type != EngineInputType::Motion) {
|
data.type != EngineInputType::Motion) {
|
||||||
|
|
|
@ -645,7 +645,10 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
||||||
const auto pos = mapFromGlobal(QCursor::pos());
|
const auto pos = mapFromGlobal(QCursor::pos());
|
||||||
const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
|
const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
|
||||||
const auto button = QtButtonToMouseButton(event->button());
|
const auto button = QtButtonToMouseButton(event->button());
|
||||||
input_subsystem->GetMouse()->PressButton(pos.x(), pos.y(), touch_x, touch_y, button);
|
|
||||||
|
input_subsystem->GetMouse()->PressMouseButton(button);
|
||||||
|
input_subsystem->GetMouse()->PressButton(pos.x(), pos.y(), button);
|
||||||
|
input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, button);
|
||||||
|
|
||||||
emit MouseActivity();
|
emit MouseActivity();
|
||||||
}
|
}
|
||||||
|
@ -661,7 +664,10 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||||
const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
|
const auto [touch_x, touch_y] = MapToTouchScreen(pos.x(), pos.y());
|
||||||
const int center_x = width() / 2;
|
const int center_x = width() / 2;
|
||||||
const int center_y = height() / 2;
|
const int center_y = height() / 2;
|
||||||
input_subsystem->GetMouse()->MouseMove(pos.x(), pos.y(), touch_x, touch_y, center_x, center_y);
|
|
||||||
|
input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
|
||||||
|
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||||
|
input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y);
|
||||||
|
|
||||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||||
|
|
|
@ -1490,7 +1490,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
||||||
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
|
input_subsystem->GetMouse()->PressButton(0, 0, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) {
|
void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) {
|
||||||
|
|
|
@ -371,7 +371,7 @@ void ConfigureRingController::mousePressEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
|
||||||
input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button);
|
input_subsystem->GetMouse()->PressButton(0, 0, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
|
void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
|
@ -1165,6 +1165,14 @@ void GMainWindow::InitializeHotkeys() {
|
||||||
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
|
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
|
||||||
});
|
});
|
||||||
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
|
connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] {
|
||||||
|
if (Settings::values.mouse_enabled) {
|
||||||
|
Settings::values.mouse_panning = false;
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Emulated mouse is enabled"),
|
||||||
|
tr("Real mouse input and mouse panning are incompatible. Please disable the "
|
||||||
|
"emulated mouse in input advanced settings to allow mouse panning."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
||||||
if (Settings::values.mouse_panning) {
|
if (Settings::values.mouse_panning) {
|
||||||
render_window->installEventFilter(render_window);
|
render_window->installEventFilter(render_window);
|
||||||
|
|
|
@ -62,7 +62,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||||
const auto mouse_button = SDLButtonToMouseButton(button);
|
const auto mouse_button = SDLButtonToMouseButton(button);
|
||||||
if (state == SDL_PRESSED) {
|
if (state == SDL_PRESSED) {
|
||||||
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||||
input_subsystem->GetMouse()->PressButton(x, y, touch_x, touch_y, mouse_button);
|
input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
|
||||||
|
input_subsystem->GetMouse()->PressMouseButton(mouse_button);
|
||||||
|
input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button);
|
||||||
} else {
|
} else {
|
||||||
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
|
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +72,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
||||||
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||||
input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, 0, 0);
|
input_subsystem->GetMouse()->Move(x, y, 0, 0);
|
||||||
|
input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
|
||||||
|
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
|
void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
|
||||||
|
|
Loading…
Reference in a new issue