mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-24 11:49:05 +02:00
Add optional controller rumble on button press
New "Vibrate controller on button press" setting under Controls. When enabled, pressing a gamepad button rumbles that pad for as long as it's held - something the PSP hardware never had, but which some people want from a modern pad. Implemented per platform behind System_ControllerRumbleStart/Stop: SDL uses SDL_RumbleGamepad, Windows feeds it into XinputDevice's existing vibration path so it doesn't fight with the vibration games request through sceCtrl, and Android goes through InputDevice.getVibrator() in Java. Stubbed elsewhere. The D-pad is excluded, since it gets tapped constantly while navigating. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GgACRqkQNpfJQ4fjwyoEup
This commit is contained in:
1 parent
6d4bc5f261
commit
e5bd8e8e58
20 files changed
+173
No files matched your search
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/CommonWindows.h"
|
||||
@@ -123,6 +124,15 @@ static void UnloadXInputDLL() {}
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
|
||||
// Written from the input thread by XinputSetButtonRumble, read by ApplyVibration.
|
||||
static std::atomic<bool> g_buttonRumble[XUSER_MAX_COUNT];
|
||||
|
||||
void XinputSetButtonRumble(int pad, bool on) {
|
||||
if (pad >= 0 && pad < XUSER_MAX_COUNT) {
|
||||
g_buttonRumble[pad] = on;
|
||||
}
|
||||
}
|
||||
|
||||
// Undocumented. Steam annoyingly grabs this button though....
|
||||
#define XINPUT_GUIDE_BUTTON 0x400
|
||||
|
||||
@@ -307,6 +317,7 @@ void XinputDevice::ApplyVibration(int pad, XINPUT_VIBRATION &vibration) {
|
||||
vibration.wLeftMotorSpeed = 0;
|
||||
vibration.wRightMotorSpeed = 0;
|
||||
}
|
||||
ApplyButtonRumble(pad, vibration);
|
||||
|
||||
if (padData_[pad].prevVibration.wLeftMotorSpeed != vibration.wLeftMotorSpeed || padData_[pad].prevVibration.wRightMotorSpeed != vibration.wRightMotorSpeed) {
|
||||
PPSSPP_XInputSetState(pad, &vibration);
|
||||
@@ -315,9 +326,19 @@ void XinputDevice::ApplyVibration(int pad, XINPUT_VIBRATION &vibration) {
|
||||
prevVibrationTime_ = newVibrationTime_;
|
||||
}
|
||||
} else {
|
||||
ApplyButtonRumble(pad, vibration);
|
||||
DWORD dwResult = PPSSPP_XInputSetState(pad, &vibration);
|
||||
if (dwResult != ERROR_SUCCESS) {
|
||||
padData_[pad].checkDelayUpdates = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XinputDevice::ApplyButtonRumble(int pad, XINPUT_VIBRATION &vibration) {
|
||||
// Runs the motors flat out for as long as the button is held, overriding whatever
|
||||
// the game asked for - it's an explicit user setting, so it wins.
|
||||
if (g_buttonRumble[pad]) {
|
||||
vibration.wLeftMotorSpeed = 0xFFFF;
|
||||
vibration.wRightMotorSpeed = 0xFFFF;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user