aboutsummaryrefslogtreecommitdiff
path: root/src/core/hid
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hid')
-rw-r--r--src/core/hid/emulated_console.cpp3
-rw-r--r--src/core/hid/emulated_console.h2
-rw-r--r--src/core/hid/emulated_controller.cpp65
-rw-r--r--src/core/hid/emulated_controller.h16
-rw-r--r--src/core/hid/hid_types.h7
-rw-r--r--src/core/hid/motion_input.cpp12
-rw-r--r--src/core/hid/motion_input.h5
7 files changed, 80 insertions, 30 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index 685ec080c..08f8af551 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -161,7 +161,10 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
motion.rotation = emulated.GetGyroscope();
motion.orientation = emulated.GetOrientation();
motion.quaternion = emulated.GetQuaternion();
+ motion.gyro_bias = emulated.GetGyroBias();
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
+ // Find what is this value
+ motion.verticalization_error = 0.0f;
TriggerOnChange(ConsoleTriggerType::Motion);
}
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
index 3afd284d5..707419102 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/core/hid/emulated_console.h
@@ -50,6 +50,8 @@ struct ConsoleMotion {
Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{};
Common::Quaternion<f32> quaternion{};
+ Common::Vec3f gyro_bias{};
+ f32 verticalization_error{};
bool is_at_rest{};
};
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 93372445b..71fc05807 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -843,23 +843,18 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
}
bool EmulatedController::TestVibration(std::size_t device_index) {
- if (device_index >= output_devices.size()) {
- return false;
- }
- if (!output_devices[device_index]) {
- return false;
- }
-
- // Send a slight vibration to test for rumble support
- constexpr Common::Input::VibrationStatus status = {
+ static constexpr VibrationValue test_vibration = {
.low_amplitude = 0.001f,
.low_frequency = 160.0f,
.high_amplitude = 0.001f,
.high_frequency = 320.0f,
- .type = Common::Input::VibrationAmplificationType::Linear,
};
- return output_devices[device_index]->SetVibration(status) ==
- Common::Input::VibrationError::None;
+
+ // Send a slight vibration to test for rumble support
+ SetVibration(device_index, test_vibration);
+
+ // Stop any vibration and return the result
+ return SetVibration(device_index, DEFAULT_VIBRATION_VALUE);
}
void EmulatedController::SetLedPattern() {
@@ -884,15 +879,42 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles)
if (!is_connected) {
return;
}
- if (!IsControllerSupported()) {
- LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller",
- npad_type);
- Disconnect();
+ if (IsControllerSupported()) {
+ return;
}
+
+ Disconnect();
+
+ // Fallback fullkey controllers to Pro controllers
+ if (IsControllerFullkey() && supported_style_tag.fullkey) {
+ LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type);
+ SetNpadStyleIndex(NpadStyleIndex::ProController);
+ Connect();
+ return;
+ }
+
+ LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller",
+ npad_type);
}
-bool EmulatedController::IsControllerSupported() const {
- switch (npad_type) {
+bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
+ const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
+ switch (type) {
+ case NpadStyleIndex::ProController:
+ case NpadStyleIndex::GameCube:
+ case NpadStyleIndex::NES:
+ case NpadStyleIndex::SNES:
+ case NpadStyleIndex::N64:
+ case NpadStyleIndex::SegaGenesis:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
+ const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
+ switch (type) {
case NpadStyleIndex::ProController:
return supported_style_tag.fullkey;
case NpadStyleIndex::Handheld:
@@ -920,9 +942,10 @@ bool EmulatedController::IsControllerSupported() const {
}
}
-void EmulatedController::Connect() {
- if (!IsControllerSupported()) {
- LOG_ERROR(Service_HID, "Controller type {} is not supported", npad_type);
+void EmulatedController::Connect(bool use_temporary_value) {
+ if (!IsControllerSupported(use_temporary_value)) {
+ const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
+ LOG_ERROR(Service_HID, "Controller type {} is not supported", type);
return;
}
{
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index e42aafebc..c0994ab4d 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -167,8 +167,11 @@ public:
*/
void SetSupportedNpadStyleTag(NpadStyleTag supported_styles);
- /// Sets the connected status to true
- void Connect();
+ /**
+ * Sets the connected status to true
+ * @param use_temporary_value If true tmp_npad_type will be used
+ */
+ void Connect(bool use_temporary_value = false);
/// Sets the connected status to false
void Disconnect();
@@ -318,10 +321,17 @@ private:
void LoadTASParams();
/**
+ * @param use_temporary_value If true tmp_npad_type will be used
+ * @return true if the controller style is fullkey
+ */
+ bool IsControllerFullkey(bool use_temporary_value = false) const;
+
+ /**
* Checks the current controller type against the supported_style_tag
+ * @param use_temporary_value If true tmp_npad_type will be used
* @return true if the controller is supported
*/
- bool IsControllerSupported() const;
+ bool IsControllerSupported(bool use_temporary_value = false) const;
/**
* Updates the button status of the controller
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 7c12f01fc..4eca68533 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -496,6 +496,13 @@ struct VibrationValue {
};
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
+constexpr VibrationValue DEFAULT_VIBRATION_VALUE{
+ .low_amplitude = 0.0f,
+ .low_frequency = 160.0f,
+ .high_amplitude = 0.0f,
+ .high_frequency = 320.0f,
+};
+
// This is nn::hid::VibrationDeviceInfo
struct VibrationDeviceInfo {
VibrationDeviceType type{};
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp
index c25fea966..a23f192d7 100644
--- a/src/core/hid/motion_input.cpp
+++ b/src/core/hid/motion_input.cpp
@@ -23,11 +23,11 @@ void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
}
void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
- gyro = gyroscope - gyro_drift;
+ gyro = gyroscope - gyro_bias;
// Auto adjust drift to minimize drift
if (!IsMoving(0.1f)) {
- gyro_drift = (gyro_drift * 0.9999f) + (gyroscope * 0.0001f);
+ gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
if (gyro.Length2() < gyro_threshold) {
@@ -41,8 +41,8 @@ void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) {
quat = quaternion;
}
-void MotionInput::SetGyroDrift(const Common::Vec3f& drift) {
- gyro_drift = drift;
+void MotionInput::SetGyroBias(const Common::Vec3f& bias) {
+ gyro_bias = bias;
}
void MotionInput::SetGyroThreshold(f32 threshold) {
@@ -192,6 +192,10 @@ Common::Vec3f MotionInput::GetGyroscope() const {
return gyro;
}
+Common::Vec3f MotionInput::GetGyroBias() const {
+ return gyro_bias;
+}
+
Common::Quaternion<f32> MotionInput::GetQuaternion() const {
return quat;
}
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h
index 5b5b420bb..bca4520fa 100644
--- a/src/core/hid/motion_input.h
+++ b/src/core/hid/motion_input.h
@@ -24,7 +24,7 @@ public:
void SetAcceleration(const Common::Vec3f& acceleration);
void SetGyroscope(const Common::Vec3f& gyroscope);
void SetQuaternion(const Common::Quaternion<f32>& quaternion);
- void SetGyroDrift(const Common::Vec3f& drift);
+ void SetGyroBias(const Common::Vec3f& bias);
void SetGyroThreshold(f32 threshold);
void EnableReset(bool reset);
@@ -36,6 +36,7 @@ public:
[[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
[[nodiscard]] Common::Vec3f GetAcceleration() const;
[[nodiscard]] Common::Vec3f GetGyroscope() const;
+ [[nodiscard]] Common::Vec3f GetGyroBias() const;
[[nodiscard]] Common::Vec3f GetRotations() const;
[[nodiscard]] Common::Quaternion<f32> GetQuaternion() const;
@@ -69,7 +70,7 @@ private:
Common::Vec3f gyro;
// Vector to be substracted from gyro measurements
- Common::Vec3f gyro_drift;
+ Common::Vec3f gyro_bias;
// Minimum gyro amplitude to detect if the device is moving
f32 gyro_threshold = 0.0f;