summaryrefslogtreecommitdiffstats
path: root/src/core/hid
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hid')
-rw-r--r--src/core/hid/emulated_controller.cpp43
-rw-r--r--src/core/hid/emulated_controller.h6
-rw-r--r--src/core/hid/input_converter.cpp10
-rw-r--r--src/core/hid/motion_input.cpp36
-rw-r--r--src/core/hid/motion_input.h2
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;