input_common: cache vibration tests
This commit is contained in:
parent
6b71530fa8
commit
7f66050f0c
10 changed files with 93 additions and 57 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
if (device_index >= output_devices.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a slight vibration to test for rumble support
|
||||
output_devices[device_index]->SetVibration(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));
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue