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.cpp35
-rw-r--r--src/core/hid/emulated_controller.h8
-rw-r--r--src/core/hid/input_converter.cpp2
-rw-r--r--src/core/hid/motion_input.cpp21
-rw-r--r--src/core/hid/motion_input.h11
5 files changed, 57 insertions, 20 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index ecab85893..366880711 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -688,6 +688,12 @@ void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage
ReloadInput();
}
+void EmulatedController::StartMotionCalibration() {
+ for (ControllerMotionInfo& motion : controller.motion_values) {
+ motion.emulated.Calibrate();
+ }
+}
+
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
Common::UUID uuid) {
if (index >= controller.button_values.size()) {
@@ -979,7 +985,6 @@ 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;
auto& motion = controller.motion_state[index];
motion.accel = emulated.GetAcceleration();
@@ -1618,19 +1623,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;
}
@@ -1696,8 +1688,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 6e01f4e12..88fad2f56 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -290,6 +290,9 @@ public:
*/
void SetMotionParam(std::size_t index, Common::ParamPackage param);
+ /// Auto calibrates the current motion devices
+ void StartMotionCalibration();
+
/// Returns the latest button status from the controller with parameters
ButtonValues GetButtonsValues() const;
@@ -415,8 +418,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
@@ -528,7 +531,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 53b00b1f9..4ccb1c596 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -86,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,
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp
index b60478dbb..f56f2ae1d 100644
--- a/src/core/hid/motion_input.cpp
+++ b/src/core/hid/motion_input.cpp
@@ -37,11 +37,17 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
- // Auto adjust drift to minimize drift
+ // Auto adjust gyro_bias to minimize drift
if (!IsMoving(IsAtRestRelaxed)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
+ // Adjust drift when calibration mode is enabled
+ if (calibration_mode) {
+ gyro_bias = (gyro_bias * 0.99f) + (gyroscope * 0.01f);
+ StopCalibration();
+ }
+
if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
gyro = {};
} else {
@@ -107,6 +113,19 @@ void MotionInput::UpdateRotation(u64 elapsed_time) {
rotations += gyro * sample_period;
}
+void MotionInput::Calibrate() {
+ calibration_mode = true;
+ calibration_counter = 0;
+}
+
+void MotionInput::StopCalibration() {
+ if (calibration_counter++ > CalibrationSamples) {
+ calibration_mode = false;
+ ResetQuaternion();
+ ResetRotations();
+ }
+}
+
// Based on Madgwick's implementation of Mayhony's AHRS algorithm.
// https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MahonyAHRS.cs
void MotionInput::UpdateOrientation(u64 elapsed_time) {
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h
index 482719359..11678983d 100644
--- a/src/core/hid/motion_input.h
+++ b/src/core/hid/motion_input.h
@@ -23,6 +23,8 @@ public:
static constexpr float GyroMaxValue = 5.0f;
static constexpr float AccelMaxValue = 7.0f;
+ static constexpr std::size_t CalibrationSamples = 300;
+
explicit MotionInput();
MotionInput(const MotionInput&) = default;
@@ -49,6 +51,8 @@ public:
void UpdateRotation(u64 elapsed_time);
void UpdateOrientation(u64 elapsed_time);
+ void Calibrate();
+
[[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
[[nodiscard]] Common::Vec3f GetAcceleration() const;
[[nodiscard]] Common::Vec3f GetGyroscope() const;
@@ -61,6 +65,7 @@ public:
[[nodiscard]] bool IsCalibrated(f32 sensitivity) const;
private:
+ void StopCalibration();
void ResetOrientation();
void SetOrientationFromAccelerometer();
@@ -103,6 +108,12 @@ private:
// Use accelerometer values to calculate position
bool only_accelerometer = true;
+
+ // When enabled it will aggressively adjust for gyro drift
+ bool calibration_mode = false;
+
+ // Used to auto disable calibration mode
+ std::size_t calibration_counter = 0;
};
} // namespace Core::HID