mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-05 01:16:26 +00:00
Report the D-Pad for HIDAPI gamepads as a hat
This makes it easier for games that don't use the gamepad API to handle D-Pad navigation, and is consistent with many other non-HIDAPI mappings. Fixes https://github.com/libsdl-org/SDL/issues/8754
This commit is contained in:
@@ -63,6 +63,16 @@
|
||||
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
|
||||
#define SWITCH_ACCEL_SCALE_MULT 4.0f
|
||||
|
||||
enum
|
||||
{
|
||||
SDL_GAMEPAD_BUTTON_SWITCH_SHARE = 11,
|
||||
SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE1,
|
||||
SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE1,
|
||||
SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE2,
|
||||
SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE2,
|
||||
SDL_GAMEPAD_NUM_SWITCH_BUTTONS,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
k_eSwitchInputReportIDs_SubcommandReply = 0x21,
|
||||
@@ -1433,8 +1443,9 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
|
||||
SDL_PlayerLEDHintChanged, ctx);
|
||||
|
||||
/* Initialize the joystick capabilities */
|
||||
joystick->nbuttons = 20;
|
||||
joystick->nbuttons = SDL_GAMEPAD_NUM_SWITCH_BUTTONS;
|
||||
joystick->naxes = SDL_GAMEPAD_AXIS_MAX;
|
||||
joystick->nhats = 1;
|
||||
joystick->epowerlevel = device->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED;
|
||||
|
||||
/* Set up for input */
|
||||
@@ -1671,51 +1682,42 @@ static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwi
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_SHARE, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (packet->ucStickHat != ctx->m_lastInputOnlyState.ucStickHat) {
|
||||
SDL_bool dpad_up = SDL_FALSE;
|
||||
SDL_bool dpad_down = SDL_FALSE;
|
||||
SDL_bool dpad_left = SDL_FALSE;
|
||||
SDL_bool dpad_right = SDL_FALSE;
|
||||
Uint8 hat;
|
||||
|
||||
switch (packet->ucStickHat) {
|
||||
case 0:
|
||||
dpad_up = SDL_TRUE;
|
||||
hat = SDL_HAT_UP;
|
||||
break;
|
||||
case 1:
|
||||
dpad_up = SDL_TRUE;
|
||||
dpad_right = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHTUP;
|
||||
break;
|
||||
case 2:
|
||||
dpad_right = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHT;
|
||||
break;
|
||||
case 3:
|
||||
dpad_right = SDL_TRUE;
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHTDOWN;
|
||||
break;
|
||||
case 4:
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_DOWN;
|
||||
break;
|
||||
case 5:
|
||||
dpad_left = SDL_TRUE;
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFTDOWN;
|
||||
break;
|
||||
case 6:
|
||||
dpad_left = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFT;
|
||||
break;
|
||||
case 7:
|
||||
dpad_up = SDL_TRUE;
|
||||
dpad_left = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFTUP;
|
||||
break;
|
||||
default:
|
||||
hat = SDL_HAT_CENTERED;
|
||||
break;
|
||||
}
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, dpad_down);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, dpad_up);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, dpad_right);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, dpad_left);
|
||||
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
|
||||
}
|
||||
|
||||
if (packet->rgucJoystickLeft[0] != ctx->m_lastInputOnlyState.rgucJoystickLeft[0]) {
|
||||
@@ -1769,51 +1771,42 @@ static void HandleSimpleControllerState(SDL_Joystick *joystick, SDL_DriverSwitch
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_STICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_SHARE, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (packet->ucStickHat != ctx->m_lastSimpleState.ucStickHat) {
|
||||
SDL_bool dpad_up = SDL_FALSE;
|
||||
SDL_bool dpad_down = SDL_FALSE;
|
||||
SDL_bool dpad_left = SDL_FALSE;
|
||||
SDL_bool dpad_right = SDL_FALSE;
|
||||
Uint8 hat;
|
||||
|
||||
switch (packet->ucStickHat) {
|
||||
case 0:
|
||||
dpad_up = SDL_TRUE;
|
||||
hat = SDL_HAT_UP;
|
||||
break;
|
||||
case 1:
|
||||
dpad_up = SDL_TRUE;
|
||||
dpad_right = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHTUP;
|
||||
break;
|
||||
case 2:
|
||||
dpad_right = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHT;
|
||||
break;
|
||||
case 3:
|
||||
dpad_right = SDL_TRUE;
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_RIGHTDOWN;
|
||||
break;
|
||||
case 4:
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_DOWN;
|
||||
break;
|
||||
case 5:
|
||||
dpad_left = SDL_TRUE;
|
||||
dpad_down = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFTDOWN;
|
||||
break;
|
||||
case 6:
|
||||
dpad_left = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFT;
|
||||
break;
|
||||
case 7:
|
||||
dpad_up = SDL_TRUE;
|
||||
dpad_left = SDL_TRUE;
|
||||
hat = SDL_HAT_LEFTUP;
|
||||
break;
|
||||
default:
|
||||
hat = SDL_HAT_CENTERED;
|
||||
break;
|
||||
}
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, dpad_down);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, dpad_up);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, dpad_right);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, dpad_left);
|
||||
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
|
||||
}
|
||||
|
||||
axis = ApplySimpleStickCalibration(ctx, 0, 0, packet->sJoystickLeft[0]);
|
||||
@@ -1882,17 +1875,29 @@ static void HandleCombinedControllerStateL(Uint64 timestamp, SDL_Joystick *joyst
|
||||
Uint8 data = packet->controllerState.rgucButtons[1];
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_BACK, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_SHARE, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) {
|
||||
Uint8 data = packet->controllerState.rgucButtons[2];
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
Uint8 hat = 0;
|
||||
|
||||
if (data & 0x01) {
|
||||
hat |= SDL_HAT_DOWN;
|
||||
}
|
||||
if (data & 0x02) {
|
||||
hat |= SDL_HAT_UP;
|
||||
}
|
||||
if (data & 0x04) {
|
||||
hat |= SDL_HAT_RIGHT;
|
||||
}
|
||||
if (data & 0x08) {
|
||||
hat |= SDL_HAT_LEFT;
|
||||
}
|
||||
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
|
||||
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE2, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
axis = (data & 0x80) ? 32767 : -32768;
|
||||
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
|
||||
@@ -1926,8 +1931,8 @@ static void HandleMiniControllerStateL(Uint64 timestamp, SDL_Joystick *joystick,
|
||||
SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_NORTH), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_LEFT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8);
|
||||
@@ -1949,8 +1954,8 @@ static void HandleCombinedControllerStateR(Uint64 timestamp, SDL_Joystick *joyst
|
||||
SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_EAST), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_WEST), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_NORTH), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
axis = (data & 0x80) ? 32767 : -32768;
|
||||
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis);
|
||||
@@ -1984,8 +1989,8 @@ static void HandleMiniControllerStateR(Uint64 timestamp, SDL_Joystick *joystick,
|
||||
SDL_SendJoystickButton(timestamp, joystick, RemapButton(ctx, SDL_GAMEPAD_BUTTON_NORTH), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_RIGHT_PADDLE2, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) {
|
||||
@@ -2042,15 +2047,27 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_STICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SWITCH_SHARE, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) {
|
||||
Uint8 data = packet->controllerState.rgucButtons[2];
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_DOWN, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
Uint8 hat = 0;
|
||||
|
||||
if (data & 0x01) {
|
||||
hat |= SDL_HAT_DOWN;
|
||||
}
|
||||
if (data & 0x02) {
|
||||
hat |= SDL_HAT_UP;
|
||||
}
|
||||
if (data & 0x04) {
|
||||
hat |= SDL_HAT_RIGHT;
|
||||
}
|
||||
if (data & 0x08) {
|
||||
hat |= SDL_HAT_LEFT;
|
||||
}
|
||||
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
|
||||
|
||||
SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
axis = (data & 0x80) ? 32767 : -32768;
|
||||
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis);
|
||||
|
Reference in New Issue
Block a user