diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/input.h | 5 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 46 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/amiibo_crypto.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/amiibo_crypto.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_types.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_user.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_user.h | 8 | ||||
| -rw-r--r-- | src/input_common/drivers/gc_adapter.cpp | 6 | ||||
| -rw-r--r-- | src/input_common/drivers/gc_adapter.h | 4 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 64 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.h | 4 | ||||
| -rw-r--r-- | src/input_common/input_engine.h | 7 | ||||
| -rw-r--r-- | src/input_common/input_poller.cpp | 6 |
17 files changed, 119 insertions, 69 deletions
diff --git a/src/common/input.h b/src/common/input.h index b533f3844..cb30b7254 100644 --- a/src/common/input.h +++ b/src/common/input.h | |||
| @@ -100,7 +100,6 @@ enum class CameraError { | |||
| 100 | enum class VibrationAmplificationType { | 100 | enum class VibrationAmplificationType { |
| 101 | Linear, | 101 | Linear, |
| 102 | Exponential, | 102 | Exponential, |
| 103 | Test, | ||
| 104 | }; | 103 | }; |
| 105 | 104 | ||
| 106 | // Analog properties for calibration | 105 | // Analog properties for calibration |
| @@ -325,6 +324,10 @@ public: | |||
| 325 | return VibrationError::NotSupported; | 324 | return VibrationError::NotSupported; |
| 326 | } | 325 | } |
| 327 | 326 | ||
| 327 | virtual bool IsVibrationEnabled() { | ||
| 328 | return false; | ||
| 329 | } | ||
| 330 | |||
| 328 | virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { | 331 | virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { |
| 329 | return PollingError::NotSupported; | 332 | return PollingError::NotSupported; |
| 330 | } | 333 | } |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 57eff72fe..ec1364452 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -970,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v | |||
| 970 | Common::Input::VibrationError::None; | 970 | Common::Input::VibrationError::None; |
| 971 | } | 971 | } |
| 972 | 972 | ||
| 973 | bool EmulatedController::TestVibration(std::size_t device_index) { | 973 | bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { |
| 974 | if (device_index >= output_devices.size()) { | ||
| 975 | return false; | ||
| 976 | } | ||
| 977 | if (!output_devices[device_index]) { | ||
| 978 | return false; | ||
| 979 | } | ||
| 980 | |||
| 981 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 974 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 982 | const auto& player = Settings::values.players.GetValue()[player_index]; | 975 | const auto& player = Settings::values.players.GetValue()[player_index]; |
| 983 | 976 | ||
| @@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) { | |||
| 985 | return false; | 978 | return false; |
| 986 | } | 979 | } |
| 987 | 980 | ||
| 988 | const Common::Input::VibrationStatus test_vibration = { | 981 | if (device_index >= output_devices.size()) { |
| 989 | .low_amplitude = 0.001f, | 982 | return false; |
| 990 | .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, | 983 | } |
| 991 | .high_amplitude = 0.001f, | ||
| 992 | .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, | ||
| 993 | .type = Common::Input::VibrationAmplificationType::Test, | ||
| 994 | }; | ||
| 995 | |||
| 996 | const Common::Input::VibrationStatus zero_vibration = { | ||
| 997 | .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude, | ||
| 998 | .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, | ||
| 999 | .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude, | ||
| 1000 | .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency, | ||
| 1001 | .type = Common::Input::VibrationAmplificationType::Test, | ||
| 1002 | }; | ||
| 1003 | |||
| 1004 | // Send a slight vibration to test for rumble support | ||
| 1005 | output_devices[device_index]->SetVibration(test_vibration); | ||
| 1006 | 984 | ||
| 1007 | // Wait for about 15ms to ensure the controller is ready for the stop command | 985 | if (!output_devices[device_index]) { |
| 1008 | std::this_thread::sleep_for(std::chrono::milliseconds(15)); | 986 | return false; |
| 987 | } | ||
| 1009 | 988 | ||
| 1010 | // Stop any vibration and return the result | 989 | return output_devices[device_index]->IsVibrationEnabled(); |
| 1011 | return output_devices[device_index]->SetVibration(zero_vibration) == | ||
| 1012 | Common::Input::VibrationError::None; | ||
| 1013 | } | 990 | } |
| 1014 | 991 | ||
| 1015 | bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { | 992 | bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { |
| @@ -1048,6 +1025,7 @@ bool EmulatedController::HasNfc() const { | |||
| 1048 | case NpadStyleIndex::JoyconRight: | 1025 | case NpadStyleIndex::JoyconRight: |
| 1049 | case NpadStyleIndex::JoyconDual: | 1026 | case NpadStyleIndex::JoyconDual: |
| 1050 | case NpadStyleIndex::ProController: | 1027 | case NpadStyleIndex::ProController: |
| 1028 | case NpadStyleIndex::Handheld: | ||
| 1051 | break; | 1029 | break; |
| 1052 | default: | 1030 | default: |
| 1053 | return false; | 1031 | return false; |
| @@ -1234,12 +1212,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const { | |||
| 1234 | return is_connected; | 1212 | return is_connected; |
| 1235 | } | 1213 | } |
| 1236 | 1214 | ||
| 1237 | bool EmulatedController::IsVibrationEnabled() const { | ||
| 1238 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||
| 1239 | const auto& player = Settings::values.players.GetValue()[player_index]; | ||
| 1240 | return player.vibration_enabled; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | NpadIdType EmulatedController::GetNpadIdType() const { | 1215 | NpadIdType EmulatedController::GetNpadIdType() const { |
| 1244 | std::scoped_lock lock{mutex}; | 1216 | std::scoped_lock lock{mutex}; |
| 1245 | return npad_id_type; | 1217 | return npad_id_type; |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 319226bf8..d004ca56a 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -206,9 +206,6 @@ public: | |||
| 206 | */ | 206 | */ |
| 207 | bool IsConnected(bool get_temporary_value = false) const; | 207 | bool IsConnected(bool get_temporary_value = false) const; |
| 208 | 208 | ||
| 209 | /// Returns true if vibration is enabled | ||
| 210 | bool IsVibrationEnabled() const; | ||
| 211 | |||
| 212 | /// Removes all callbacks created from input devices | 209 | /// Removes all callbacks created from input devices |
| 213 | void UnloadInput(); | 210 | void UnloadInput(); |
| 214 | 211 | ||
| @@ -339,7 +336,7 @@ public: | |||
| 339 | * Sends a small vibration to the output device | 336 | * Sends a small vibration to the output device |
| 340 | * @return true if SetVibration was successfull | 337 | * @return true if SetVibration was successfull |
| 341 | */ | 338 | */ |
| 342 | bool TestVibration(std::size_t device_index); | 339 | bool IsVibrationEnabled(std::size_t device_index); |
| 343 | 340 | ||
| 344 | /** | 341 | /** |
| 345 | * Sets the desired data to be polled from a controller | 342 | * Sets the desired data to be polled from a controller |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 3b26e96de..2f871de31 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -868,7 +868,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, | |||
| 868 | return false; | 868 | return false; |
| 869 | } | 869 | } |
| 870 | 870 | ||
| 871 | if (!controller.device->IsVibrationEnabled()) { | 871 | if (!controller.device->IsVibrationEnabled(device_index)) { |
| 872 | if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f || | 872 | if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f || |
| 873 | controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) { | 873 | controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) { |
| 874 | // Send an empty vibration to stop any vibrations. | 874 | // Send an empty vibration to stop any vibrations. |
| @@ -1001,7 +1001,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa | |||
| 1001 | } | 1001 | } |
| 1002 | 1002 | ||
| 1003 | controller.vibration[device_index].device_mounted = | 1003 | controller.vibration[device_index].device_mounted = |
| 1004 | controller.device->TestVibration(device_index); | 1004 | controller.device->IsVibrationEnabled(device_index); |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| 1007 | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { | 1007 | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { |
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp index c32a6816b..167e29572 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.cpp +++ b/src/core/hle/service/nfp/amiibo_crypto.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <mbedtls/hmac_drbg.h> | 9 | #include <mbedtls/hmac_drbg.h> |
| 10 | 10 | ||
| 11 | #include "common/fs/file.h" | 11 | #include "common/fs/file.h" |
| 12 | #include "common/fs/fs.h" | ||
| 12 | #include "common/fs/path_util.h" | 13 | #include "common/fs/path_util.h" |
| 13 | #include "common/logging/log.h" | 14 | #include "common/logging/log.h" |
| 14 | #include "core/hle/service/mii/mii_manager.h" | 15 | #include "core/hle/service/mii/mii_manager.h" |
| @@ -279,7 +280,7 @@ bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) { | |||
| 279 | Common::FS::FileType::BinaryFile}; | 280 | Common::FS::FileType::BinaryFile}; |
| 280 | 281 | ||
| 281 | if (!keys_file.IsOpen()) { | 282 | if (!keys_file.IsOpen()) { |
| 282 | LOG_ERROR(Service_NFP, "No keys detected"); | 283 | LOG_ERROR(Service_NFP, "Failed to open key file"); |
| 283 | return false; | 284 | return false; |
| 284 | } | 285 | } |
| 285 | 286 | ||
| @@ -295,6 +296,11 @@ bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) { | |||
| 295 | return true; | 296 | return true; |
| 296 | } | 297 | } |
| 297 | 298 | ||
| 299 | bool IsKeyAvailable() { | ||
| 300 | const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); | ||
| 301 | return Common::FS::Exists(yuzu_keys_dir / "key_retail.bin"); | ||
| 302 | } | ||
| 303 | |||
| 298 | bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data) { | 304 | bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data) { |
| 299 | InternalKey locked_secret{}; | 305 | InternalKey locked_secret{}; |
| 300 | InternalKey unfixed_info{}; | 306 | InternalKey unfixed_info{}; |
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h index 0175ced91..1fa61174e 100644 --- a/src/core/hle/service/nfp/amiibo_crypto.h +++ b/src/core/hle/service/nfp/amiibo_crypto.h | |||
| @@ -91,6 +91,9 @@ void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& ou | |||
| 91 | /// Loads both amiibo keys from key_retail.bin | 91 | /// Loads both amiibo keys from key_retail.bin |
| 92 | bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info); | 92 | bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info); |
| 93 | 93 | ||
| 94 | /// Returns true if key_retail.bin exist | ||
| 95 | bool IsKeyAvailable(); | ||
| 96 | |||
| 94 | /// Decodes encripted amiibo data returns true if output is valid | 97 | /// Decodes encripted amiibo data returns true if output is valid |
| 95 | bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data); | 98 | bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data); |
| 96 | 99 | ||
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 76f8a267a..b19672560 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include "core/hle/ipc_helpers.h" | 17 | #include "core/hle/ipc_helpers.h" |
| 18 | #include "core/hle/kernel/k_event.h" | 18 | #include "core/hle/kernel/k_event.h" |
| 19 | #include "core/hle/service/mii/mii_manager.h" | 19 | #include "core/hle/service/mii/mii_manager.h" |
| 20 | #include "core/hle/service/mii/types.h" | ||
| 20 | #include "core/hle/service/nfp/amiibo_crypto.h" | 21 | #include "core/hle/service/nfp/amiibo_crypto.h" |
| 21 | #include "core/hle/service/nfp/nfp.h" | 22 | #include "core/hle/service/nfp/nfp.h" |
| 22 | #include "core/hle/service/nfp/nfp_device.h" | 23 | #include "core/hle/service/nfp/nfp_device.h" |
| @@ -233,6 +234,14 @@ Result NfpDevice::Mount(MountTarget mount_target_) { | |||
| 233 | return NotAnAmiibo; | 234 | return NotAnAmiibo; |
| 234 | } | 235 | } |
| 235 | 236 | ||
| 237 | // Mark amiibos as read only when keys are missing | ||
| 238 | if (!AmiiboCrypto::IsKeyAvailable()) { | ||
| 239 | LOG_ERROR(Service_NFP, "No keys detected"); | ||
| 240 | device_state = DeviceState::TagMounted; | ||
| 241 | mount_target = MountTarget::Rom; | ||
| 242 | return ResultSuccess; | ||
| 243 | } | ||
| 244 | |||
| 236 | if (!AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { | 245 | if (!AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { |
| 237 | LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state); | 246 | LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state); |
| 238 | return CorruptedData; | 247 | return CorruptedData; |
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index a5b72cf19..76d0e9ae4 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/common_funcs.h" | 9 | #include "common/common_funcs.h" |
| 10 | #include "core/hle/service/kernel_helpers.h" | 10 | #include "core/hle/service/kernel_helpers.h" |
| 11 | #include "core/hle/service/mii/types.h" | ||
| 12 | #include "core/hle/service/nfp/nfp_types.h" | 11 | #include "core/hle/service/nfp/nfp_types.h" |
| 13 | #include "core/hle/service/service.h" | 12 | #include "core/hle/service/service.h" |
| 14 | 13 | ||
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index c09f9ddb6..63d5917cb 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h | |||
| @@ -17,11 +17,6 @@ enum class ServiceType : u32 { | |||
| 17 | System, | 17 | System, |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | enum class State : u32 { | ||
| 21 | NonInitialized, | ||
| 22 | Initialized, | ||
| 23 | }; | ||
| 24 | |||
| 25 | enum class DeviceState : u32 { | 20 | enum class DeviceState : u32 { |
| 26 | Initialized, | 21 | Initialized, |
| 27 | SearchingForTag, | 22 | SearchingForTag, |
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index 4ed53b534..33e2ef518 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp | |||
| @@ -6,12 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hid/emulated_controller.h" | ||
| 10 | #include "core/hid/hid_core.h" | ||
| 11 | #include "core/hid/hid_types.h" | 9 | #include "core/hid/hid_types.h" |
| 12 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 13 | #include "core/hle/kernel/k_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| 14 | #include "core/hle/service/mii/mii_manager.h" | ||
| 15 | #include "core/hle/service/nfp/nfp_device.h" | 12 | #include "core/hle/service/nfp/nfp_device.h" |
| 16 | #include "core/hle/service/nfp/nfp_result.h" | 13 | #include "core/hle/service/nfp/nfp_result.h" |
| 17 | #include "core/hle/service/nfp/nfp_user.h" | 14 | #include "core/hle/service/nfp/nfp_user.h" |
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h index 68c60ae82..47aff3695 100644 --- a/src/core/hle/service/nfp/nfp_user.h +++ b/src/core/hle/service/nfp/nfp_user.h | |||
| @@ -4,8 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/kernel_helpers.h" | 6 | #include "core/hle/service/kernel_helpers.h" |
| 7 | #include "core/hle/service/nfp/nfp.h" | 7 | #include "core/hle/service/service.h" |
| 8 | #include "core/hle/service/nfp/nfp_types.h" | ||
| 9 | 8 | ||
| 10 | namespace Service::NFP { | 9 | namespace Service::NFP { |
| 11 | class NfpDevice; | 10 | class NfpDevice; |
| @@ -15,6 +14,11 @@ public: | |||
| 15 | explicit IUser(Core::System& system_); | 14 | explicit IUser(Core::System& system_); |
| 16 | 15 | ||
| 17 | private: | 16 | private: |
| 17 | enum class State : u32 { | ||
| 18 | NonInitialized, | ||
| 19 | Initialized, | ||
| 20 | }; | ||
| 21 | |||
| 18 | void Initialize(Kernel::HLERequestContext& ctx); | 22 | void Initialize(Kernel::HLERequestContext& ctx); |
| 19 | void Finalize(Kernel::HLERequestContext& ctx); | 23 | void Finalize(Kernel::HLERequestContext& ctx); |
| 20 | void ListDevices(Kernel::HLERequestContext& ctx); | 24 | void ListDevices(Kernel::HLERequestContext& ctx); |
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp index f4dd24e7d..826fa2109 100644 --- a/src/input_common/drivers/gc_adapter.cpp +++ b/src/input_common/drivers/gc_adapter.cpp | |||
| @@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) { | |||
| 324 | return true; | 324 | return true; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | Common::Input::VibrationError GCAdapter::SetRumble( | 327 | Common::Input::VibrationError GCAdapter::SetVibration( |
| 328 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { | 328 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { |
| 329 | const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; | 329 | const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; |
| 330 | const auto processed_amplitude = | 330 | const auto processed_amplitude = |
| @@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble( | |||
| 338 | return Common::Input::VibrationError::None; | 338 | return Common::Input::VibrationError::None; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | ||
| 342 | return rumble_enabled; | ||
| 343 | } | ||
| 344 | |||
| 341 | void GCAdapter::UpdateVibrations() { | 345 | void GCAdapter::UpdateVibrations() { |
| 342 | // Use 8 states to keep the switching between on/off fast enough for | 346 | // Use 8 states to keep the switching between on/off fast enough for |
| 343 | // a human to feel different vibration strenght | 347 | // a human to feel different vibration strenght |
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h index 8682da847..7f81767f7 100644 --- a/src/input_common/drivers/gc_adapter.h +++ b/src/input_common/drivers/gc_adapter.h | |||
| @@ -25,9 +25,11 @@ public: | |||
| 25 | explicit GCAdapter(std::string input_engine_); | 25 | explicit GCAdapter(std::string input_engine_); |
| 26 | ~GCAdapter() override; | 26 | ~GCAdapter() override; |
| 27 | 27 | ||
| 28 | Common::Input::VibrationError SetRumble( | 28 | Common::Input::VibrationError SetVibration( |
| 29 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | 29 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |
| 30 | 30 | ||
| 31 | bool IsVibrationEnabled(const PadIdentifier& identifier) override; | ||
| 32 | |||
| 31 | /// Used for automapping features | 33 | /// Used for automapping features |
| 32 | std::vector<Common::ParamPackage> GetInputDevices() const override; | 34 | std::vector<Common::ParamPackage> GetInputDevices() const override; |
| 33 | ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override; | 35 | ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override; |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index c175a8853..45ce588f0 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -114,6 +114,20 @@ public: | |||
| 114 | } | 114 | } |
| 115 | return false; | 115 | return false; |
| 116 | } | 116 | } |
| 117 | |||
| 118 | void EnableVibration(bool is_enabled) { | ||
| 119 | has_vibration = is_enabled; | ||
| 120 | is_vibration_tested = true; | ||
| 121 | } | ||
| 122 | |||
| 123 | bool HasVibration() const { | ||
| 124 | return has_vibration; | ||
| 125 | } | ||
| 126 | |||
| 127 | bool IsVibrationTested() const { | ||
| 128 | return is_vibration_tested; | ||
| 129 | } | ||
| 130 | |||
| 117 | /** | 131 | /** |
| 118 | * The Pad identifier of the joystick | 132 | * The Pad identifier of the joystick |
| 119 | */ | 133 | */ |
| @@ -236,6 +250,8 @@ private: | |||
| 236 | u64 last_motion_update{}; | 250 | u64 last_motion_update{}; |
| 237 | bool has_gyro{false}; | 251 | bool has_gyro{false}; |
| 238 | bool has_accel{false}; | 252 | bool has_accel{false}; |
| 253 | bool has_vibration{false}; | ||
| 254 | bool is_vibration_tested{false}; | ||
| 239 | BasicMotion motion; | 255 | BasicMotion motion; |
| 240 | }; | 256 | }; |
| 241 | 257 | ||
| @@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 517 | return devices; | 533 | return devices; |
| 518 | } | 534 | } |
| 519 | 535 | ||
| 520 | Common::Input::VibrationError SDLDriver::SetRumble( | 536 | Common::Input::VibrationError SDLDriver::SetVibration( |
| 521 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { | 537 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { |
| 522 | const auto joystick = | 538 | const auto joystick = |
| 523 | GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); | 539 | GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); |
| @@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||
| 546 | .type = Common::Input::VibrationAmplificationType::Exponential, | 562 | .type = Common::Input::VibrationAmplificationType::Exponential, |
| 547 | }; | 563 | }; |
| 548 | 564 | ||
| 549 | if (vibration.type == Common::Input::VibrationAmplificationType::Test) { | ||
| 550 | if (!joystick->RumblePlay(new_vibration)) { | ||
| 551 | return Common::Input::VibrationError::Unknown; | ||
| 552 | } | ||
| 553 | return Common::Input::VibrationError::None; | ||
| 554 | } | ||
| 555 | |||
| 556 | vibration_queue.Push(VibrationRequest{ | 565 | vibration_queue.Push(VibrationRequest{ |
| 557 | .identifier = identifier, | 566 | .identifier = identifier, |
| 558 | .vibration = new_vibration, | 567 | .vibration = new_vibration, |
| @@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||
| 561 | return Common::Input::VibrationError::None; | 570 | return Common::Input::VibrationError::None; |
| 562 | } | 571 | } |
| 563 | 572 | ||
| 573 | bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { | ||
| 574 | const auto joystick = | ||
| 575 | GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); | ||
| 576 | |||
| 577 | constexpr Common::Input::VibrationStatus test_vibration{ | ||
| 578 | .low_amplitude = 1, | ||
| 579 | .low_frequency = 160.0f, | ||
| 580 | .high_amplitude = 1, | ||
| 581 | .high_frequency = 320.0f, | ||
| 582 | .type = Common::Input::VibrationAmplificationType::Exponential, | ||
| 583 | }; | ||
| 584 | |||
| 585 | constexpr Common::Input::VibrationStatus zero_vibration{ | ||
| 586 | .low_amplitude = 0, | ||
| 587 | .low_frequency = 160.0f, | ||
| 588 | .high_amplitude = 0, | ||
| 589 | .high_frequency = 320.0f, | ||
| 590 | .type = Common::Input::VibrationAmplificationType::Exponential, | ||
| 591 | }; | ||
| 592 | |||
| 593 | if (joystick->IsVibrationTested()) { | ||
| 594 | return joystick->HasVibration(); | ||
| 595 | } | ||
| 596 | |||
| 597 | // First vibration might fail | ||
| 598 | joystick->RumblePlay(test_vibration); | ||
| 599 | |||
| 600 | // Wait for about 15ms to ensure the controller is ready for the stop command | ||
| 601 | std::this_thread::sleep_for(std::chrono::milliseconds(15)); | ||
| 602 | |||
| 603 | if (!joystick->RumblePlay(zero_vibration)) { | ||
| 604 | joystick->EnableVibration(false); | ||
| 605 | return false; | ||
| 606 | } | ||
| 607 | |||
| 608 | joystick->EnableVibration(true); | ||
| 609 | return true; | ||
| 610 | } | ||
| 611 | |||
| 564 | void SDLDriver::SendVibrations() { | 612 | void SDLDriver::SendVibrations() { |
| 565 | while (!vibration_queue.Empty()) { | 613 | while (!vibration_queue.Empty()) { |
| 566 | VibrationRequest request; | 614 | VibrationRequest request; |
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index fc3a44572..d1b4471cf 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h | |||
| @@ -61,9 +61,11 @@ public: | |||
| 61 | 61 | ||
| 62 | bool IsStickInverted(const Common::ParamPackage& params) override; | 62 | bool IsStickInverted(const Common::ParamPackage& params) override; |
| 63 | 63 | ||
| 64 | Common::Input::VibrationError SetRumble( | 64 | Common::Input::VibrationError SetVibration( |
| 65 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; | 65 | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |
| 66 | 66 | ||
| 67 | bool IsVibrationEnabled(const PadIdentifier& identifier) override; | ||
| 68 | |||
| 67 | private: | 69 | private: |
| 68 | struct VibrationRequest { | 70 | struct VibrationRequest { |
| 69 | PadIdentifier identifier; | 71 | PadIdentifier identifier; |
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h index cfbdb26bd..d4c264a8e 100644 --- a/src/input_common/input_engine.h +++ b/src/input_common/input_engine.h | |||
| @@ -108,12 +108,17 @@ public: | |||
| 108 | [[maybe_unused]] const Common::Input::LedStatus& led_status) {} | 108 | [[maybe_unused]] const Common::Input::LedStatus& led_status) {} |
| 109 | 109 | ||
| 110 | // Sets rumble to a controller | 110 | // Sets rumble to a controller |
| 111 | virtual Common::Input::VibrationError SetRumble( | 111 | virtual Common::Input::VibrationError SetVibration( |
| 112 | [[maybe_unused]] const PadIdentifier& identifier, | 112 | [[maybe_unused]] const PadIdentifier& identifier, |
| 113 | [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { | 113 | [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { |
| 114 | return Common::Input::VibrationError::NotSupported; | 114 | return Common::Input::VibrationError::NotSupported; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | // Returns true if device supports vibrations | ||
| 118 | virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | ||
| 119 | return false; | ||
| 120 | } | ||
| 121 | |||
| 117 | // Sets polling mode to a controller | 122 | // Sets polling mode to a controller |
| 118 | virtual Common::Input::PollingError SetPollingMode( | 123 | virtual Common::Input::PollingError SetPollingMode( |
| 119 | [[maybe_unused]] const PadIdentifier& identifier, | 124 | [[maybe_unused]] const PadIdentifier& identifier, |
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index ccc3076ca..4ac182147 100644 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp | |||
| @@ -763,7 +763,11 @@ public: | |||
| 763 | 763 | ||
| 764 | Common::Input::VibrationError SetVibration( | 764 | Common::Input::VibrationError SetVibration( |
| 765 | const Common::Input::VibrationStatus& vibration_status) override { | 765 | const Common::Input::VibrationStatus& vibration_status) override { |
| 766 | return input_engine->SetRumble(identifier, vibration_status); | 766 | return input_engine->SetVibration(identifier, vibration_status); |
| 767 | } | ||
| 768 | |||
| 769 | bool IsVibrationEnabled() override { | ||
| 770 | return input_engine->IsVibrationEnabled(identifier); | ||
| 767 | } | 771 | } |
| 768 | 772 | ||
| 769 | Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override { | 773 | Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override { |