AnalogController: Fix sync/readback value for vibration

This commit is contained in:
Stenzek
2025-10-04 22:59:53 +10:00
parent 1665cb6953
commit f219c2ca98
4 changed files with 33 additions and 21 deletions

View File

@@ -151,7 +151,7 @@ float AnalogController::GetBindState(u32 index) const
if (index >= LED_BIND_START_INDEX)
return BoolToFloat(index == LED_BIND_START_INDEX && m_analog_mode);
else if (index >= MOTOR_BIND_START_INDEX)
return m_motor_state[index - MOTOR_BIND_START_INDEX] * (1.0f / 255.0f);
return GetMotorStrength(index - MOTOR_BIND_START_INDEX);
else if (index >= HALFAXIS_BIND_START_INDEX)
return static_cast<float>(m_half_axis_state[index - HALFAXIS_BIND_START_INDEX]) * (1.0f / 255.0f);
else if (index < static_cast<u32>(Button::Analog))
@@ -377,21 +377,26 @@ void AnalogController::SetMotorState(u32 motor, u8 value)
{
m_motor_state[motor] = value;
// Small motor is only 0/1.
const u8 state =
(motor == SmallMotor) ? (((m_motor_state[SmallMotor] & 0x01) != 0x00) ? 255 : 0) : m_motor_state[LargeMotor];
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
const double x = static_cast<double>(std::clamp<s32>(static_cast<s32>(state) + m_vibration_bias[motor], 0, 255));
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
156.82454281087692 * x + 3.637978807091713e-11;
const float hvalue = (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
DEV_LOG("Set {} motor to {} (raw {})", (motor == LargeMotor) ? "large" : "small", hvalue, state);
const float hvalue = GetMotorStrength(motor);
DEV_LOG("Set {} motor to {} (raw {})", (motor == LargeMotor) ? "large" : "small", hvalue, m_motor_state[motor]);
InputManager::SetPadVibrationIntensity(m_index, MOTOR_BIND_START_INDEX + motor, hvalue);
}
}
float AnalogController::GetMotorStrength(u32 motor) const
{
// Small motor is only 0/1.
const u8 state =
(motor == SmallMotor) ? (((m_motor_state[SmallMotor] & 0x01) != 0x00) ? 255 : 0) : m_motor_state[LargeMotor];
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
const double x = static_cast<double>(std::clamp<s32>(static_cast<s32>(state) + m_vibration_bias[motor], 0, 255));
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
156.82454281087692 * x + 3.637978807091713e-11;
return (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
}
u16 AnalogController::GetExtraButtonMask() const
{
u16 mask = 0xFFFF;

View File

@@ -124,6 +124,7 @@ private:
void SetAnalogMode(bool enabled, bool show_message);
void ProcessAnalogModeToggle();
void SetMotorState(u32 motor, u8 value);
float GetMotorStrength(u32 motor) const;
u16 GetExtraButtonMask() const;
void ResetRumbleConfig();
void Poll();

View File

@@ -125,7 +125,7 @@ float NeGconRumble::GetBindState(u32 index) const
}
else if (index >= MOTOR_BIND_START_INDEX)
{
return m_motor_state[index - MOTOR_BIND_START_INDEX] * (1.0f / 255.0f);
return GetMotorStrength(index - MOTOR_BIND_START_INDEX);
}
else if (index >= (HALFAXIS_BIND_START_INDEX + static_cast<u32>(HalfAxis::I)))
{
@@ -279,18 +279,23 @@ void NeGconRumble::SetMotorState(u32 motor, u8 value)
{
m_motor_state[motor] = value;
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
const u8 state = m_motor_state[motor];
const double x = static_cast<double>(std::clamp<s32>(static_cast<s32>(state) + m_vibration_bias[motor], 0, 255));
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
156.82454281087692 * x + 3.637978807091713e-11;
const float hvalue = (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
DEV_LOG("Set {} motor to {} (raw {})", (motor == LargeMotor) ? "large" : "small", hvalue, state);
const float hvalue = GetMotorStrength(motor);
DEV_LOG("Set {} motor to {} (raw {})", (motor == LargeMotor) ? "large" : "small", hvalue, m_motor_state[motor]);
InputManager::SetPadVibrationIntensity(m_index, MOTOR_BIND_START_INDEX + motor, hvalue);
}
}
float NeGconRumble::GetMotorStrength(u32 motor) const
{
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
const u8 state = m_motor_state[motor];
const double x = static_cast<double>(std::clamp<s32>(static_cast<s32>(state) + m_vibration_bias[motor], 0, 255));
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
156.82454281087692 * x + 3.637978807091713e-11;
return (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
}
u8 NeGconRumble::GetExtraButtonMaskLSB() const
{
return 0xFF;

View File

@@ -145,6 +145,7 @@ private:
void SetAnalogMode(bool enabled, bool show_message);
void ProcessAnalogModeToggle();
void SetMotorState(u32 motor, u8 value);
float GetMotorStrength(u32 motor) const;
u8 GetExtraButtonMaskLSB() const;
void ResetRumbleConfig();
void SetMotorStateForConfigIndex(int index, u8 value);