mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
Merge pull request #9107 from german77/gidoly_rules
input_common: cache vibration tests
This commit is contained in:
commit
77803d96be
10 changed files with 93 additions and 57 deletions
|
@ -100,7 +100,6 @@ enum class CameraError {
|
||||||
enum class VibrationAmplificationType {
|
enum class VibrationAmplificationType {
|
||||||
Linear,
|
Linear,
|
||||||
Exponential,
|
Exponential,
|
||||||
Test,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Analog properties for calibration
|
// Analog properties for calibration
|
||||||
|
@ -325,6 +324,10 @@ public:
|
||||||
return VibrationError::NotSupported;
|
return VibrationError::NotSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool IsVibrationEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
|
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
|
||||||
return PollingError::NotSupported;
|
return PollingError::NotSupported;
|
||||||
}
|
}
|
||||||
|
|
|
@ -970,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
|
||||||
Common::Input::VibrationError::None;
|
Common::Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::TestVibration(std::size_t device_index) {
|
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
|
||||||
if (device_index >= output_devices.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!output_devices[device_index]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
|
|
||||||
|
@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Common::Input::VibrationStatus test_vibration = {
|
if (device_index >= output_devices.size()) {
|
||||||
.low_amplitude = 0.001f,
|
return false;
|
||||||
.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 = {
|
if (!output_devices[device_index]) {
|
||||||
.low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
|
return false;
|
||||||
.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
|
return output_devices[device_index]->IsVibrationEnabled();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
|
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
|
||||||
|
@ -1234,12 +1211,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const {
|
||||||
return is_connected;
|
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 {
|
NpadIdType EmulatedController::GetNpadIdType() const {
|
||||||
std::scoped_lock lock{mutex};
|
std::scoped_lock lock{mutex};
|
||||||
return npad_id_type;
|
return npad_id_type;
|
||||||
|
|
|
@ -206,9 +206,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsConnected(bool get_temporary_value = false) const;
|
bool IsConnected(bool get_temporary_value = false) const;
|
||||||
|
|
||||||
/// Returns true if vibration is enabled
|
|
||||||
bool IsVibrationEnabled() const;
|
|
||||||
|
|
||||||
/// Removes all callbacks created from input devices
|
/// Removes all callbacks created from input devices
|
||||||
void UnloadInput();
|
void UnloadInput();
|
||||||
|
|
||||||
|
@ -339,7 +336,7 @@ public:
|
||||||
* Sends a small vibration to the output device
|
* Sends a small vibration to the output device
|
||||||
* @return true if SetVibration was successfull
|
* @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
|
* Sets the desired data to be polled from a controller
|
||||||
|
|
|
@ -868,7 +868,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller.device->IsVibrationEnabled()) {
|
if (!controller.device->IsVibrationEnabled(device_index)) {
|
||||||
if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
|
if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
|
||||||
controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
|
controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
|
||||||
// Send an empty vibration to stop any vibrations.
|
// Send an empty vibration to stop any vibrations.
|
||||||
|
@ -1001,7 +1001,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.vibration[device_index].device_mounted =
|
controller.vibration[device_index].device_mounted =
|
||||||
controller.device->TestVibration(device_index);
|
controller.device->IsVibrationEnabled(device_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
|
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
|
||||||
|
|
|
@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Input::VibrationError GCAdapter::SetRumble(
|
Common::Input::VibrationError GCAdapter::SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
||||||
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
|
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
|
||||||
const auto processed_amplitude =
|
const auto processed_amplitude =
|
||||||
|
@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble(
|
||||||
return Common::Input::VibrationError::None;
|
return Common::Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
||||||
|
return rumble_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void GCAdapter::UpdateVibrations() {
|
void GCAdapter::UpdateVibrations() {
|
||||||
// Use 8 states to keep the switching between on/off fast enough for
|
// Use 8 states to keep the switching between on/off fast enough for
|
||||||
// a human to feel different vibration strenght
|
// a human to feel different vibration strenght
|
||||||
|
|
|
@ -25,9 +25,11 @@ public:
|
||||||
explicit GCAdapter(std::string input_engine_);
|
explicit GCAdapter(std::string input_engine_);
|
||||||
~GCAdapter() override;
|
~GCAdapter() override;
|
||||||
|
|
||||||
Common::Input::VibrationError SetRumble(
|
Common::Input::VibrationError SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||||
|
|
||||||
|
bool IsVibrationEnabled(const PadIdentifier& identifier) override;
|
||||||
|
|
||||||
/// Used for automapping features
|
/// Used for automapping features
|
||||||
std::vector<Common::ParamPackage> GetInputDevices() const override;
|
std::vector<Common::ParamPackage> GetInputDevices() const override;
|
||||||
ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
|
ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
|
||||||
|
|
|
@ -114,6 +114,20 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
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
|
* The Pad identifier of the joystick
|
||||||
*/
|
*/
|
||||||
|
@ -236,6 +250,8 @@ private:
|
||||||
u64 last_motion_update{};
|
u64 last_motion_update{};
|
||||||
bool has_gyro{false};
|
bool has_gyro{false};
|
||||||
bool has_accel{false};
|
bool has_accel{false};
|
||||||
|
bool has_vibration{false};
|
||||||
|
bool is_vibration_tested{false};
|
||||||
BasicMotion motion;
|
BasicMotion motion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Input::VibrationError SDLDriver::SetRumble(
|
Common::Input::VibrationError SDLDriver::SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
||||||
const auto joystick =
|
const auto joystick =
|
||||||
GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
|
GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
|
||||||
|
@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble(
|
||||||
.type = Common::Input::VibrationAmplificationType::Exponential,
|
.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{
|
vibration_queue.Push(VibrationRequest{
|
||||||
.identifier = identifier,
|
.identifier = identifier,
|
||||||
.vibration = new_vibration,
|
.vibration = new_vibration,
|
||||||
|
@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble(
|
||||||
return Common::Input::VibrationError::None;
|
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() {
|
void SDLDriver::SendVibrations() {
|
||||||
while (!vibration_queue.Empty()) {
|
while (!vibration_queue.Empty()) {
|
||||||
VibrationRequest request;
|
VibrationRequest request;
|
||||||
|
|
|
@ -61,9 +61,11 @@ public:
|
||||||
|
|
||||||
bool IsStickInverted(const Common::ParamPackage& params) override;
|
bool IsStickInverted(const Common::ParamPackage& params) override;
|
||||||
|
|
||||||
Common::Input::VibrationError SetRumble(
|
Common::Input::VibrationError SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||||
|
|
||||||
|
bool IsVibrationEnabled(const PadIdentifier& identifier) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VibrationRequest {
|
struct VibrationRequest {
|
||||||
PadIdentifier identifier;
|
PadIdentifier identifier;
|
||||||
|
|
|
@ -108,12 +108,17 @@ public:
|
||||||
[[maybe_unused]] const Common::Input::LedStatus& led_status) {}
|
[[maybe_unused]] const Common::Input::LedStatus& led_status) {}
|
||||||
|
|
||||||
// Sets rumble to a controller
|
// Sets rumble to a controller
|
||||||
virtual Common::Input::VibrationError SetRumble(
|
virtual Common::Input::VibrationError SetVibration(
|
||||||
[[maybe_unused]] const PadIdentifier& identifier,
|
[[maybe_unused]] const PadIdentifier& identifier,
|
||||||
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
|
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
|
||||||
return Common::Input::VibrationError::NotSupported;
|
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
|
// Sets polling mode to a controller
|
||||||
virtual Common::Input::PollingError SetPollingMode(
|
virtual Common::Input::PollingError SetPollingMode(
|
||||||
[[maybe_unused]] const PadIdentifier& identifier,
|
[[maybe_unused]] const PadIdentifier& identifier,
|
||||||
|
|
|
@ -763,7 +763,11 @@ public:
|
||||||
|
|
||||||
Common::Input::VibrationError SetVibration(
|
Common::Input::VibrationError SetVibration(
|
||||||
const Common::Input::VibrationStatus& vibration_status) override {
|
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 {
|
Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override {
|
||||||
|
|
Loading…
Reference in a new issue