core/hid: Fix rumble too strong at 1%
This commit is contained in:
parent
601ac43495
commit
c3ff0a8ac0
3 changed files with 48 additions and 13 deletions
|
@ -60,6 +60,12 @@ enum class PollingError {
|
||||||
Unknown,
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hint for amplification curve to be used
|
||||||
|
enum class VibrationAmplificationType {
|
||||||
|
Linear,
|
||||||
|
Exponential,
|
||||||
|
};
|
||||||
|
|
||||||
struct AnalogProperties {
|
struct AnalogProperties {
|
||||||
float deadzone{};
|
float deadzone{};
|
||||||
float range{1.0f};
|
float range{1.0f};
|
||||||
|
@ -126,6 +132,7 @@ struct VibrationStatus {
|
||||||
f32 low_frequency{};
|
f32 low_frequency{};
|
||||||
f32 high_amplitude{};
|
f32 high_amplitude{};
|
||||||
f32 high_frequency{};
|
f32 high_frequency{};
|
||||||
|
VibrationAmplificationType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LedStatus {
|
struct LedStatus {
|
||||||
|
|
|
@ -54,7 +54,6 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadType type
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadFromSettings() {
|
void EmulatedController::ReloadFromSettings() {
|
||||||
//LOG_ERROR(Service_HID, "reload config from settings {}", NpadIdTypeToIndex(npad_id_type));
|
|
||||||
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];
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ void EmulatedController::ReloadFromSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadInput() {
|
void EmulatedController::ReloadInput() {
|
||||||
//LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type));
|
// LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type));
|
||||||
// If you load any device here add the equivalent to the UnloadInput() function
|
// If you load any device here add the equivalent to the UnloadInput() function
|
||||||
const auto left_side = button_params[Settings::NativeButton::ZL];
|
const auto left_side = button_params[Settings::NativeButton::ZL];
|
||||||
const auto right_side = button_params[Settings::NativeButton::ZR];
|
const auto right_side = button_params[Settings::NativeButton::ZR];
|
||||||
|
@ -640,12 +639,22 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
|
||||||
if (!output_devices[device_index]) {
|
if (!output_devices[device_index]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
|
const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f;
|
||||||
|
|
||||||
|
// Exponential amplification is too strong at low amplitudes. Switch to a linear
|
||||||
|
// amplification if strength is set below 0.7f
|
||||||
|
const Input::VibrationAmplificationType type =
|
||||||
|
strength > 0.7f ? Input::VibrationAmplificationType::Exponential
|
||||||
|
: Input::VibrationAmplificationType::Linear;
|
||||||
|
|
||||||
const Input::VibrationStatus status = {
|
const Input::VibrationStatus status = {
|
||||||
.low_amplitude = vibration.high_amplitude,
|
.low_amplitude = std::min(vibration.low_amplitude * strength, 1.0f),
|
||||||
.low_frequency = vibration.high_amplitude,
|
.low_frequency = vibration.low_frequency,
|
||||||
.high_amplitude = vibration.high_amplitude,
|
.high_amplitude = std::min(vibration.high_amplitude * strength, 1.0f),
|
||||||
.high_frequency = vibration.high_amplitude,
|
.high_frequency = vibration.high_frequency,
|
||||||
|
.type = type,
|
||||||
};
|
};
|
||||||
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
@ -661,6 +670,7 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||||
.low_frequency = 160.0f,
|
.low_frequency = 160.0f,
|
||||||
.high_amplitude = 0.001f,
|
.high_amplitude = 0.001f,
|
||||||
.high_frequency = 320.0f,
|
.high_frequency = 320.0f,
|
||||||
|
.type = Input::VibrationAmplificationType::Linear,
|
||||||
};
|
};
|
||||||
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
@ -687,7 +697,7 @@ void EmulatedController::Connect() {
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
temporary_is_connected = true;
|
temporary_is_connected = true;
|
||||||
TriggerOnChange(ControllerTriggerType::Connected,false);
|
TriggerOnChange(ControllerTriggerType::Connected, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +707,7 @@ void EmulatedController::Connect() {
|
||||||
is_connected = true;
|
is_connected = true;
|
||||||
}
|
}
|
||||||
LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type));
|
LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type));
|
||||||
TriggerOnChange(ControllerTriggerType::Connected,true);
|
TriggerOnChange(ControllerTriggerType::Connected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::Disconnect() {
|
void EmulatedController::Disconnect() {
|
||||||
|
@ -707,7 +717,7 @@ void EmulatedController::Disconnect() {
|
||||||
temporary_is_connected = false;
|
temporary_is_connected = false;
|
||||||
LOG_ERROR(Service_HID, "Disconnected temporal controller {}",
|
LOG_ERROR(Service_HID, "Disconnected temporal controller {}",
|
||||||
NpadIdTypeToIndex(npad_id_type));
|
NpadIdTypeToIndex(npad_id_type));
|
||||||
TriggerOnChange(ControllerTriggerType::Disconnected,false);
|
TriggerOnChange(ControllerTriggerType::Disconnected, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,7 +727,7 @@ void EmulatedController::Disconnect() {
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
}
|
}
|
||||||
LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type));
|
LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type));
|
||||||
TriggerOnChange(ControllerTriggerType::Disconnected,true);
|
TriggerOnChange(ControllerTriggerType::Disconnected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsConnected(bool temporary) const {
|
bool EmulatedController::IsConnected(bool temporary) const {
|
||||||
|
@ -751,7 +761,7 @@ void EmulatedController::SetNpadType(NpadType npad_type_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
temporary_npad_type = npad_type_;
|
temporary_npad_type = npad_type_;
|
||||||
TriggerOnChange(ControllerTriggerType::Type,false);
|
TriggerOnChange(ControllerTriggerType::Type, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +774,7 @@ void EmulatedController::SetNpadType(NpadType npad_type_) {
|
||||||
}
|
}
|
||||||
npad_type = npad_type_;
|
npad_type = npad_type_;
|
||||||
}
|
}
|
||||||
TriggerOnChange(ControllerTriggerType::Type,true);
|
TriggerOnChange(ControllerTriggerType::Type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
LedPattern EmulatedController::GetLedPattern() const {
|
LedPattern EmulatedController::GetLedPattern() const {
|
||||||
|
|
|
@ -107,6 +107,14 @@ public:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasHDRumble() const {
|
||||||
|
if (sdl_controller) {
|
||||||
|
return (SDL_GameControllerGetType(sdl_controller.get()) ==
|
||||||
|
SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* The Pad identifier of the joystick
|
* The Pad identifier of the joystick
|
||||||
*/
|
*/
|
||||||
|
@ -515,16 +523,26 @@ Input::VibrationError SDLDriver::SetRumble(const PadIdentifier& identifier,
|
||||||
const auto process_amplitude = [](f32 amplitude) {
|
const auto process_amplitude = [](f32 amplitude) {
|
||||||
return (amplitude + std::pow(amplitude, 0.3f)) * 0.5f * 0xFFFF;
|
return (amplitude + std::pow(amplitude, 0.3f)) * 0.5f * 0xFFFF;
|
||||||
};
|
};
|
||||||
const Input::VibrationStatus new_vibration{
|
const Input::VibrationStatus exponential_vibration{
|
||||||
.low_amplitude = process_amplitude(vibration.low_amplitude),
|
.low_amplitude = process_amplitude(vibration.low_amplitude),
|
||||||
.low_frequency = vibration.low_frequency,
|
.low_frequency = vibration.low_frequency,
|
||||||
.high_amplitude = process_amplitude(vibration.high_amplitude),
|
.high_amplitude = process_amplitude(vibration.high_amplitude),
|
||||||
.high_frequency = vibration.high_frequency,
|
.high_frequency = vibration.high_frequency,
|
||||||
|
.type = Input::VibrationAmplificationType::Exponential,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Input::VibrationStatus new_vibration{};
|
||||||
|
|
||||||
|
if (vibration.type == Input::VibrationAmplificationType::Linear || joystick->HasHDRumble()) {
|
||||||
|
new_vibration = vibration;
|
||||||
|
} else {
|
||||||
|
new_vibration = exponential_vibration;
|
||||||
|
}
|
||||||
|
|
||||||
if (!joystick->RumblePlay(new_vibration)) {
|
if (!joystick->RumblePlay(new_vibration)) {
|
||||||
return Input::VibrationError::Unknown;
|
return Input::VibrationError::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Input::VibrationError::None;
|
return Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
|
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
|
||||||
|
|
Loading…
Reference in a new issue