Files
ppsspp/Windows/Hid/HidInputDevice.h
T
Henrik RydgårdandClaude Opus 5.5 3f1b40b54d Windows HID input: Fix stuck keys on disconnect, don't treat odd reports as disconnects
ReleaseAllKeys released on the XInput device IDs while input arrives on PAD
IDs, so whatever was held at a disconnect stayed held. Short reads and
report types we don't parse made the pad "disconnect" for several seconds,
and a simple DualSense BT report zeroed the state (pressing DPAD up, since
hat 0 is up). These now keep the previous state.

With HID input turned off we no longer open and block reading the device on
the shared input thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:56:32 +02:00

77 lines
1.8 KiB
C++

// This file in particular along with its cpp file is public domain, use it for whatever you want.
// Internal common header for Hid input stuff.
#pragma once
#include <set>
#include <unordered_set>
#include "Common/CommonTypes.h"
#include "Common/Input/InputState.h"
#include "Windows/InputDevice.h"
#include "Common/CommonWindows.h"
enum class HIDControllerType {
DualShock,
DualSense,
SwitchPro,
};
struct HIDControllerState {
// Analog sticks
s8 stickAxes[4]; // LX LY RX RY
// Analog triggers
u8 triggerAxes[2];
// Buttons. Here the mapping is specific to the controller type and resolved
// later.
u32 buttons; // Bitmask, PSButton enum
bool accValid = false;
bool gyroValid = false;
float accelerometer[3]; // X, Y, Z
float gyro[3];
};
struct ButtonInputMapping {
u32 button;
InputKeyCode keyCode;
};
// Supports a few specific HID input devices, namely DualShock and DualSense.
// More may be added later. Just picks the first one available, for now.
class HidInputDevice : public InputDevice {
public:
void Init() override;
int UpdateState() override;
void Shutdown() override;
static void AddSupportedDevices(std::set<u32> *deviceVIDPIDs);
bool HasAccelerometer() const override {
switch (subType_) {
case HIDControllerType::DualSense:
case HIDControllerType::SwitchPro:
return true;
default:
break;
}
return false;
}
private:
void ReleaseAllKeys(const ButtonInputMapping *buttonMappings, int count);
void Disconnect();
InputDeviceID DeviceID(int pad);
HIDControllerState prevState_{};
HIDControllerType subType_{};
HANDLE controller_ = nullptr;
std::string name_;
std::unordered_set<std::wstring> ignoreHidDevicePaths_;
int pad_ = 0;
int pollCount_ = 0;
int inReportSize_ = 0;
int outReportSize_ = 0;
enum {
POLL_FREQ = 709, // a prime number.
};
};