diff options
Diffstat (limited to 'src/core/hid')
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 43 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.h | 6 | ||||
-rw-r--r-- | src/core/hid/input_converter.cpp | 10 | ||||
-rw-r--r-- | src/core/hid/motion_input.cpp | 36 | ||||
-rw-r--r-- | src/core/hid/motion_input.h | 2 |
5 files changed, 74 insertions, 23 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index a29c9a6f8..c7f0af71f 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -280,6 +280,10 @@ void EmulatedController::LoadVirtualGamepadParams() { virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1); virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2); virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3); + virtual_stick_params[Settings::NativeAnalog::LStick].Set("deadzone", 0.0f); + virtual_stick_params[Settings::NativeAnalog::LStick].Set("range", 1.0f); + virtual_stick_params[Settings::NativeAnalog::RStick].Set("deadzone", 0.0f); + virtual_stick_params[Settings::NativeAnalog::RStick].Set("range", 1.0f); } void EmulatedController::ReloadInput() { @@ -372,6 +376,7 @@ void EmulatedController::ReloadInput() { motion.accel = emulated_motion.GetAcceleration(); motion.gyro = emulated_motion.GetGyroscope(); motion.rotation = emulated_motion.GetRotations(); + motion.euler = emulated_motion.GetEulerAngles(); motion.orientation = emulated_motion.GetOrientation(); motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity); } @@ -547,6 +552,8 @@ void EmulatedController::EnableSystemButtons() { void EmulatedController::DisableSystemButtons() { std::scoped_lock lock{mutex}; system_buttons_enabled = false; + controller.home_button_state.raw = 0; + controller.capture_button_state.raw = 0; } void EmulatedController::ResetSystemButtons() { @@ -730,6 +737,8 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback if (is_configuring) { controller.npad_button_state.raw = NpadButton::None; controller.debug_pad_button_state.raw = 0; + controller.home_button_state.raw = 0; + controller.capture_button_state.raw = 0; lock.unlock(); TriggerOnChange(ControllerTriggerType::Button, false); return; @@ -970,16 +979,12 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold); emulated.UpdateRotation(raw_status.delta_timestamp); emulated.UpdateOrientation(raw_status.delta_timestamp); - force_update_motion = raw_status.force_update; - - if (is_configuring) { - return; - } auto& motion = controller.motion_state[index]; motion.accel = emulated.GetAcceleration(); motion.gyro = emulated.GetGyroscope(); motion.rotation = emulated.GetRotations(); + motion.euler = emulated.GetEulerAngles(); motion.orientation = emulated.GetOrientation(); motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); } @@ -1612,19 +1617,6 @@ NpadGcTriggerState EmulatedController::GetTriggers() const { MotionState EmulatedController::GetMotions() const { std::unique_lock lock{mutex}; - - // Some drivers like mouse motion need constant refreshing - if (force_update_motion) { - for (auto& device : motion_devices) { - if (!device) { - continue; - } - lock.unlock(); - device->ForceUpdate(); - lock.lock(); - } - } - return controller.motion_state; } @@ -1690,8 +1682,21 @@ void EmulatedController::DeleteCallback(int key) { callback_list.erase(iterator); } -void EmulatedController::TurboButtonUpdate() { +void EmulatedController::StatusUpdate() { turbo_button_state = (turbo_button_state + 1) % (TURBO_BUTTON_DELAY * 2); + + // Some drivers like key motion need constant refreshing + for (std::size_t index = 0; index < motion_devices.size(); ++index) { + const auto& raw_status = controller.motion_values[index].raw_status; + auto& device = motion_devices[index]; + if (!raw_status.force_update) { + continue; + } + if (!device) { + continue; + } + device->ForceUpdate(); + } } NpadButton EmulatedController::GetTurboButtonMask() const { diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 429655355..fa4ad7fae 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -106,6 +106,7 @@ struct ControllerMotion { Common::Vec3f accel{}; Common::Vec3f gyro{}; Common::Vec3f rotation{}; + Common::Vec3f euler{}; std::array<Common::Vec3f, 3> orientation{}; bool is_at_rest{}; }; @@ -414,8 +415,8 @@ public: */ void DeleteCallback(int key); - /// Swaps the state of the turbo buttons - void TurboButtonUpdate(); + /// Swaps the state of the turbo buttons and updates motion input + void StatusUpdate(); private: /// creates input devices from params @@ -527,7 +528,6 @@ private: bool is_configuring{false}; bool system_buttons_enabled{true}; f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; - bool force_update_motion{false}; u32 turbo_button_state{0}; // Temporary values to avoid doing changes while the controller is in configuring mode diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 7cee39a53..4ccb1c596 100644 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp @@ -54,6 +54,7 @@ Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatu case Common::Input::InputType::Analog: status.value = TransformToTrigger(callback).pressed.value; status.toggle = callback.analog_status.properties.toggle; + status.inverted = callback.analog_status.properties.inverted_button; break; case Common::Input::InputType::Trigger: status.value = TransformToTrigger(callback).pressed.value; @@ -61,6 +62,9 @@ Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatu case Common::Input::InputType::Button: status = callback.button_status; break; + case Common::Input::InputType::Motion: + status.value = std::abs(callback.motion_status.gyro.x.raw_value) > 1.0f; + break; default: LOG_ERROR(Input, "Conversion from type {} to button not implemented", callback.type); break; @@ -82,7 +86,7 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu .range = 1.0f, .offset = 0.0f, }; - status.delta_timestamp = 5000; + status.delta_timestamp = 1000; status.force_update = true; status.accel.x = { .value = 0.0f, @@ -226,6 +230,10 @@ Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackSta status = callback.trigger_status; calculate_button_value = false; break; + case Common::Input::InputType::Motion: + status.analog.properties.range = 1.0f; + raw_value = callback.motion_status.accel.x.raw_value; + break; default: LOG_ERROR(Input, "Conversion from type {} to trigger not implemented", callback.type); break; diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp index 0dd66c1cc..b60478dbb 100644 --- a/src/core/hid/motion_input.cpp +++ b/src/core/hid/motion_input.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <cmath> + #include "common/math_util.h" #include "core/hid/motion_input.h" @@ -51,6 +53,20 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) { quat = quaternion; } +void MotionInput::SetEulerAngles(const Common::Vec3f& euler_angles) { + const float cr = std::cos(euler_angles.x * 0.5f); + const float sr = std::sin(euler_angles.x * 0.5f); + const float cp = std::cos(euler_angles.y * 0.5f); + const float sp = std::sin(euler_angles.y * 0.5f); + const float cy = std::cos(euler_angles.z * 0.5f); + const float sy = std::sin(euler_angles.z * 0.5f); + + quat.w = cr * cp * cy + sr * sp * sy; + quat.xyz.x = sr * cp * cy - cr * sp * sy; + quat.xyz.y = cr * sp * cy + sr * cp * sy; + quat.xyz.z = cr * cp * sy - sr * sp * cy; +} + void MotionInput::SetGyroBias(const Common::Vec3f& bias) { gyro_bias = bias; } @@ -222,6 +238,26 @@ Common::Vec3f MotionInput::GetRotations() const { return rotations; } +Common::Vec3f MotionInput::GetEulerAngles() const { + // roll (x-axis rotation) + const float sinr_cosp = 2 * (quat.w * quat.xyz.x + quat.xyz.y * quat.xyz.z); + const float cosr_cosp = 1 - 2 * (quat.xyz.x * quat.xyz.x + quat.xyz.y * quat.xyz.y); + + // pitch (y-axis rotation) + const float sinp = std::sqrt(1 + 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z)); + const float cosp = std::sqrt(1 - 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z)); + + // yaw (z-axis rotation) + const float siny_cosp = 2 * (quat.w * quat.xyz.z + quat.xyz.x * quat.xyz.y); + const float cosy_cosp = 1 - 2 * (quat.xyz.y * quat.xyz.y + quat.xyz.z * quat.xyz.z); + + return { + std::atan2(sinr_cosp, cosr_cosp), + 2 * std::atan2(sinp, cosp) - Common::PI / 2, + std::atan2(siny_cosp, cosy_cosp), + }; +} + void MotionInput::ResetOrientation() { if (!reset_enabled || only_accelerometer) { return; diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 9f3fc1cf7..482719359 100644 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h @@ -35,6 +35,7 @@ public: void SetAcceleration(const Common::Vec3f& acceleration); void SetGyroscope(const Common::Vec3f& gyroscope); void SetQuaternion(const Common::Quaternion<f32>& quaternion); + void SetEulerAngles(const Common::Vec3f& euler_angles); void SetGyroBias(const Common::Vec3f& bias); void SetGyroThreshold(f32 threshold); @@ -54,6 +55,7 @@ public: [[nodiscard]] Common::Vec3f GetGyroBias() const; [[nodiscard]] Common::Vec3f GetRotations() const; [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const; + [[nodiscard]] Common::Vec3f GetEulerAngles() const; [[nodiscard]] bool IsMoving(f32 sensitivity) const; [[nodiscard]] bool IsCalibrated(f32 sensitivity) const; |