diff options
| author | 2021-11-01 19:49:14 -0600 | |
|---|---|---|
| committer | 2021-11-24 20:30:27 -0600 | |
| commit | 136eb9c4c2b2425c2dd45a79cf444dee7170714d (patch) | |
| tree | 74a055a08126fdd33b2071baa08125177847db6e | |
| parent | second commit lion review (diff) | |
| download | yuzu-136eb9c4c2b2425c2dd45a79cf444dee7170714d.tar.gz yuzu-136eb9c4c2b2425c2dd45a79cf444dee7170714d.tar.xz yuzu-136eb9c4c2b2425c2dd45a79cf444dee7170714d.zip | |
core/hid: Fully emulate motion from button
Diffstat (limited to '')
| -rw-r--r-- | src/common/input.h | 5 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 11 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 1 | ||||
| -rw-r--r-- | src/core/hid/input_converter.cpp | 78 | ||||
| -rw-r--r-- | src/core/hid/motion_input.h | 16 | ||||
| -rw-r--r-- | src/input_common/helpers/stick_from_buttons.cpp | 12 | ||||
| -rw-r--r-- | src/input_common/helpers/touch_from_buttons.cpp | 11 |
7 files changed, 97 insertions, 37 deletions
diff --git a/src/common/input.h b/src/common/input.h index 12acd8785..8f29026a1 100644 --- a/src/common/input.h +++ b/src/common/input.h | |||
| @@ -110,9 +110,14 @@ struct MotionSensor { | |||
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | struct MotionStatus { | 112 | struct MotionStatus { |
| 113 | // Gyroscope vector measurement in radians/s. | ||
| 113 | MotionSensor gyro{}; | 114 | MotionSensor gyro{}; |
| 115 | // Acceleration vector measurement in G force | ||
| 114 | MotionSensor accel{}; | 116 | MotionSensor accel{}; |
| 117 | // Time since last measurement in microseconds | ||
| 115 | u64 delta_timestamp{}; | 118 | u64 delta_timestamp{}; |
| 119 | // Request to update after reading the value | ||
| 120 | bool force_update{}; | ||
| 116 | }; | 121 | }; |
| 117 | 122 | ||
| 118 | struct TouchStatus { | 123 | struct TouchStatus { |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 7bab00bb1..2db2b4da0 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -644,6 +644,7 @@ void EmulatedController::SetMotion(Common::Input::CallbackStatus callback, std:: | |||
| 644 | }); | 644 | }); |
| 645 | emulated.UpdateRotation(raw_status.delta_timestamp); | 645 | emulated.UpdateRotation(raw_status.delta_timestamp); |
| 646 | emulated.UpdateOrientation(raw_status.delta_timestamp); | 646 | emulated.UpdateOrientation(raw_status.delta_timestamp); |
| 647 | force_update_motion = raw_status.force_update; | ||
| 647 | 648 | ||
| 648 | if (is_configuring) { | 649 | if (is_configuring) { |
| 649 | TriggerOnChange(ControllerTriggerType::Motion, false); | 650 | TriggerOnChange(ControllerTriggerType::Motion, false); |
| @@ -653,7 +654,7 @@ void EmulatedController::SetMotion(Common::Input::CallbackStatus callback, std:: | |||
| 653 | auto& motion = controller.motion_state[index]; | 654 | auto& motion = controller.motion_state[index]; |
| 654 | motion.accel = emulated.GetAcceleration(); | 655 | motion.accel = emulated.GetAcceleration(); |
| 655 | motion.gyro = emulated.GetGyroscope(); | 656 | motion.gyro = emulated.GetGyroscope(); |
| 656 | motion.rotation = emulated.GetGyroscope(); | 657 | motion.rotation = emulated.GetRotations(); |
| 657 | motion.orientation = emulated.GetOrientation(); | 658 | motion.orientation = emulated.GetOrientation(); |
| 658 | motion.is_at_rest = emulated.IsMoving(motion_sensitivity); | 659 | motion.is_at_rest = emulated.IsMoving(motion_sensitivity); |
| 659 | 660 | ||
| @@ -962,6 +963,14 @@ NpadGcTriggerState EmulatedController::GetTriggers() const { | |||
| 962 | } | 963 | } |
| 963 | 964 | ||
| 964 | MotionState EmulatedController::GetMotions() const { | 965 | MotionState EmulatedController::GetMotions() const { |
| 966 | if (force_update_motion) { | ||
| 967 | for (auto& device : motion_devices) { | ||
| 968 | if (!device) { | ||
| 969 | continue; | ||
| 970 | } | ||
| 971 | device->ForceUpdate(); | ||
| 972 | } | ||
| 973 | } | ||
| 965 | return controller.motion_state; | 974 | return controller.motion_state; |
| 966 | } | 975 | } |
| 967 | 976 | ||
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index dd9a93364..2f7afff56 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -355,6 +355,7 @@ private: | |||
| 355 | bool is_connected{false}; | 355 | bool is_connected{false}; |
| 356 | bool is_configuring{false}; | 356 | bool is_configuring{false}; |
| 357 | f32 motion_sensitivity{0.01f}; | 357 | f32 motion_sensitivity{0.01f}; |
| 358 | bool force_update_motion{false}; | ||
| 358 | 359 | ||
| 359 | // Temporary values to avoid doing changes while the controller is on configuration mode | 360 | // Temporary values to avoid doing changes while the controller is on configuration mode |
| 360 | NpadType tmp_npad_type{NpadType::None}; | 361 | NpadType tmp_npad_type{NpadType::None}; |
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 5b123bd3a..480b862fd 100644 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp | |||
| @@ -74,45 +74,53 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu | |||
| 74 | Common::Input::MotionStatus status{}; | 74 | Common::Input::MotionStatus status{}; |
| 75 | switch (callback.type) { | 75 | switch (callback.type) { |
| 76 | case Common::Input::InputType::Button: { | 76 | case Common::Input::InputType::Button: { |
| 77 | Common::Input::AnalogProperties properties{ | ||
| 78 | .deadzone = 0.0f, | ||
| 79 | .range = 1.0f, | ||
| 80 | .offset = 0.0f, | ||
| 81 | }; | ||
| 82 | status.delta_timestamp = 5000; | ||
| 83 | status.force_update = true; | ||
| 84 | status.accel.x = { | ||
| 85 | .value = 0.0f, | ||
| 86 | .raw_value = 0.0f, | ||
| 87 | .properties = properties, | ||
| 88 | }; | ||
| 89 | status.accel.y = { | ||
| 90 | .value = 0.0f, | ||
| 91 | .raw_value = 0.0f, | ||
| 92 | .properties = properties, | ||
| 93 | }; | ||
| 94 | status.accel.z = { | ||
| 95 | .value = 0.0f, | ||
| 96 | .raw_value = -1.0f, | ||
| 97 | .properties = properties, | ||
| 98 | }; | ||
| 99 | status.gyro.x = { | ||
| 100 | .value = 0.0f, | ||
| 101 | .raw_value = 0.0f, | ||
| 102 | .properties = properties, | ||
| 103 | }; | ||
| 104 | status.gyro.y = { | ||
| 105 | .value = 0.0f, | ||
| 106 | .raw_value = 0.0f, | ||
| 107 | .properties = properties, | ||
| 108 | }; | ||
| 109 | status.gyro.z = { | ||
| 110 | .value = 0.0f, | ||
| 111 | .raw_value = 0.0f, | ||
| 112 | .properties = properties, | ||
| 113 | }; | ||
| 77 | if (TransformToButton(callback).value) { | 114 | if (TransformToButton(callback).value) { |
| 78 | std::random_device device; | 115 | std::random_device device; |
| 79 | std::mt19937 gen(device()); | 116 | std::mt19937 gen(device()); |
| 80 | std::uniform_int_distribution<s16> distribution(-1000, 1000); | 117 | std::uniform_int_distribution<s16> distribution(-1000, 1000); |
| 81 | Common::Input::AnalogProperties properties{ | 118 | status.accel.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 82 | .deadzone = 0.0, | 119 | status.accel.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 83 | .range = 1.0f, | 120 | status.accel.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 84 | .offset = 0.0, | 121 | status.gyro.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 85 | }; | 122 | status.gyro.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 86 | status.accel.x = { | 123 | status.gyro.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f; |
| 87 | .value = 0, | ||
| 88 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 89 | .properties = properties, | ||
| 90 | }; | ||
| 91 | status.accel.y = { | ||
| 92 | .value = 0, | ||
| 93 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 94 | .properties = properties, | ||
| 95 | }; | ||
| 96 | status.accel.z = { | ||
| 97 | .value = 0, | ||
| 98 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 99 | .properties = properties, | ||
| 100 | }; | ||
| 101 | status.gyro.x = { | ||
| 102 | .value = 0, | ||
| 103 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 104 | .properties = properties, | ||
| 105 | }; | ||
| 106 | status.gyro.y = { | ||
| 107 | .value = 0, | ||
| 108 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 109 | .properties = properties, | ||
| 110 | }; | ||
| 111 | status.gyro.z = { | ||
| 112 | .value = 0, | ||
| 113 | .raw_value = static_cast<f32>(distribution(gen)) * 0.001f, | ||
| 114 | .properties = properties, | ||
| 115 | }; | ||
| 116 | } | 124 | } |
| 117 | break; | 125 | break; |
| 118 | } | 126 | } |
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h index 3deef5ac3..5b5b420bb 100644 --- a/src/core/hid/motion_input.h +++ b/src/core/hid/motion_input.h | |||
| @@ -56,15 +56,31 @@ private: | |||
| 56 | Common::Vec3f integral_error; | 56 | Common::Vec3f integral_error; |
| 57 | Common::Vec3f derivative_error; | 57 | Common::Vec3f derivative_error; |
| 58 | 58 | ||
| 59 | // Quaternion containing the device orientation | ||
| 59 | Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f}; | 60 | Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f}; |
| 61 | |||
| 62 | // Number of full rotations in each axis | ||
| 60 | Common::Vec3f rotations; | 63 | Common::Vec3f rotations; |
| 64 | |||
| 65 | // Acceleration vector measurement in G force | ||
| 61 | Common::Vec3f accel; | 66 | Common::Vec3f accel; |
| 67 | |||
| 68 | // Gyroscope vector measurement in radians/s. | ||
| 62 | Common::Vec3f gyro; | 69 | Common::Vec3f gyro; |
| 70 | |||
| 71 | // Vector to be substracted from gyro measurements | ||
| 63 | Common::Vec3f gyro_drift; | 72 | Common::Vec3f gyro_drift; |
| 64 | 73 | ||
| 74 | // Minimum gyro amplitude to detect if the device is moving | ||
| 65 | f32 gyro_threshold = 0.0f; | 75 | f32 gyro_threshold = 0.0f; |
| 76 | |||
| 77 | // Number of invalid sequential data | ||
| 66 | u32 reset_counter = 0; | 78 | u32 reset_counter = 0; |
| 79 | |||
| 80 | // If the provided data is invalid the device will be autocalibrated | ||
| 67 | bool reset_enabled = true; | 81 | bool reset_enabled = true; |
| 82 | |||
| 83 | // Use accelerometer values to calculate position | ||
| 68 | bool only_accelerometer = true; | 84 | bool only_accelerometer = true; |
| 69 | }; | 85 | }; |
| 70 | 86 | ||
diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 1d5948f79..77fcd655e 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp | |||
| @@ -36,6 +36,8 @@ public: | |||
| 36 | left->SetCallback(button_left_callback); | 36 | left->SetCallback(button_left_callback); |
| 37 | right->SetCallback(button_right_callback); | 37 | right->SetCallback(button_right_callback); |
| 38 | modifier->SetCallback(button_modifier_callback); | 38 | modifier->SetCallback(button_modifier_callback); |
| 39 | last_x_axis_value = 0.0f; | ||
| 40 | last_y_axis_value = 0.0f; | ||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | bool IsAngleGreater(float old_angle, float new_angle) const { | 43 | bool IsAngleGreater(float old_angle, float new_angle) const { |
| @@ -199,6 +201,8 @@ public: | |||
| 199 | .type = Common::Input::InputType::Stick, | 201 | .type = Common::Input::InputType::Stick, |
| 200 | .stick_status = GetStatus(), | 202 | .stick_status = GetStatus(), |
| 201 | }; | 203 | }; |
| 204 | last_x_axis_value = status.stick_status.x.raw_value; | ||
| 205 | last_y_axis_value = status.stick_status.y.raw_value; | ||
| 202 | TriggerOnChange(status); | 206 | TriggerOnChange(status); |
| 203 | } | 207 | } |
| 204 | 208 | ||
| @@ -215,6 +219,12 @@ public: | |||
| 215 | .type = Common::Input::InputType::Stick, | 219 | .type = Common::Input::InputType::Stick, |
| 216 | .stick_status = GetStatus(), | 220 | .stick_status = GetStatus(), |
| 217 | }; | 221 | }; |
| 222 | if (last_x_axis_value == status.stick_status.x.raw_value && | ||
| 223 | last_y_axis_value == status.stick_status.y.raw_value) { | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | last_x_axis_value = status.stick_status.x.raw_value; | ||
| 227 | last_y_axis_value = status.stick_status.y.raw_value; | ||
| 218 | TriggerOnChange(status); | 228 | TriggerOnChange(status); |
| 219 | } | 229 | } |
| 220 | 230 | ||
| @@ -265,6 +275,8 @@ private: | |||
| 265 | bool left_status; | 275 | bool left_status; |
| 266 | bool right_status; | 276 | bool right_status; |
| 267 | bool modifier_status; | 277 | bool modifier_status; |
| 278 | float last_x_axis_value; | ||
| 279 | float last_y_axis_value; | ||
| 268 | const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; | 280 | const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; |
| 269 | std::chrono::time_point<std::chrono::steady_clock> last_update; | 281 | std::chrono::time_point<std::chrono::steady_clock> last_update; |
| 270 | }; | 282 | }; |
diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 024343715..35d60bc90 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp | |||
| @@ -16,10 +16,15 @@ public: | |||
| 16 | : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { | 16 | : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) { |
| 17 | Common::Input::InputCallback button_up_callback{ | 17 | Common::Input::InputCallback button_up_callback{ |
| 18 | [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; | 18 | [this](Common::Input::CallbackStatus callback_) { UpdateButtonStatus(callback_); }}; |
| 19 | last_button_value = false; | ||
| 19 | button->SetCallback(button_up_callback); | 20 | button->SetCallback(button_up_callback); |
| 20 | button->ForceUpdate(); | 21 | button->ForceUpdate(); |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 24 | void ForceUpdate() override { | ||
| 25 | button->ForceUpdate(); | ||
| 26 | } | ||
| 27 | |||
| 23 | Common::Input::TouchStatus GetStatus(bool pressed) const { | 28 | Common::Input::TouchStatus GetStatus(bool pressed) const { |
| 24 | const Common::Input::ButtonStatus button_status{ | 29 | const Common::Input::ButtonStatus button_status{ |
| 25 | .value = pressed, | 30 | .value = pressed, |
| @@ -47,11 +52,15 @@ public: | |||
| 47 | .type = Common::Input::InputType::Touch, | 52 | .type = Common::Input::InputType::Touch, |
| 48 | .touch_status = GetStatus(button_callback.button_status.value), | 53 | .touch_status = GetStatus(button_callback.button_status.value), |
| 49 | }; | 54 | }; |
| 50 | TriggerOnChange(status); | 55 | if (last_button_value != button_callback.button_status.value) { |
| 56 | last_button_value = button_callback.button_status.value; | ||
| 57 | TriggerOnChange(status); | ||
| 58 | } | ||
| 51 | } | 59 | } |
| 52 | 60 | ||
| 53 | private: | 61 | private: |
| 54 | Button button; | 62 | Button button; |
| 63 | bool last_button_value; | ||
| 55 | const int touch_id; | 64 | const int touch_id; |
| 56 | const float x; | 65 | const float x; |
| 57 | const float y; | 66 | const float y; |