CommonHostInterface: Throttle rumble updates to changes or every 100ms

These updates appear to be synchronous, and limit how fast we can fast
forward when controllers are connected via bluetooth.
This commit is contained in:
Connor McLaughlin 2021-01-19 00:27:33 +10:00
parent d4f52f1ec7
commit cbee8fab66
2 changed files with 26 additions and 2 deletions

View file

@ -1075,23 +1075,46 @@ void CommonHostInterface::AddControllerRumble(u32 controller_index, u32 num_moto
rumble.num_motors = std::min<u32>(num_motors, ControllerRumbleState::MAX_MOTORS); rumble.num_motors = std::min<u32>(num_motors, ControllerRumbleState::MAX_MOTORS);
rumble.last_strength.fill(0.0f); rumble.last_strength.fill(0.0f);
rumble.update_callback = std::move(callback); rumble.update_callback = std::move(callback);
rumble.last_update_time = Common::Timer::GetValue();
m_controller_vibration_motors.push_back(std::move(rumble)); m_controller_vibration_motors.push_back(std::move(rumble));
} }
void CommonHostInterface::UpdateControllerRumble() void CommonHostInterface::UpdateControllerRumble()
{ {
if (m_controller_vibration_motors.empty())
return;
// Rumble update frequency in milliseconds.
// We won't send an update to the controller unless this amount of time has passed, if the value has not changed.
// This is because the rumble update is synchronous, and with bluetooth latency can severely impact fast forward
// performance.
static constexpr float UPDATE_FREQUENCY = 1000.0f;
const u64 time = Common::Timer::GetValue();
for (ControllerRumbleState& rumble : m_controller_vibration_motors) for (ControllerRumbleState& rumble : m_controller_vibration_motors)
{ {
Controller* controller = System::GetController(rumble.controller_index); Controller* controller = System::GetController(rumble.controller_index);
if (!controller) if (!controller)
continue; continue;
bool changed = false;
for (u32 i = 0; i < rumble.num_motors; i++) for (u32 i = 0; i < rumble.num_motors; i++)
rumble.last_strength[i] = controller->GetVibrationMotorStrength(i); {
const float strength = controller->GetVibrationMotorStrength(i);
if (rumble.last_strength[i] != strength)
{
rumble.last_strength[i] = strength;
changed = true;
}
}
if (changed || Common::Timer::ConvertValueToMilliseconds(time - rumble.last_update_time) >= UPDATE_FREQUENCY)
{
rumble.last_update_time = time;
rumble.update_callback(rumble.last_strength.data(), rumble.num_motors); rumble.update_callback(rumble.last_strength.data(), rumble.num_motors);
} }
} }
}
void CommonHostInterface::StopControllerRumble() void CommonHostInterface::StopControllerRumble()
{ {

View file

@ -396,6 +396,7 @@ private:
u32 num_motors; u32 num_motors;
std::array<float, MAX_MOTORS> last_strength; std::array<float, MAX_MOTORS> last_strength;
ControllerRumbleCallback update_callback; ControllerRumbleCallback update_callback;
u64 last_update_time;
}; };
std::vector<ControllerRumbleState> m_controller_vibration_motors; std::vector<ControllerRumbleState> m_controller_vibration_motors;