mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	core: hid: Use gyro thresholds modes set by the game
This commit is contained in:
		
							parent
							
								
									c27006e99d
								
							
						
					
					
						commit
						5e9fa5def5
					
				| @ -957,7 +957,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||||||
|         raw_status.gyro.y.value, |         raw_status.gyro.y.value, | ||||||
|         raw_status.gyro.z.value, |         raw_status.gyro.z.value, | ||||||
|     }); |     }); | ||||||
|     emulated.SetGyroThreshold(raw_status.gyro.x.properties.threshold); |     emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold); | ||||||
|     emulated.UpdateRotation(raw_status.delta_timestamp); |     emulated.UpdateRotation(raw_status.delta_timestamp); | ||||||
|     emulated.UpdateOrientation(raw_status.delta_timestamp); |     emulated.UpdateOrientation(raw_status.delta_timestamp); | ||||||
|     force_update_motion = raw_status.force_update; |     force_update_motion = raw_status.force_update; | ||||||
| @ -1284,6 +1284,26 @@ void EmulatedController::SetLedPattern() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) { | ||||||
|  |     for (auto& motion : controller.motion_values) { | ||||||
|  |         switch (mode) { | ||||||
|  |         case GyroscopeZeroDriftMode::Loose: | ||||||
|  |             motion_sensitivity = motion.emulated.IsAtRestLoose; | ||||||
|  |             motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose); | ||||||
|  |             break; | ||||||
|  |         case GyroscopeZeroDriftMode::Tight: | ||||||
|  |             motion_sensitivity = motion.emulated.IsAtRestThight; | ||||||
|  |             motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight); | ||||||
|  |             break; | ||||||
|  |         case GyroscopeZeroDriftMode::Standard: | ||||||
|  |         default: | ||||||
|  |             motion_sensitivity = motion.emulated.IsAtRestStandard; | ||||||
|  |             motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) { | void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) { | ||||||
|     supported_style_tag = supported_styles; |     supported_style_tag = supported_styles; | ||||||
|     if (!is_connected) { |     if (!is_connected) { | ||||||
|  | |||||||
| @ -398,6 +398,9 @@ public: | |||||||
|     /// Asks the output device to change the player led pattern
 |     /// Asks the output device to change the player led pattern
 | ||||||
|     void SetLedPattern(); |     void SetLedPattern(); | ||||||
| 
 | 
 | ||||||
|  |     /// Changes sensitivity of the motion sensor
 | ||||||
|  |     void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Adds a callback to the list of events |      * Adds a callback to the list of events | ||||||
|      * @param update_callback A ConsoleUpdateCallback that will be triggered |      * @param update_callback A ConsoleUpdateCallback that will be triggered | ||||||
| @ -523,7 +526,7 @@ private: | |||||||
|     bool is_connected{false}; |     bool is_connected{false}; | ||||||
|     bool is_configuring{false}; |     bool is_configuring{false}; | ||||||
|     bool system_buttons_enabled{true}; |     bool system_buttons_enabled{true}; | ||||||
|     f32 motion_sensitivity{0.01f}; |     f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; | ||||||
|     bool force_update_motion{false}; |     bool force_update_motion{false}; | ||||||
|     u32 turbo_button_state{0}; |     u32 turbo_button_state{0}; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -282,6 +282,13 @@ enum class VibrationGcErmCommand : u64 { | |||||||
|     StopHard = 2, |     StopHard = 2, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // This is nn::hid::GyroscopeZeroDriftMode
 | ||||||
|  | enum class GyroscopeZeroDriftMode : u32 { | ||||||
|  |     Loose = 0, | ||||||
|  |     Standard = 1, | ||||||
|  |     Tight = 2, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| // This is nn::hid::NpadStyleTag
 | // This is nn::hid::NpadStyleTag
 | ||||||
| struct NpadStyleTag { | struct NpadStyleTag { | ||||||
|     union { |     union { | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ namespace Core::HID { | |||||||
| MotionInput::MotionInput() { | MotionInput::MotionInput() { | ||||||
|     // Initialize PID constants with default values
 |     // Initialize PID constants with default values
 | ||||||
|     SetPID(0.3f, 0.005f, 0.0f); |     SetPID(0.3f, 0.005f, 0.0f); | ||||||
|     SetGyroThreshold(0.007f); |     SetGyroThreshold(ThresholdStandard); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) { | void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) { | ||||||
| @ -26,11 +26,11 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) { | |||||||
|     gyro = gyroscope - gyro_bias; |     gyro = gyroscope - gyro_bias; | ||||||
| 
 | 
 | ||||||
|     // Auto adjust drift to minimize drift
 |     // Auto adjust drift to minimize drift
 | ||||||
|     if (!IsMoving(0.1f)) { |     if (!IsMoving(IsAtRestRelaxed)) { | ||||||
|         gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); |         gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (gyro.Length() < gyro_threshold) { |     if (gyro.Length() < gyro_threshold * user_gyro_threshold) { | ||||||
|         gyro = {}; |         gyro = {}; | ||||||
|     } else { |     } else { | ||||||
|         only_accelerometer = false; |         only_accelerometer = false; | ||||||
| @ -49,6 +49,10 @@ void MotionInput::SetGyroThreshold(f32 threshold) { | |||||||
|     gyro_threshold = threshold; |     gyro_threshold = threshold; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void MotionInput::SetUserGyroThreshold(f32 threshold) { | ||||||
|  |     user_gyro_threshold = threshold / ThresholdStandard; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void MotionInput::EnableReset(bool reset) { | void MotionInput::EnableReset(bool reset) { | ||||||
|     reset_enabled = reset; |     reset_enabled = reset; | ||||||
| } | } | ||||||
| @ -208,7 +212,7 @@ void MotionInput::ResetOrientation() { | |||||||
|     if (!reset_enabled || only_accelerometer) { |     if (!reset_enabled || only_accelerometer) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     if (!IsMoving(0.5f) && accel.z <= -0.9f) { |     if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) { | ||||||
|         ++reset_counter; |         ++reset_counter; | ||||||
|         if (reset_counter > 900) { |         if (reset_counter > 900) { | ||||||
|             quat.w = 0; |             quat.w = 0; | ||||||
|  | |||||||
| @ -11,6 +11,15 @@ namespace Core::HID { | |||||||
| 
 | 
 | ||||||
| class MotionInput { | class MotionInput { | ||||||
| public: | public: | ||||||
|  |     static constexpr float ThresholdLoose = 0.01f; | ||||||
|  |     static constexpr float ThresholdStandard = 0.007f; | ||||||
|  |     static constexpr float ThresholdThight = 0.002f; | ||||||
|  | 
 | ||||||
|  |     static constexpr float IsAtRestRelaxed = 0.05f; | ||||||
|  |     static constexpr float IsAtRestLoose = 0.02f; | ||||||
|  |     static constexpr float IsAtRestStandard = 0.01f; | ||||||
|  |     static constexpr float IsAtRestThight = 0.005f; | ||||||
|  | 
 | ||||||
|     explicit MotionInput(); |     explicit MotionInput(); | ||||||
| 
 | 
 | ||||||
|     MotionInput(const MotionInput&) = default; |     MotionInput(const MotionInput&) = default; | ||||||
| @ -26,6 +35,9 @@ public: | |||||||
|     void SetGyroBias(const Common::Vec3f& bias); |     void SetGyroBias(const Common::Vec3f& bias); | ||||||
|     void SetGyroThreshold(f32 threshold); |     void SetGyroThreshold(f32 threshold); | ||||||
| 
 | 
 | ||||||
|  |     /// Applies a modifier on top of the normal gyro threshold
 | ||||||
|  |     void SetUserGyroThreshold(f32 threshold); | ||||||
|  | 
 | ||||||
|     void EnableReset(bool reset); |     void EnableReset(bool reset); | ||||||
|     void ResetRotations(); |     void ResetRotations(); | ||||||
| 
 | 
 | ||||||
| @ -74,6 +86,9 @@ private: | |||||||
|     // Minimum gyro amplitude to detect if the device is moving
 |     // Minimum gyro amplitude to detect if the device is moving
 | ||||||
|     f32 gyro_threshold = 0.0f; |     f32 gyro_threshold = 0.0f; | ||||||
| 
 | 
 | ||||||
|  |     // Multiplies gyro_threshold by this value
 | ||||||
|  |     f32 user_gyro_threshold = 0.0f; | ||||||
|  | 
 | ||||||
|     // Number of invalid sequential data
 |     // Number of invalid sequential data
 | ||||||
|     u32 reset_counter = 0; |     u32 reset_counter = 0; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1132,7 +1132,8 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { | |||||||
|     return ResultSuccess; |     return ResultSuccess; | ||||||
| } | } | ||||||
| Result Controller_NPad::SetGyroscopeZeroDriftMode( | Result Controller_NPad::SetGyroscopeZeroDriftMode( | ||||||
|     const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) { |     const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||||||
|  |     Core::HID::GyroscopeZeroDriftMode drift_mode) { | ||||||
|     const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |     const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||||||
|     if (is_valid.IsError()) { |     if (is_valid.IsError()) { | ||||||
|         LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |         LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||||||
| @ -1140,14 +1141,16 @@ Result Controller_NPad::SetGyroscopeZeroDriftMode( | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto& sixaxis = GetSixaxisState(sixaxis_handle); |     auto& sixaxis = GetSixaxisState(sixaxis_handle); | ||||||
|  |     auto& controller = GetControllerFromHandle(sixaxis_handle); | ||||||
|     sixaxis.gyroscope_zero_drift_mode = drift_mode; |     sixaxis.gyroscope_zero_drift_mode = drift_mode; | ||||||
|  |     controller.device->SetGyroscopeZeroDriftMode(drift_mode); | ||||||
| 
 | 
 | ||||||
|     return ResultSuccess; |     return ResultSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Result Controller_NPad::GetGyroscopeZeroDriftMode( | Result Controller_NPad::GetGyroscopeZeroDriftMode( | ||||||
|     const Core::HID::SixAxisSensorHandle& sixaxis_handle, |     const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||||||
|     GyroscopeZeroDriftMode& drift_mode) const { |     Core::HID::GyroscopeZeroDriftMode& drift_mode) const { | ||||||
|     const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); |     const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); | ||||||
|     if (is_valid.IsError()) { |     if (is_valid.IsError()) { | ||||||
|         LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); |         LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); | ||||||
|  | |||||||
| @ -52,13 +52,6 @@ public: | |||||||
|     // When the controller is requesting a motion update for the shared memory
 |     // When the controller is requesting a motion update for the shared memory
 | ||||||
|     void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override; |     void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||||
| 
 | 
 | ||||||
|     // This is nn::hid::GyroscopeZeroDriftMode
 |  | ||||||
|     enum class GyroscopeZeroDriftMode : u32 { |  | ||||||
|         Loose = 0, |  | ||||||
|         Standard = 1, |  | ||||||
|         Tight = 2, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     // This is nn::hid::NpadJoyHoldType
 |     // This is nn::hid::NpadJoyHoldType
 | ||||||
|     enum class NpadJoyHoldType : u64 { |     enum class NpadJoyHoldType : u64 { | ||||||
|         Vertical = 0, |         Vertical = 0, | ||||||
| @ -146,9 +139,9 @@ public: | |||||||
|     Result DisconnectNpad(Core::HID::NpadIdType npad_id); |     Result DisconnectNpad(Core::HID::NpadIdType npad_id); | ||||||
| 
 | 
 | ||||||
|     Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |     Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||||||
|                                      GyroscopeZeroDriftMode drift_mode); |                                      Core::HID::GyroscopeZeroDriftMode drift_mode); | ||||||
|     Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |     Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||||||
|                                      GyroscopeZeroDriftMode& drift_mode) const; |                                      Core::HID::GyroscopeZeroDriftMode& drift_mode) const; | ||||||
|     Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, |     Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, | ||||||
|                                  bool& is_at_rest) const; |                                  bool& is_at_rest) const; | ||||||
|     Result IsFirmwareUpdateAvailableForSixAxisSensor( |     Result IsFirmwareUpdateAvailableForSixAxisSensor( | ||||||
| @ -489,7 +482,8 @@ private: | |||||||
|         Core::HID::SixAxisSensorFusionParameters fusion{}; |         Core::HID::SixAxisSensorFusionParameters fusion{}; | ||||||
|         Core::HID::SixAxisSensorCalibrationParameter calibration{}; |         Core::HID::SixAxisSensorCalibrationParameter calibration{}; | ||||||
|         Core::HID::SixAxisSensorIcInformation ic_information{}; |         Core::HID::SixAxisSensorIcInformation ic_information{}; | ||||||
|         GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; |         Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{ | ||||||
|  |             Core::HID::GyroscopeZeroDriftMode::Standard}; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     struct NpadControllerData { |     struct NpadControllerData { | ||||||
|  | |||||||
| @ -712,7 +712,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { | |||||||
| void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; |     const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()}; | ||||||
|     const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()}; |     const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()}; | ||||||
|     const auto applet_resource_user_id{rp.Pop<u64>()}; |     const auto applet_resource_user_id{rp.Pop<u64>()}; | ||||||
| 
 | 
 | ||||||
|     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||||||
| @ -739,7 +739,7 @@ void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | |||||||
| 
 | 
 | ||||||
|     const auto parameters{rp.PopRaw<Parameters>()}; |     const auto parameters{rp.PopRaw<Parameters>()}; | ||||||
| 
 | 
 | ||||||
|     auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard}; |     auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||||||
|     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||||||
|     const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); |     const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||||||
| 
 | 
 | ||||||
| @ -764,7 +764,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | |||||||
| 
 | 
 | ||||||
|     const auto parameters{rp.PopRaw<Parameters>()}; |     const auto parameters{rp.PopRaw<Parameters>()}; | ||||||
| 
 | 
 | ||||||
|     const auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard}; |     const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; | ||||||
|     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |     auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); | ||||||
|     const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); |     const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user