summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/input.h5
-rw-r--r--src/core/hid/emulated_controller.cpp45
-rw-r--r--src/core/hid/emulated_controller.h5
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp4
-rw-r--r--src/input_common/drivers/gc_adapter.cpp6
-rw-r--r--src/input_common/drivers/gc_adapter.h4
-rw-r--r--src/input_common/drivers/sdl_driver.cpp64
-rw-r--r--src/input_common/drivers/sdl_driver.h4
-rw-r--r--src/input_common/input_engine.h7
-rw-r--r--src/input_common/input_poller.cpp6
10 files changed, 93 insertions, 57 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 {
enum class VibrationAmplificationType {
Linear,
Exponential,
- Test,
};
// Analog properties for calibration
@@ -325,6 +324,10 @@ public:
return VibrationError::NotSupported;
}
+ virtual bool IsVibrationEnabled() {
+ return false;
+ }
+
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported;
}
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 025f1c78e..06c2081a9 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
Common::Input::VibrationError::None;
}
-bool EmulatedController::TestVibration(std::size_t device_index) {
- if (device_index >= output_devices.size()) {
- return false;
- }
- if (!output_devices[device_index]) {
- return false;
- }
-
+bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
@@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
return false;
}
- const Common::Input::VibrationStatus test_vibration = {
- .low_amplitude = 0.001f,
- .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
- .high_amplitude = 0.001f,
- .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
- .type = Common::Input::VibrationAmplificationType::Test,
- };
-
- const Common::Input::VibrationStatus zero_vibration = {
- .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
- .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
- .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
- .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
- .type = Common::Input::VibrationAmplificationType::Test,
- };
-
- // Send a slight vibration to test for rumble support
- output_devices[device_index]->SetVibration(test_vibration);
+ if (device_index >= output_devices.size()) {
+ return false;
+ }
- // Wait for about 15ms to ensure the controller is ready for the stop command
- std::this_thread::sleep_for(std::chrono::milliseconds(15));
+ if (!output_devices[device_index]) {
+ return false;
+ }
- // Stop any vibration and return the result
- return output_devices[device_index]->SetVibration(zero_vibration) ==
- Common::Input::VibrationError::None;
+ return output_devices[device_index]->IsVibrationEnabled();
}
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
@@ -1234,12 +1211,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const {
return is_connected;
}
-bool EmulatedController::IsVibrationEnabled() const {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
- return player.vibration_enabled;
-}
-
NpadIdType EmulatedController::GetNpadIdType() const {
std::scoped_lock lock{mutex};
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:
*/
bool IsConnected(bool get_temporary_value = false) const;
- /// Returns true if vibration is enabled
- bool IsVibrationEnabled() const;
-
/// Removes all callbacks created from input devices
void UnloadInput();
@@ -339,7 +336,7 @@ public:
* Sends a small vibration to the output device
* @return true if SetVibration was successfull
*/
- bool TestVibration(std::size_t device_index);
+ bool IsVibrationEnabled(std::size_t device_index);
/**
* 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 98e4f2af7..b85831de1 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -867,7 +867,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
return false;
}
- if (!controller.device->IsVibrationEnabled()) {
+ if (!controller.device->IsVibrationEnabled(device_index)) {
if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
// Send an empty vibration to stop any vibrations.
@@ -1000,7 +1000,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
}
controller.vibration[device_index].device_mounted =
- controller.device->TestVibration(device_index);
+ controller.device->IsVibrationEnabled(device_index);
}
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
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) {
return true;
}
-Common::Input::VibrationError GCAdapter::SetRumble(
+Common::Input::VibrationError GCAdapter::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
const auto processed_amplitude =
@@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble(
return Common::Input::VibrationError::None;
}
+bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+ return rumble_enabled;
+}
+
void GCAdapter::UpdateVibrations() {
// Use 8 states to keep the switching between on/off fast enough for
// 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:
explicit GCAdapter(std::string input_engine_);
~GCAdapter() override;
- Common::Input::VibrationError SetRumble(
+ Common::Input::VibrationError SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
+ bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
/// Used for automapping features
std::vector<Common::ParamPackage> GetInputDevices() const override;
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 b72e4b397..ddbe8a896 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -114,6 +114,20 @@ public:
}
return false;
}
+
+ void EnableVibration(bool is_enabled) {
+ has_vibration = is_enabled;
+ is_vibration_tested = true;
+ }
+
+ bool HasVibration() const {
+ return has_vibration;
+ }
+
+ bool IsVibrationTested() const {
+ return is_vibration_tested;
+ }
+
/**
* The Pad identifier of the joystick
*/
@@ -236,6 +250,8 @@ private:
u64 last_motion_update{};
bool has_gyro{false};
bool has_accel{false};
+ bool has_vibration{false};
+ bool is_vibration_tested{false};
BasicMotion motion;
};
@@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
return devices;
}
-Common::Input::VibrationError SDLDriver::SetRumble(
+Common::Input::VibrationError SDLDriver::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto joystick =
GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
@@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble(
.type = Common::Input::VibrationAmplificationType::Exponential,
};
- if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
- if (!joystick->RumblePlay(new_vibration)) {
- return Common::Input::VibrationError::Unknown;
- }
- return Common::Input::VibrationError::None;
- }
-
vibration_queue.Push(VibrationRequest{
.identifier = identifier,
.vibration = new_vibration,
@@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble(
return Common::Input::VibrationError::None;
}
+bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
+ const auto joystick =
+ GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
+
+ constexpr Common::Input::VibrationStatus test_vibration{
+ .low_amplitude = 1,
+ .low_frequency = 160.0f,
+ .high_amplitude = 1,
+ .high_frequency = 320.0f,
+ .type = Common::Input::VibrationAmplificationType::Exponential,
+ };
+
+ constexpr Common::Input::VibrationStatus zero_vibration{
+ .low_amplitude = 0,
+ .low_frequency = 160.0f,
+ .high_amplitude = 0,
+ .high_frequency = 320.0f,
+ .type = Common::Input::VibrationAmplificationType::Exponential,
+ };
+
+ if (joystick->IsVibrationTested()) {
+ return joystick->HasVibration();
+ }
+
+ // First vibration might fail
+ joystick->RumblePlay(test_vibration);
+
+ // Wait for about 15ms to ensure the controller is ready for the stop command
+ std::this_thread::sleep_for(std::chrono::milliseconds(15));
+
+ if (!joystick->RumblePlay(zero_vibration)) {
+ joystick->EnableVibration(false);
+ return false;
+ }
+
+ joystick->EnableVibration(true);
+ return true;
+}
+
void SDLDriver::SendVibrations() {
while (!vibration_queue.Empty()) {
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:
bool IsStickInverted(const Common::ParamPackage& params) override;
- Common::Input::VibrationError SetRumble(
+ Common::Input::VibrationError SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
+ bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
private:
struct VibrationRequest {
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:
[[maybe_unused]] const Common::Input::LedStatus& led_status) {}
// Sets rumble to a controller
- virtual Common::Input::VibrationError SetRumble(
+ virtual Common::Input::VibrationError SetVibration(
[[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
return Common::Input::VibrationError::NotSupported;
}
+ // Returns true if device supports vibrations
+ virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+ return false;
+ }
+
// Sets polling mode to a controller
virtual Common::Input::PollingError SetPollingMode(
[[maybe_unused]] const PadIdentifier& identifier,
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
index ca33fb4eb..fff9731ce 100644
--- a/src/input_common/input_poller.cpp
+++ b/src/input_common/input_poller.cpp
@@ -763,7 +763,11 @@ public:
Common::Input::VibrationError SetVibration(
const Common::Input::VibrationStatus& vibration_status) override {
- return input_engine->SetRumble(identifier, vibration_status);
+ return input_engine->SetVibration(identifier, vibration_status);
+ }
+
+ bool IsVibrationEnabled() override {
+ return input_engine->IsVibrationEnabled(identifier);
}
Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override {