Mac and Linux SDL2 binary snapshots
Edward Rudd
2019-04-09 9cd2e9ec8fc0127393dfce9c0359d500c8c238be
source/src/joystick/windows/SDL_xinputjoystick.c
@@ -26,8 +26,10 @@
#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_windowsjoystick_c.h"
#include "SDL_xinputjoystick_c.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
/*
 * Internal stuff.
@@ -186,6 +188,9 @@
static void
AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
{
    Uint16 vendor = 0;
    Uint16 product = 0;
    Uint16 version = 0;
    JoyStick_DeviceData *pPrevJoystick = NULL;
    JoyStick_DeviceData *pNewJoystick = *pContext;
@@ -229,15 +234,11 @@
    if (SDL_XInputUseOldJoystickMapping()) {
        SDL_zero(pNewJoystick->guid);
    } else {
        const Uint16 BUS_USB = 0x03;
        Uint16 vendor = 0;
        Uint16 product = 0;
        Uint16 version = 0;
        Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data;
        GuessXInputDevice(userid, &vendor, &product, &version);
        *guid16++ = SDL_SwapLE16(BUS_USB);
        *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(vendor);
        *guid16++ = 0;
@@ -253,12 +254,29 @@
    pNewJoystick->SubType = SubType;
    pNewJoystick->XInputUserId = userid;
    if (SDL_ShouldIgnoreGameController(pNewJoystick->joystickname, pNewJoystick->guid)) {
    if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
        SDL_free(pNewJoystick);
        return;
    }
    SDL_SYS_AddJoystickDevice(pNewJoystick);
#ifdef SDL_JOYSTICK_HIDAPI
    if (HIDAPI_IsDevicePresent(vendor, product, version)) {
        /* The HIDAPI driver is taking care of this device */
        SDL_free(pNewJoystick);
        return;
    }
#endif
    WINDOWS_AddJoystickDevice(pNewJoystick);
}
static void
DelXInputDevice(Uint8 userid)
{
    if (s_arrXInputDevicePath[userid]) {
        SDL_free(s_arrXInputDevicePath[userid]);
        s_arrXInputDevicePath[userid] = NULL;
    }
}
void
@@ -276,6 +294,8 @@
        XINPUT_CAPABILITIES capabilities;
        if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
            AddXInputDevice(userid, capabilities.SubType, pContext);
        } else {
            DelXInputDevice(userid);
        }
    }
}
@@ -291,6 +311,8 @@
    SDL_assert(XINPUTGETCAPABILITIES);
    SDL_assert(XINPUTSETSTATE);
    SDL_assert(userId < XUSER_MAX_COUNT);
    joystick->player_index = userId;
    joystick->hwdata->bXInputDevice = SDL_TRUE;
@@ -384,12 +406,12 @@
    Uint8 button;
    Uint8 hat = SDL_HAT_CENTERED;
    SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX);
    SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY)));
    SDL_PrivateJoystickAxis(joystick, 2, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768));
    SDL_PrivateJoystickAxis(joystick, 3, (Sint16)pXInputState->Gamepad.sThumbRX);
    SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY)));
    SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768));
    SDL_PrivateJoystickAxis(joystick, 0, pXInputState->Gamepad.sThumbLX);
    SDL_PrivateJoystickAxis(joystick, 1, ~pXInputState->Gamepad.sThumbLY);
    SDL_PrivateJoystickAxis(joystick, 2, ((int)pXInputState->Gamepad.bLeftTrigger * 257) - 32768);
    SDL_PrivateJoystickAxis(joystick, 3, pXInputState->Gamepad.sThumbRX);
    SDL_PrivateJoystickAxis(joystick, 4, ~pXInputState->Gamepad.sThumbRY);
    SDL_PrivateJoystickAxis(joystick, 5, ((int)pXInputState->Gamepad.bRightTrigger * 257) - 32768);
    for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
        SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
@@ -412,6 +434,29 @@
    UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
}
int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
    XINPUT_VIBRATION XVibration;
    if (!XINPUTSETSTATE) {
        return SDL_Unsupported();
    }
    XVibration.wLeftMotorSpeed = low_frequency_rumble;
    XVibration.wRightMotorSpeed = high_frequency_rumble;
    if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) {
        return SDL_SetError("XInputSetState() failed");
    }
    if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
        joystick->hwdata->rumble_expiration = SDL_GetTicks() + duration_ms;
    } else {
        joystick->hwdata->rumble_expiration = 0;
    }
    return 0;
}
void
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
@@ -424,14 +469,6 @@
    result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
    if (result == ERROR_DEVICE_NOT_CONNECTED) {
        Uint8 userid = joystick->hwdata->userid;
        joystick->hwdata->send_remove_event = SDL_TRUE;
        joystick->hwdata->removed = SDL_TRUE;
        if (s_arrXInputDevicePath[userid]) {
            SDL_free(s_arrXInputDevicePath[userid]);
            s_arrXInputDevicePath[userid] = NULL;
        }
        return;
    }
@@ -449,6 +486,13 @@
        }
        joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
    }
    if (joystick->hwdata->rumble_expiration) {
        Uint32 now = SDL_GetTicks();
        if (SDL_TICKS_PASSED(now, joystick->hwdata->rumble_expiration)) {
            SDL_XINPUT_JoystickRumble(joystick, 0, 0, 0);
        }
    }
}
void
@@ -462,18 +506,6 @@
    if (s_bXInputEnabled) {
        WIN_UnloadXInputDLL();
    }
}
SDL_bool
SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index)
{
    JoyStick_DeviceData *device = SYS_Joystick;
    int index;
    for (index = device_index; index > 0; index--)
        device = device->pNext;
    return device->bXInputDevice;
}
#else /* !SDL_JOYSTICK_XINPUT */
@@ -502,6 +534,12 @@
    return SDL_Unsupported();
}
int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
    return SDL_Unsupported();
}
void
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
{