summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar german772021-11-01 19:49:14 -0600
committerGravatar Narr the Reg2021-11-24 20:30:27 -0600
commit136eb9c4c2b2425c2dd45a79cf444dee7170714d (patch)
tree74a055a08126fdd33b2071baa08125177847db6e
parentsecond commit lion review (diff)
downloadyuzu-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.h5
-rw-r--r--src/core/hid/emulated_controller.cpp11
-rw-r--r--src/core/hid/emulated_controller.h1
-rw-r--r--src/core/hid/input_converter.cpp78
-rw-r--r--src/core/hid/motion_input.h16
-rw-r--r--src/input_common/helpers/stick_from_buttons.cpp12
-rw-r--r--src/input_common/helpers/touch_from_buttons.cpp11
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
112struct MotionStatus { 112struct 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
118struct TouchStatus { 123struct 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
964MotionState EmulatedController::GetMotions() const { 965MotionState 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
53private: 61private:
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;