xinput: bind UI, vibration, hotplug (#620)

## Link to GitHub Issue or related Pull Request, if one exists
#616 

## Description of change
`Naive` button is now called `Naive/XInput` and detects XInput
controllers

Add vibration output as "Lights"

Add proper hotplug support and multiple controllers

Fix misc bugs on x86

## Testing
I tested with two xbox controllers.
This commit is contained in:
bicarus
2026-04-10 01:04:20 -07:00
committed by GitHub
parent ca70f7b19c
commit a159691097
11 changed files with 275 additions and 68 deletions
+22 -6
View File
@@ -11,7 +11,7 @@ namespace xinput {
#define XUSER_MAX_COUNT 4
typedef struct _XINPUT_GAMEPAD_STATE {
struct XINPUT_GAMEPAD_STATE {
uint16_t wButtons;
uint8_t bLeftTrigger;
uint8_t bRightTrigger;
@@ -19,9 +19,9 @@ namespace xinput {
int16_t sThumbLY;
int16_t sThumbRX;
int16_t sThumbRY;
} XINPUT_GAMEPAD_STATE;
};
typedef struct _XINPUT_GAMEPAD_STATE_NORMALIZED {
struct XINPUT_GAMEPAD_STATE_NORMALIZED {
uint16_t wButtons;
float bLeftTrigger;
float bRightTrigger;
@@ -29,9 +29,9 @@ namespace xinput {
float sThumbLY;
float sThumbRX;
float sThumbRY;
} XINPUT_GAMEPAD_STATE_NORMALIZED;
};
enum class XInputButtonEnum {
enum class XInputButtonEnum : uint16_t {
// actual buttons
DPAD_UP,
DPAD_DOWN,
@@ -75,14 +75,28 @@ namespace xinput {
COUNT
};
enum class XInputOutputEnum : uint16_t {
LEFT_RUMBLE,
RIGHT_RUMBLE,
COUNT
};
struct XINPUT_NEW_BUTTON {
uint8_t player;
XInputButtonEnum button;
};
std::string get_button_string(XInputButtonEnum button);
std::string get_analog_string(XInputAnalogEnum analog);
std::string get_output_string(XInputOutputEnum output);
std::string get_device_desc(uint8_t player);
class XInputManager {
private:
bool initialized = false;
HMODULE xinput_lib = nullptr;
void get_state(uint8_t player, XINPUT_GAMEPAD_STATE_NORMALIZED *state);
void get_state(uint8_t player, XINPUT_GAMEPAD_STATE_NORMALIZED &state);
public:
XInputManager();
~XInputManager();
@@ -90,5 +104,7 @@ namespace xinput {
std::vector<uint8_t> get_available_players();
bool is_button_pressed(uint8_t player, XInputButtonEnum button);
float get_analog_state(uint8_t player, XInputAnalogEnum analog);
bool get_any_button_pressed(XINPUT_NEW_BUTTON &button);
void set_output_state(uint8_t player, XInputOutputEnum output, float value);
};
}