winebus.sys: Report SDL controller dpad as hatswitch.
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2239aae97f
commit
564e7b4db9
|
@ -92,6 +92,7 @@ MAKE_FUNCPTR(SDL_JoystickGetAxis);
|
|||
MAKE_FUNCPTR(SDL_JoystickGetHat);
|
||||
MAKE_FUNCPTR(SDL_IsGameController);
|
||||
MAKE_FUNCPTR(SDL_GameControllerGetAxis);
|
||||
MAKE_FUNCPTR(SDL_GameControllerGetButton);
|
||||
MAKE_FUNCPTR(SDL_GameControllerName);
|
||||
MAKE_FUNCPTR(SDL_GameControllerOpen);
|
||||
MAKE_FUNCPTR(SDL_GameControllerEventState);
|
||||
|
@ -150,21 +151,21 @@ static const BYTE REPORT_AXIS_TAIL[] = {
|
|||
};
|
||||
#define IDX_ABS_AXIS_COUNT 23
|
||||
|
||||
#define CONTROLLER_NUM_BUTTONS 15
|
||||
#define CONTROLLER_NUM_BUTTONS 11
|
||||
|
||||
static const BYTE CONTROLLER_BUTTONS[] = {
|
||||
0x05, 0x09, /* USAGE_PAGE (Button) */
|
||||
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
|
||||
0x29, CONTROLLER_NUM_BUTTONS, /* USAGE_MAXIMUM (Button 15) */
|
||||
0x29, CONTROLLER_NUM_BUTTONS, /* USAGE_MAXIMUM (Button 11) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x35, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x45, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x95, CONTROLLER_NUM_BUTTONS, /* REPORT_COUNT (15) */
|
||||
0x95, CONTROLLER_NUM_BUTTONS, /* REPORT_COUNT (11) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||
/* padding */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x95, 0x05, /* REPORT_COUNT (5) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
|
||||
};
|
||||
|
@ -199,6 +200,8 @@ static const BYTE CONTROLLER_TRIGGERS [] = {
|
|||
|
||||
#define CONTROLLER_NUM_AXES 6
|
||||
|
||||
#define CONTROLLER_NUM_HATSWITCHES 1
|
||||
|
||||
static const BYTE HAPTIC_RUMBLE[] = {
|
||||
0x06, 0x00, 0xff, /* USAGE PAGE (vendor-defined) */
|
||||
0x09, 0x01, /* USAGE (1) */
|
||||
|
@ -496,6 +499,33 @@ static BOOL build_report_descriptor(struct platform_private *ext)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static SHORT compose_dpad_value(SDL_GameController *joystick)
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP))
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHTUP;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFTUP;
|
||||
return SDL_HAT_UP;
|
||||
}
|
||||
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN))
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHTDOWN;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFTDOWN;
|
||||
return SDL_HAT_DOWN;
|
||||
}
|
||||
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHT;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFT;
|
||||
return SDL_HAT_CENTERED;
|
||||
}
|
||||
|
||||
static BOOL build_mapped_report_descriptor(struct platform_private *ext)
|
||||
{
|
||||
BYTE *report_ptr;
|
||||
|
@ -505,12 +535,14 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
|
|||
descript_size += sizeof(CONTROLLER_AXIS);
|
||||
descript_size += sizeof(CONTROLLER_TRIGGERS);
|
||||
descript_size += sizeof(CONTROLLER_BUTTONS);
|
||||
descript_size += sizeof(REPORT_HATSWITCH);
|
||||
descript_size += test_haptic(ext);
|
||||
|
||||
ext->axis_start = 0;
|
||||
ext->button_start = CONTROLLER_NUM_AXES * sizeof(WORD);
|
||||
ext->hat_start = ext->button_start + (CONTROLLER_NUM_BUTTONS + 7) / 8;
|
||||
|
||||
ext->buffer_length = (CONTROLLER_NUM_BUTTONS + 7) / 8 + CONTROLLER_NUM_AXES * sizeof(WORD);
|
||||
ext->buffer_length = (CONTROLLER_NUM_BUTTONS + 7) / 8 + CONTROLLER_NUM_AXES * sizeof(WORD) + CONTROLLER_NUM_HATSWITCHES;
|
||||
|
||||
TRACE("Report Descriptor will be %i bytes\n", descript_size);
|
||||
TRACE("Report will be %i bytes\n", ext->buffer_length);
|
||||
|
@ -533,6 +565,7 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
|
|||
report_ptr += sizeof(CONTROLLER_TRIGGERS);
|
||||
memcpy(report_ptr, CONTROLLER_BUTTONS, sizeof(CONTROLLER_BUTTONS));
|
||||
report_ptr += sizeof(CONTROLLER_BUTTONS);
|
||||
report_ptr = add_hatswitch(report_ptr, 1);
|
||||
report_ptr += build_haptic(ext, report_ptr);
|
||||
memcpy(report_ptr, REPORT_TAIL, sizeof(REPORT_TAIL));
|
||||
|
||||
|
@ -549,6 +582,8 @@ static BOOL build_mapped_report_descriptor(struct platform_private *ext)
|
|||
for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++)
|
||||
set_axis_value(ext, i, pSDL_GameControllerGetAxis(ext->sdl_controller, i));
|
||||
|
||||
set_hat_value(ext, 0, compose_dpad_value(ext->sdl_controller));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -778,10 +813,15 @@ static BOOL set_mapped_report_from_event(SDL_Event *event)
|
|||
case SDL_CONTROLLER_BUTTON_START: usage = 8; break;
|
||||
case SDL_CONTROLLER_BUTTON_BACK: usage = 9; break;
|
||||
case SDL_CONTROLLER_BUTTON_GUIDE: usage = 10; break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP: usage = 11; break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: usage = 12; break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: usage = 13; break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: usage = 14; break;
|
||||
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||
set_hat_value(private, 0, compose_dpad_value(private->sdl_controller));
|
||||
process_hid_report(device, private->report_buffer, private->buffer_length);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR("Unknown Button %i\n",ie->button);
|
||||
}
|
||||
|
@ -1040,6 +1080,7 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
|
|||
LOAD_FUNCPTR(SDL_JoystickGetHat);
|
||||
LOAD_FUNCPTR(SDL_IsGameController);
|
||||
LOAD_FUNCPTR(SDL_GameControllerGetAxis);
|
||||
LOAD_FUNCPTR(SDL_GameControllerGetButton);
|
||||
LOAD_FUNCPTR(SDL_GameControllerName);
|
||||
LOAD_FUNCPTR(SDL_GameControllerOpen);
|
||||
LOAD_FUNCPTR(SDL_GameControllerEventState);
|
||||
|
|
|
@ -124,8 +124,8 @@ static BOOL VerifyGamepad(PHIDP_PREPARSED_DATA ppd, XINPUT_CAPABILITIES *xinput_
|
|||
button_count = max(button_count, button_caps[i].NotRange.Usage);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, button_caps);
|
||||
if (button_count < 14)
|
||||
WARN("Too few buttons, Continue\n");
|
||||
if (button_count < 11)
|
||||
WARN("Too few buttons, continuing anyway\n");
|
||||
xinput_caps->Gamepad.wButtons = 0xffff;
|
||||
|
||||
value_caps_count = caps->NumberInputValueCaps;
|
||||
|
@ -335,8 +335,8 @@ void HID_update_state(xinput_controller* device)
|
|||
CHAR *report = private->reports[(private->current_report)%2];
|
||||
CHAR *target_report = private->reports[(private->current_report+1)%2];
|
||||
|
||||
USAGE buttons[15];
|
||||
ULONG button_length;
|
||||
USAGE buttons[11];
|
||||
ULONG button_length, hat_value;
|
||||
LONG value;
|
||||
|
||||
if (!private->enabled)
|
||||
|
@ -361,7 +361,7 @@ void HID_update_state(xinput_controller* device)
|
|||
private->current_report = (private->current_report+1)%2;
|
||||
|
||||
device->state.dwPacketNumber++;
|
||||
button_length = 15;
|
||||
button_length = ARRAY_SIZE(buttons);
|
||||
HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, buttons, &button_length, private->ppd, target_report, private->report_length);
|
||||
|
||||
device->state.Gamepad.wButtons = 0;
|
||||
|
@ -381,10 +381,42 @@ void HID_update_state(xinput_controller* device)
|
|||
case 9: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_START; break;
|
||||
case 10: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_BACK; break;
|
||||
case 11: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_GUIDE; break;
|
||||
case 12: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP; break;
|
||||
case 13: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN; break;
|
||||
case 14: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT; break;
|
||||
case 15: device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT; break;
|
||||
}
|
||||
}
|
||||
|
||||
if(HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, 0, HID_USAGE_GENERIC_HATSWITCH, &hat_value,
|
||||
private->ppd, target_report, private->report_length) == HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
switch(hat_value){
|
||||
/* 8 1 2
|
||||
* 7 0 3
|
||||
* 6 5 4 */
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP;
|
||||
break;
|
||||
case 2:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_RIGHT;
|
||||
break;
|
||||
case 3:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
|
||||
break;
|
||||
case 4:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_DPAD_DOWN;
|
||||
break;
|
||||
case 5:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
|
||||
break;
|
||||
case 6:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT;
|
||||
break;
|
||||
case 7:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
|
||||
break;
|
||||
case 8:
|
||||
device->state.Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_UP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue