mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
Improvements to XInput vibration:
- use std::chrono to measure 20ms between XInputSetState calls, because clock() measures cpu time and not real time (so calls were made more often than intended) - fixup data types for cached vibration values to prevent u8 values overflowing and giving false positives on m_dev->newVibrateData
This commit is contained in:
parent
b3aff3a1c6
commit
87ffa04a2b
2 changed files with 13 additions and 13 deletions
|
@ -415,28 +415,28 @@ void xinput_pad_handler::ThreadProc()
|
|||
|
||||
// The left motor is the low-frequency rumble motor. The right motor is the high-frequency rumble motor.
|
||||
// The two motors are not the same, and they create different vibration effects. Values range between 0 to 65535.
|
||||
int idx_l = profile->switch_vibration_motors ? 1 : 0;
|
||||
int idx_s = profile->switch_vibration_motors ? 0 : 1;
|
||||
size_t idx_l = profile->switch_vibration_motors ? 1 : 0;
|
||||
size_t idx_s = profile->switch_vibration_motors ? 0 : 1;
|
||||
|
||||
int speed_large = profile->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min;
|
||||
int speed_small = profile->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min;
|
||||
u16 speed_large = profile->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : static_cast<u16>(vibration_min);
|
||||
u16 speed_small = profile->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : static_cast<u16>(vibration_min);
|
||||
|
||||
m_dev->newVibrateData = m_dev->newVibrateData || m_dev->largeVibrate != speed_large || m_dev->smallVibrate != speed_small;
|
||||
m_dev->newVibrateData |= m_dev->largeVibrate != speed_large || m_dev->smallVibrate != speed_small;
|
||||
|
||||
m_dev->largeVibrate = speed_large;
|
||||
m_dev->smallVibrate = speed_small;
|
||||
|
||||
// XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. So I'll use 20ms to be on the safe side. No lag was noticable.
|
||||
if (m_dev->newVibrateData && (clock() - m_dev->last_vibration > 20))
|
||||
if (m_dev->newVibrateData && (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - m_dev->last_vibration) > 20ms))
|
||||
{
|
||||
XINPUT_VIBRATION vibrate;
|
||||
vibrate.wLeftMotorSpeed = speed_large;
|
||||
vibrate.wRightMotorSpeed = speed_small;
|
||||
vibrate.wLeftMotorSpeed = speed_large * 257;
|
||||
vibrate.wRightMotorSpeed = speed_small * 257;
|
||||
|
||||
if ((*xinputSetState)(padnum, &vibrate) == ERROR_SUCCESS)
|
||||
{
|
||||
m_dev->newVibrateData = false;
|
||||
m_dev->last_vibration = clock();
|
||||
m_dev->last_vibration = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#include <Xinput.h>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
|
||||
namespace XINPUT_INFO
|
||||
{
|
||||
|
@ -91,9 +91,9 @@ class xinput_pad_handler final : public PadHandlerBase
|
|||
{
|
||||
u32 deviceNumber{ 0 };
|
||||
bool newVibrateData{ true };
|
||||
u8 largeVibrate{ 0 };
|
||||
u8 smallVibrate{ 0 };
|
||||
clock_t last_vibration{ 0 };
|
||||
u16 largeVibrate{ 0 };
|
||||
u16 smallVibrate{ 0 };
|
||||
std::chrono::high_resolution_clock::time_point last_vibration;
|
||||
pad_config* config{ nullptr };
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue