1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-17 02:24:07 +02:00

#15 Windows fix gamepad vibration on high FPS

This commit is contained in:
XProger
2018-03-06 04:19:38 +03:00
parent 6fb0e2781e
commit 8d3371cbe2

View File

@@ -215,24 +215,39 @@ void (WINAPI *XInputEnable) (BOOL enable) = NULL;
#define JOY_DEAD_ZONE_STICK 0.3f #define JOY_DEAD_ZONE_STICK 0.3f
#define JOY_DEAD_ZONE_TRIGGER 0.01f #define JOY_DEAD_ZONE_TRIGGER 0.01f
#define JOY_MIN_UPDATE_FX_TIME 50
bool joyReady[INPUT_JOY_COUNT]; struct JoyDevice {
float vL, vR; // current value for left/right motor vibration
float oL, oR; // last applied value
int time; // time when we can send vibration update
bool ready;
} joyDevice[INPUT_JOY_COUNT];
bool osJoyReady(int index) { bool osJoyReady(int index) {
return joyReady[index]; return joyDevice[index].ready;
} }
void osJoyVibrate(int index, float L, float R) { void osJoyVibrate(int index, float L, float R) {
if (XInputSetState && joyReady[index]) { joyDevice[index].vL = L;
joyDevice[index].vR = R;
}
void joyRumble(int index) {
JoyDevice &joy = joyDevice[index];
if (XInputSetState && joy.ready && (joy.vL != joy.oL || joy.vR != joy.oR) && osGetTime() >= joy.time) {
XINPUT_VIBRATION vibration; XINPUT_VIBRATION vibration;
vibration.wLeftMotorSpeed = int(L * 65535.0f); vibration.wLeftMotorSpeed = int(joy.vL * 65535.0f);
vibration.wRightMotorSpeed = int(R * 65535.0f); vibration.wRightMotorSpeed = int(joy.vR * 65535.0f);
XInputSetState(index, &vibration); XInputSetState(index, &vibration);
joy.oL = joy.vL;
joy.oR = joy.vR;
joy.time = osGetTime() + JOY_MIN_UPDATE_FX_TIME;
} }
} }
void joyInit() { void joyInit() {
memset(joyReady, 0, sizeof(joyReady)); memset(joyDevice, 0, sizeof(joyDevice));
HMODULE h = LoadLibrary("xinput1_3.dll"); HMODULE h = LoadLibrary("xinput1_3.dll");
if (h == NULL) if (h == NULL)
@@ -246,18 +261,21 @@ void joyInit() {
if (XInputGetState) { // XInput if (XInputGetState) { // XInput
XINPUT_STATE state; XINPUT_STATE state;
int res = XInputGetState(j, &state); int res = XInputGetState(j, &state);
joyReady[j] = (XInputGetState(j, &state) == ERROR_SUCCESS); joyDevice[j].ready = (XInputGetState(j, &state) == ERROR_SUCCESS);
} else { // mmSystem (legacy) } else { // mmSystem (legacy)
JOYINFOEX info; JOYINFOEX info;
info.dwSize = sizeof(info); info.dwSize = sizeof(info);
info.dwFlags = JOY_RETURNALL; info.dwFlags = JOY_RETURNALL;
joyReady[j] = (joyGetPosEx(j, &info) == JOYERR_NOERROR); joyDevice[j].ready = (joyGetPosEx(j, &info) == JOYERR_NOERROR);
} }
if (joyDevice[j].ready)
LOG("Gamepad %d is ready\n", j + 1);
} }
} }
void joyFree() { void joyFree() {
memset(joyReady, 0, sizeof(joyReady)); memset(joyDevice, 0, sizeof(joyDevice));
Input::reset(); Input::reset();
} }
@@ -279,7 +297,9 @@ int joyDeadZone(int value, int zone) {
void joyUpdate() { void joyUpdate() {
for (int j = 0; j < INPUT_JOY_COUNT; j++) { for (int j = 0; j < INPUT_JOY_COUNT; j++) {
if (!joyReady[j]) continue; if (!joyDevice[j].ready) continue;
joyRumble(j);
if (XInputGetState) { // XInput if (XInputGetState) { // XInput
XINPUT_STATE state; XINPUT_STATE state;