core/hid: Fully implement native mouse
This commit is contained in:
parent
bca299e8e0
commit
654d76e79e
21 changed files with 323 additions and 1039 deletions
|
@ -24,7 +24,10 @@ void EmulatedConsole::SetTouchParams() {
|
|||
std::size_t index = 0;
|
||||
|
||||
// Hardcode mouse, touchscreen and cemuhook parameters
|
||||
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
||||
if (!Settings::values.mouse_enabled) {
|
||||
// We can't use mouse as touch if native mouse is enabled
|
||||
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
||||
}
|
||||
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"};
|
||||
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"};
|
||||
touch_params[index++] = Common::ParamPackage{"engine:cemuhookudp,axis_x:0,axis_y:1,button:0"};
|
||||
|
@ -36,6 +39,9 @@ void EmulatedConsole::SetTouchParams() {
|
|||
|
||||
// Map the rest of the fingers from touch from button configuration
|
||||
for (const auto& config_entry : touch_buttons) {
|
||||
if (index >= touch_params.size()) {
|
||||
continue;
|
||||
}
|
||||
Common::ParamPackage params{config_entry};
|
||||
Common::ParamPackage touch_button_params;
|
||||
const int x = params.Get("x", 0);
|
||||
|
@ -49,9 +55,6 @@ void EmulatedConsole::SetTouchParams() {
|
|||
touch_button_params.Set("touch_id", static_cast<int>(index));
|
||||
touch_params[index] = touch_button_params;
|
||||
index++;
|
||||
if (index >= touch_params.size()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,21 +15,34 @@ EmulatedDevices::EmulatedDevices() = default;
|
|||
EmulatedDevices::~EmulatedDevices() = default;
|
||||
|
||||
void EmulatedDevices::ReloadFromSettings() {
|
||||
const auto& mouse = Settings::values.mouse_buttons;
|
||||
|
||||
for (std::size_t index = 0; index < mouse.size(); ++index) {
|
||||
mouse_button_params[index] = Common::ParamPackage(mouse[index]);
|
||||
}
|
||||
ReloadInput();
|
||||
}
|
||||
|
||||
void EmulatedDevices::ReloadInput() {
|
||||
std::transform(mouse_button_params.begin() + Settings::NativeMouseButton::MOUSE_HID_BEGIN,
|
||||
mouse_button_params.begin() + Settings::NativeMouseButton::MOUSE_HID_END,
|
||||
mouse_button_devices.begin(),
|
||||
Common::Input::CreateDevice<Common::Input::InputDevice>);
|
||||
|
||||
// If you load any device here add the equivalent to the UnloadInput() function
|
||||
std::size_t key_index = 0;
|
||||
for (auto& mouse_device : mouse_button_devices) {
|
||||
Common::ParamPackage mouse_params;
|
||||
mouse_params.Set("engine", "mouse");
|
||||
mouse_params.Set("button", static_cast<int>(key_index));
|
||||
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
mouse_stick_device = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
|
||||
"engine:mouse,axis_x:0,axis_y:1");
|
||||
|
||||
// First two axis are reserved for mouse position
|
||||
key_index = 2;
|
||||
for (auto& mouse_device : mouse_analog_devices) {
|
||||
Common::ParamPackage mouse_params;
|
||||
mouse_params.Set("engine", "mouse");
|
||||
mouse_params.Set("axis", static_cast<int>(key_index));
|
||||
mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params);
|
||||
key_index++;
|
||||
}
|
||||
|
||||
key_index = 0;
|
||||
for (auto& keyboard_device : keyboard_devices) {
|
||||
// Keyboard keys are only mapped on port 1, pad 0
|
||||
Common::ParamPackage keyboard_params;
|
||||
|
@ -64,6 +77,23 @@ void EmulatedDevices::ReloadInput() {
|
|||
mouse_button_devices[index]->SetCallback(button_callback);
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; index < mouse_analog_devices.size(); ++index) {
|
||||
if (!mouse_analog_devices[index]) {
|
||||
continue;
|
||||
}
|
||||
Common::Input::InputCallback button_callback{
|
||||
[this, index](Common::Input::CallbackStatus callback) {
|
||||
SetMouseAnalog(callback, index);
|
||||
}};
|
||||
mouse_analog_devices[index]->SetCallback(button_callback);
|
||||
}
|
||||
|
||||
if (mouse_stick_device) {
|
||||
Common::Input::InputCallback button_callback{
|
||||
[this](Common::Input::CallbackStatus callback) { SetMouseStick(callback); }};
|
||||
mouse_stick_device->SetCallback(button_callback);
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; index < keyboard_devices.size(); ++index) {
|
||||
if (!keyboard_devices[index]) {
|
||||
continue;
|
||||
|
@ -91,6 +121,10 @@ void EmulatedDevices::UnloadInput() {
|
|||
for (auto& button : mouse_button_devices) {
|
||||
button.reset();
|
||||
}
|
||||
for (auto& analog : mouse_analog_devices) {
|
||||
analog.reset();
|
||||
}
|
||||
mouse_stick_device.reset();
|
||||
for (auto& button : keyboard_devices) {
|
||||
button.reset();
|
||||
}
|
||||
|
@ -116,12 +150,6 @@ void EmulatedDevices::SaveCurrentConfig() {
|
|||
if (!is_configuring) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& mouse = Settings::values.mouse_buttons;
|
||||
|
||||
for (std::size_t index = 0; index < mouse.size(); ++index) {
|
||||
mouse[index] = mouse_button_params[index].Serialize();
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedDevices::RestoreConfig() {
|
||||
|
@ -131,21 +159,6 @@ void EmulatedDevices::RestoreConfig() {
|
|||
ReloadFromSettings();
|
||||
}
|
||||
|
||||
Common::ParamPackage EmulatedDevices::GetMouseButtonParam(std::size_t index) const {
|
||||
if (index >= mouse_button_params.size()) {
|
||||
return {};
|
||||
}
|
||||
return mouse_button_params[index];
|
||||
}
|
||||
|
||||
void EmulatedDevices::SetMouseButtonParam(std::size_t index, Common::ParamPackage param) {
|
||||
if (index >= mouse_button_params.size()) {
|
||||
return;
|
||||
}
|
||||
mouse_button_params[index] = param;
|
||||
ReloadInput();
|
||||
}
|
||||
|
||||
void EmulatedDevices::SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index) {
|
||||
if (index >= device_status.keyboard_values.size()) {
|
||||
return;
|
||||
|
@ -334,6 +347,51 @@ void EmulatedDevices::SetMouseButton(Common::Input::CallbackStatus callback, std
|
|||
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||
}
|
||||
|
||||
void EmulatedDevices::SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index) {
|
||||
if (index >= device_status.mouse_analog_values.size()) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard lock{mutex};
|
||||
const auto analog_value = TransformToAnalog(callback);
|
||||
|
||||
device_status.mouse_analog_values[index] = analog_value;
|
||||
|
||||
if (is_configuring) {
|
||||
device_status.mouse_position_state = {};
|
||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case Settings::NativeMouseWheel::X:
|
||||
device_status.mouse_wheel_state.x = static_cast<s32>(analog_value.value);
|
||||
break;
|
||||
case Settings::NativeMouseWheel::Y:
|
||||
device_status.mouse_wheel_state.y = static_cast<s32>(analog_value.value);
|
||||
break;
|
||||
}
|
||||
|
||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||
}
|
||||
|
||||
void EmulatedDevices::SetMouseStick(Common::Input::CallbackStatus callback) {
|
||||
std::lock_guard lock{mutex};
|
||||
const auto stick_value = TransformToStick(callback);
|
||||
|
||||
device_status.mouse_stick_value = stick_value;
|
||||
|
||||
if (is_configuring) {
|
||||
device_status.mouse_position_state = {};
|
||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||
return;
|
||||
}
|
||||
|
||||
device_status.mouse_position_state.x = stick_value.x.value;
|
||||
device_status.mouse_position_state.y = stick_value.y.value;
|
||||
|
||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||
}
|
||||
|
||||
KeyboardValues EmulatedDevices::GetKeyboardValues() const {
|
||||
return device_status.keyboard_values;
|
||||
}
|
||||
|
@ -362,6 +420,10 @@ MousePosition EmulatedDevices::GetMousePosition() const {
|
|||
return device_status.mouse_position_state;
|
||||
}
|
||||
|
||||
AnalogStickState EmulatedDevices::GetMouseDeltaWheel() const {
|
||||
return device_status.mouse_wheel_state;
|
||||
}
|
||||
|
||||
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
|
||||
for (const auto& poller_pair : callback_list) {
|
||||
const InterfaceUpdateCallback& poller = poller_pair.second;
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::HID {
|
||||
|
||||
using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
|
||||
Settings::NativeKeyboard::NumKeyboardKeys>;
|
||||
using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
|
||||
Settings::NativeKeyboard::NumKeyboardMods>;
|
||||
using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
|
||||
Settings::NativeMouseButton::NumMouseButtons>;
|
||||
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
|
||||
Settings::NativeMouseWheel::NumMouseWheels>;
|
||||
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
|
||||
|
||||
using MouseButtonParams =
|
||||
std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
|
||||
|
@ -34,12 +36,13 @@ using KeyboardModifierValues =
|
|||
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
|
||||
using MouseButtonValues =
|
||||
std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
|
||||
using MouseAnalogValues =
|
||||
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
|
||||
using MouseStickValue = Common::Input::StickStatus;
|
||||
|
||||
struct MousePosition {
|
||||
s32 x;
|
||||
s32 y;
|
||||
s32 delta_wheel_x;
|
||||
s32 delta_wheel_y;
|
||||
f32 x;
|
||||
f32 y;
|
||||
};
|
||||
|
||||
struct DeviceStatus {
|
||||
|
@ -47,12 +50,15 @@ struct DeviceStatus {
|
|||
KeyboardValues keyboard_values{};
|
||||
KeyboardModifierValues keyboard_moddifier_values{};
|
||||
MouseButtonValues mouse_button_values{};
|
||||
MouseAnalogValues mouse_analog_values{};
|
||||
MouseStickValue mouse_stick_value{};
|
||||
|
||||
// Data for HID serices
|
||||
KeyboardKey keyboard_state{};
|
||||
KeyboardModifier keyboard_moddifier_state{};
|
||||
MouseButton mouse_button_state{};
|
||||
MousePosition mouse_position_state{};
|
||||
AnalogStickState mouse_wheel_state{};
|
||||
};
|
||||
|
||||
enum class DeviceTriggerType {
|
||||
|
@ -102,15 +108,6 @@ public:
|
|||
/// Reverts any mapped changes made that weren't saved
|
||||
void RestoreConfig();
|
||||
|
||||
/// Returns the current mapped mouse button device
|
||||
Common::ParamPackage GetMouseButtonParam(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Updates the current mapped mouse button device
|
||||
* @param ParamPackage with controller data to be mapped
|
||||
*/
|
||||
void SetMouseButtonParam(std::size_t index, Common::ParamPackage param);
|
||||
|
||||
/// Returns the latest status of button input from the keyboard with parameters
|
||||
KeyboardValues GetKeyboardValues() const;
|
||||
|
||||
|
@ -132,9 +129,12 @@ public:
|
|||
/// Returns the latest mouse coordinates
|
||||
MousePosition GetMousePosition() const;
|
||||
|
||||
/// Returns the latest mouse wheel change
|
||||
AnalogStickState GetMouseDeltaWheel() const;
|
||||
|
||||
/**
|
||||
* Adds a callback to the list of events
|
||||
* @param ConsoleUpdateCallback that will be triggered
|
||||
* @param InterfaceUpdateCallback that will be triggered
|
||||
* @return an unique key corresponding to the callback index in the list
|
||||
*/
|
||||
int SetCallback(InterfaceUpdateCallback update_callback);
|
||||
|
@ -150,26 +150,40 @@ private:
|
|||
void UpdateKey(std::size_t key_index, bool status);
|
||||
|
||||
/**
|
||||
* Updates the touch status of the console
|
||||
* Updates the touch status of the keyboard device
|
||||
* @param callback: A CallbackStatus containing the key status
|
||||
* @param index: key ID to be updated
|
||||
*/
|
||||
void SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index);
|
||||
|
||||
/**
|
||||
* Updates the touch status of the console
|
||||
* Updates the keyboard status of the keyboard device
|
||||
* @param callback: A CallbackStatus containing the modifier key status
|
||||
* @param index: modifier key ID to be updated
|
||||
*/
|
||||
void SetKeyboardModifier(Common::Input::CallbackStatus callback, std::size_t index);
|
||||
|
||||
/**
|
||||
* Updates the touch status of the console
|
||||
* Updates the mouse button status of the mouse device
|
||||
* @param callback: A CallbackStatus containing the button status
|
||||
* @param index: Button ID of the to be updated
|
||||
* @param index: Button ID to be updated
|
||||
*/
|
||||
void SetMouseButton(Common::Input::CallbackStatus callback, std::size_t index);
|
||||
|
||||
/**
|
||||
* Updates the mouse wheel status of the mouse device
|
||||
* @param callback: A CallbackStatus containing the wheel status
|
||||
* @param index: wheel ID to be updated
|
||||
*/
|
||||
void SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index);
|
||||
|
||||
/**
|
||||
* Updates the mouse position status of the mouse device
|
||||
* @param callback: A CallbackStatus containing the position status
|
||||
* @param index: stick ID to be updated
|
||||
*/
|
||||
void SetMouseStick(Common::Input::CallbackStatus callback);
|
||||
|
||||
/**
|
||||
* Triggers a callback that something has changed on the device status
|
||||
* @param Input type of the event to trigger
|
||||
|
@ -178,11 +192,11 @@ private:
|
|||
|
||||
bool is_configuring{false};
|
||||
|
||||
MouseButtonParams mouse_button_params;
|
||||
|
||||
KeyboardDevices keyboard_devices;
|
||||
KeyboardModifierDevices keyboard_modifier_devices;
|
||||
MouseButtonDevices mouse_button_devices;
|
||||
MouseAnalogDevices mouse_analog_devices;
|
||||
MouseStickDevice mouse_stick_device;
|
||||
|
||||
mutable std::mutex mutex;
|
||||
std::unordered_map<int, InterfaceUpdateCallback> callback_list;
|
||||
|
|
|
@ -242,6 +242,27 @@ Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackSta
|
|||
return status;
|
||||
}
|
||||
|
||||
Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback) {
|
||||
Common::Input::AnalogStatus status{};
|
||||
|
||||
switch (callback.type) {
|
||||
case Common::Input::InputType::Analog:
|
||||
status.properties = callback.analog_status.properties;
|
||||
status.raw_value = callback.analog_status.raw_value;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Input, "Conversion from type {} to analog not implemented", callback.type);
|
||||
break;
|
||||
}
|
||||
|
||||
SanitizeAnalog(status, false);
|
||||
|
||||
// Adjust if value is inverted
|
||||
status.value = status.properties.inverted ? -status.value : status.value;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
|
||||
const auto& properties = analog.properties;
|
||||
float& raw_value = analog.raw_value;
|
||||
|
|
|
@ -68,6 +68,15 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
|
|||
*/
|
||||
Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback);
|
||||
|
||||
/**
|
||||
* Converts raw input data into a valid analog status. Applies offset, deadzone, range and
|
||||
* invert properties to the output.
|
||||
*
|
||||
* @param Supported callbacks: Analog.
|
||||
* @return A valid AnalogStatus object.
|
||||
*/
|
||||
Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback);
|
||||
|
||||
/**
|
||||
* Converts raw analog data into a valid analog value
|
||||
* @param An analog object containing raw data and properties, bool that determines if the value
|
||||
|
|
|
@ -38,13 +38,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
|||
if (Settings::values.mouse_enabled) {
|
||||
const auto& mouse_button_state = emulated_devices->GetMouseButtons();
|
||||
const auto& mouse_position_state = emulated_devices->GetMousePosition();
|
||||
const auto& mouse_wheel_state = emulated_devices->GetMouseDeltaWheel();
|
||||
next_state.attribute.is_connected.Assign(1);
|
||||
next_state.x = mouse_position_state.x;
|
||||
next_state.y = mouse_position_state.y;
|
||||
next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
|
||||
next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
|
||||
next_state.delta_x = next_state.x - last_entry.x;
|
||||
next_state.delta_y = next_state.y - last_entry.y;
|
||||
next_state.delta_wheel_x = mouse_position_state.delta_wheel_x;
|
||||
next_state.delta_wheel_y = mouse_position_state.delta_wheel_y;
|
||||
next_state.delta_wheel_x = mouse_wheel_state.x;
|
||||
next_state.delta_wheel_y = mouse_wheel_state.y;
|
||||
|
||||
next_state.button = mouse_button_state;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue