diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 29d2b059e..e0fce669f 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -281,6 +281,16 @@ extern "C" { #define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + + /** * \brief A variable that lets you manually hint extra gamecontroller db entries * diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index c324043ca..950cb3601 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -261,7 +261,7 @@ ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *gu ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) { #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) - if (SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping) { + if (SDL_SYS_IsXInputGamepad_DeviceIndex(device_index) && s_pXInputMapping) { return s_pXInputMapping; } else diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index b9527ffba..161594f92 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -41,9 +41,9 @@ static const char *s_ControllerMappings [] = "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,", "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", + "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #elif defined(SDL_JOYSTICK_XINPUT) - "xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", + "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #elif defined(__MACOSX__) "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index ac71587a8..2a60c0036 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -113,9 +113,8 @@ SDL_JoystickOpen(int device_index) /* If the joystick is already open, return it * it is important that we have a single joystick * for each instance id */ - while ( joysticklist ) - { - if ( SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == joysticklist->instance_id ) { + while (joysticklist) { + if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == joysticklist->instance_id) { joystick = joysticklist; ++joystick->ref_count; return (joystick); @@ -136,9 +135,9 @@ SDL_JoystickOpen(int device_index) return NULL; } - joystickname = SDL_SYS_JoystickNameForDeviceIndex( device_index ); - if ( joystickname ) - joystick->name = SDL_strdup( joystickname ); + joystickname = SDL_SYS_JoystickNameForDeviceIndex(device_index); + if (joystickname) + joystick->name = SDL_strdup(joystickname); else joystick->name = NULL; @@ -186,7 +185,7 @@ SDL_JoystickOpen(int device_index) joystick->next = SDL_joysticks; SDL_joysticks = joystick; - SDL_SYS_JoystickUpdate( joystick ); + SDL_SYS_JoystickUpdate(joystick); return (joystick); } @@ -200,15 +199,14 @@ SDL_PrivateJoystickValid(SDL_Joystick * joystick) { int valid; - if ( joystick == NULL ) { + if (joystick == NULL) { SDL_SetError("Joystick hasn't been opened yet"); valid = 0; } else { valid = 1; } - if ( joystick && joystick->closed ) - { + if (joystick && joystick->closed) { valid = 0; } @@ -417,20 +415,14 @@ SDL_JoystickClose(SDL_Joystick * joystick) joysticklist = SDL_joysticks; joysticklistprev = NULL; - while ( joysticklist ) - { - if (joystick == joysticklist) - { - if ( joysticklistprev ) - { + while (joysticklist) { + if (joystick == joysticklist) { + if (joysticklistprev) { /* unlink this entry */ joysticklistprev->next = joysticklist->next; - } - else - { + } else { SDL_joysticks = joystick->next; } - break; } joysticklistprev = joysticklist; @@ -454,8 +446,7 @@ SDL_JoystickQuit(void) SDL_assert(!SDL_updating_joystick); /* Stop the event polling */ - while ( SDL_joysticks ) - { + while (SDL_joysticks) { SDL_joysticks->ref_count = 1; SDL_JoystickClose(SDL_joysticks); } @@ -472,8 +463,7 @@ SDL_JoystickQuit(void) static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent() { - if (SDL_joystick_allows_background_events) - { + if (SDL_joystick_allows_background_events) { return SDL_FALSE; } @@ -497,10 +487,13 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) { int posted; - /* Make sure we're not getting garbage events */ + /* Make sure we're not getting garbage or duplicate events */ if (axis >= joystick->naxes) { return 0; } + if (value == joystick->axes[axis]) { + return 0; + } /* We ignore events if we don't have keyboard focus, except for centering * events. @@ -513,9 +506,6 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) } /* Update internal joystick state */ - if (value == joystick->axes[axis]) { - return 0; - } joystick->axes[axis] = value; /* Post the event, if desired */ @@ -538,10 +528,13 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) { int posted; - /* Make sure we're not getting garbage events */ + /* Make sure we're not getting garbage or duplicate events */ if (hat >= joystick->nhats) { return 0; } + if (value == joystick->hats[hat]) { + return 0; + } /* We ignore events if we don't have keyboard focus, except for centering * events. @@ -553,9 +546,6 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) } /* Update internal joystick state */ - if (value == joystick->hats[hat]) { - return 0; - } joystick->hats[hat] = value; /* Post the event, if desired */ @@ -629,10 +619,13 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) } #endif /* !SDL_EVENTS_DISABLED */ - /* Make sure we're not getting garbage events */ + /* Make sure we're not getting garbage or duplicate events */ if (button >= joystick->nbuttons) { return 0; - } + } + if (state == joystick->buttons[button]) { + return 0; + } /* We ignore events if we don't have keyboard focus, except for button * release. */ @@ -643,9 +636,6 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) } /* Update internal joystick state */ - if (state == joystick->buttons[button]) { - return 0; - } joystick->buttons[button] = state; /* Post the event, if desired */ @@ -667,8 +657,7 @@ SDL_JoystickUpdate(void) SDL_Joystick *joystick; joystick = SDL_joysticks; - while ( joystick ) - { + while (joystick) { SDL_Joystick *joysticknext; /* save off the next pointer, the Update call may cause a joystick removed event * and cause our joystick pointer to be freed @@ -677,10 +666,9 @@ SDL_JoystickUpdate(void) SDL_updating_joystick = joystick; - SDL_SYS_JoystickUpdate( joystick ); + SDL_SYS_JoystickUpdate(joystick); - if ( joystick->closed && joystick->uncentered ) - { + if (joystick->closed && joystick->uncentered) { int i; /* Tell the app that everything is centered/unpressed... */ @@ -693,13 +681,13 @@ SDL_JoystickUpdate(void) for (i = 0; i < joystick->nhats; i++) SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); - joystick->uncentered = 0; + joystick->uncentered = SDL_FALSE; } SDL_updating_joystick = NULL; /* If the joystick was closed while updating, free it here */ - if ( joystick->ref_count <= 0 ) { + if (joystick->ref_count <= 0) { SDL_JoystickClose(joystick); } @@ -750,10 +738,10 @@ SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index) if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { SDL_JoystickGUID emptyGUID; SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); - SDL_zero( emptyGUID ); + SDL_zero(emptyGUID); return emptyGUID; } - return SDL_SYS_JoystickGetDeviceGUID( device_index ); + return SDL_SYS_JoystickGetDeviceGUID(device_index); } /* return the guid for this opened device */ @@ -761,14 +749,14 @@ SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick * joystick) { if (!SDL_PrivateJoystickValid(joystick)) { SDL_JoystickGUID emptyGUID; - SDL_zero( emptyGUID ); + SDL_zero(emptyGUID); return emptyGUID; } - return SDL_SYS_JoystickGetGUID( joystick ); + return SDL_SYS_JoystickGetGUID(joystick); } /* convert the guid to a printable string */ -void SDL_JoystickGetGUIDString( SDL_JoystickGUID guid, char *pszGUID, int cbGUID ) +void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID) { static const char k_rgchHexToASCII[] = "0123456789abcdef"; int i; @@ -777,14 +765,13 @@ void SDL_JoystickGetGUIDString( SDL_JoystickGUID guid, char *pszGUID, int cbGUID return; } - for ( i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++ ) - { + for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) { /* each input byte writes 2 ascii chars, and might write a null byte. */ /* If we don't have room for next input byte, stop */ unsigned char c = guid.data[i]; - *pszGUID++ = k_rgchHexToASCII[ c >> 4 ]; - *pszGUID++ = k_rgchHexToASCII[ c & 0x0F ]; + *pszGUID++ = k_rgchHexToASCII[c >> 4]; + *pszGUID++ = k_rgchHexToASCII[c & 0x0F]; } *pszGUID = '\0'; } @@ -795,28 +782,22 @@ void SDL_JoystickGetGUIDString( SDL_JoystickGUID guid, char *pszGUID, int cbGUID * Input : c - * Output : unsigned char *-----------------------------------------------------------------------------*/ -static unsigned char nibble( char c ) +static unsigned char nibble(char c) { - if ( ( c >= '0' ) && - ( c <= '9' ) ) - { + if ((c >= '0') && (c <= '9')) { return (unsigned char)(c - '0'); } - if ( ( c >= 'A' ) && - ( c <= 'F' ) ) - { + if ((c >= 'A') && (c <= 'F')) { return (unsigned char)(c - 'A' + 0x0a); } - if ( ( c >= 'a' ) && - ( c <= 'f' ) ) - { + if ((c >= 'a') && (c <= 'f')) { return (unsigned char)(c - 'a' + 0x0a); } /* received an invalid character, and no real way to return an error */ - /* AssertMsg1( false, "Q_nibble invalid hex character '%c' ", c ); */ + /* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */ return 0; } @@ -826,21 +807,18 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) { SDL_JoystickGUID guid; int maxoutputbytes= sizeof(guid); - size_t len = SDL_strlen( pchGUID ); + size_t len = SDL_strlen(pchGUID); Uint8 *p; size_t i; /* Make sure it's even */ - len = ( len ) & ~0x1; + len = (len) & ~0x1; - SDL_memset( &guid, 0x00, sizeof(guid) ); + SDL_memset(&guid, 0x00, sizeof(guid)); p = (Uint8 *)&guid; - for ( i = 0; - ( i < len ) && ( ( p - (Uint8 *)&guid ) < maxoutputbytes ); - i+=2, p++ ) - { - *p = ( nibble( pchGUID[i] ) << 4 ) | nibble( pchGUID[i+1] ); + for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) { + *p = (nibble(pchGUID[i]) << 4) | nibble(pchGUID[i+1]); } return guid; diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index a5218d507..d5ef3a529 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -50,8 +50,8 @@ struct _SDL_Joystick int ref_count; /* Reference count for multiple opens */ - Uint8 closed; /* 1 if this device is no longer valid */ - Uint8 uncentered; /* 1 if this device needs to have its state reset to 0 */ + SDL_bool closed; /* SDL_TRUE if this device is no longer valid */ + SDL_bool uncentered; /* SDL_TRUE if this device needs to have its state reset to 0 */ struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */ }; @@ -106,9 +106,8 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index); extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick); #if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) -/* Function to get the current instance id of the joystick located at device_index */ -extern SDL_bool SDL_SYS_IsXInputDeviceIndex( int device_index ); -extern SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick); +/* Function returns SDL_TRUE if this device is an XInput gamepad */ +extern SDL_bool SDL_SYS_IsXInputGamepad_DeviceIndex( int device_index ); #endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/windows/SDL_dxjoystick.c b/src/joystick/windows/SDL_dxjoystick.c index ff8a215e5..e8a4f3bec 100644 --- a/src/joystick/windows/SDL_dxjoystick.c +++ b/src/joystick/windows/SDL_dxjoystick.c @@ -102,13 +102,13 @@ WIN_LoadXInputDLL(void) } version = (1 << 16) | 4; - s_pXInputDLL = LoadLibrary( L"XInput1_4.dll" ); /* 1.4 Ships with Windows 8. */ + s_pXInputDLL = LoadLibrary(L"XInput1_4.dll"); /* 1.4 Ships with Windows 8. */ if (!s_pXInputDLL) { version = (1 << 16) | 3; - s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" ); /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */ + s_pXInputDLL = LoadLibrary(L"XInput1_3.dll"); /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */ } if (!s_pXInputDLL) { - s_pXInputDLL = LoadLibrary( L"bin\\XInput1_3.dll" ); + s_pXInputDLL = LoadLibrary(L"bin\\XInput1_3.dll"); } if (!s_pXInputDLL) { return -1; @@ -119,10 +119,10 @@ WIN_LoadXInputDLL(void) s_XInputDLLRefCount = 1; /* 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... */ - SDL_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, (LPCSTR)100 ); - SDL_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputSetState" ); - SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetCapabilities" ); - if ( !SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities ) { + SDL_XInputGetState = (XInputGetState_t)GetProcAddress((HMODULE)s_pXInputDLL, (LPCSTR)100); + SDL_XInputSetState = (XInputSetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputSetState"); + SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetCapabilities"); + if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) { WIN_UnloadXInputDLL(); return -1; } @@ -133,10 +133,10 @@ WIN_LoadXInputDLL(void) void WIN_UnloadXInputDLL(void) { - if ( s_pXInputDLL ) { + if (s_pXInputDLL) { SDL_assert(s_XInputDLLRefCount > 0); if (--s_XInputDLLRefCount == 0) { - FreeLibrary( s_pXInputDLL ); + FreeLibrary(s_pXInputDLL); s_pXInputDLL = NULL; } } else { @@ -156,6 +156,7 @@ struct JoyStick_DeviceData_ Uint8 send_add_event; SDL_JoystickID nInstanceID; SDL_bool bXInputDevice; + BYTE SubType; Uint8 XInputUserId; struct JoyStick_DeviceData_ *pNext; }; @@ -172,12 +173,6 @@ static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef); static void SortDevObjects(SDL_Joystick *joystick); static Uint8 TranslatePOV(DWORD value); -static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, - Sint16 value); -static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, - Uint8 value); -static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, - Uint8 button, Uint8 state); /* Taken from Wine - Thanks! */ DIOBJECTDATAFORMAT dfDIJoystick2[] = { @@ -377,15 +372,26 @@ SetDIerror(const char *function, HRESULT code) } \ } -DEFINE_GUID(IID_ValveStreamingGamepad, MAKELONG( 0x28DE, 0x11FF ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); -DEFINE_GUID(IID_X360WiredGamepad, MAKELONG( 0x045E, 0x02A1 ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); -DEFINE_GUID(IID_X360WirelessGamepad, MAKELONG( 0x045E, 0x028E ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); +DEFINE_GUID(IID_ValveStreamingGamepad, MAKELONG(0x28DE, 0x11FF),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); +DEFINE_GUID(IID_X360WiredGamepad, MAKELONG(0x045E, 0x02A1),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); +DEFINE_GUID(IID_X360WirelessGamepad, MAKELONG(0x045E, 0x028E),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44); static PRAWINPUTDEVICELIST SDL_RawDevList = NULL; static UINT SDL_RawDevListCount = 0; static SDL_bool -SDL_IsXInputDevice( const GUID* pGuidProductFromDirectInput ) +SDL_XInputUseOldJoystickMapping() +{ + static int s_XInputUseOldJoystickMapping = -1; + if (s_XInputUseOldJoystickMapping < 0) { + const char *hint = SDL_GetHint(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING); + s_XInputUseOldJoystickMapping = (hint && *hint == '1') ? 1 : 0; + } + return (s_XInputUseOldJoystickMapping > 0); +} + +static SDL_bool +SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput) { static const GUID *s_XInputProductGUID[] = { &IID_ValveStreamingGamepad, @@ -402,7 +408,7 @@ SDL_IsXInputDevice( const GUID* pGuidProductFromDirectInput ) /* Check for well known XInput device GUIDs */ /* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */ - for ( iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice ) { + for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) { if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) { return SDL_TRUE; } @@ -435,11 +441,11 @@ SDL_IsXInputDevice( const GUID* pGuidProductFromDirectInput ) UINT nameSize = SDL_arraysize(devName); rdi.cbSize = sizeof (rdi); - if ( (SDL_RawDevList[i].dwType == RIM_TYPEHID) && + if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) && (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) && (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) && (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) && - (SDL_strstr(devName, "IG_") != NULL) ) { + (SDL_strstr(devName, "IG_") != NULL)) { return SDL_TRUE; } } @@ -452,17 +458,18 @@ static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE; /* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */ -LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { +LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { case WM_DEVICECHANGE: switch (wParam) { case DBT_DEVICEARRIVAL: - if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { s_bWindowsDeviceChanged = SDL_TRUE; } break; case DBT_DEVICEREMOVECOMPLETE: - if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { s_bWindowsDeviceChanged = SDL_TRUE; } break; @@ -492,20 +499,18 @@ SDL_JoystickThread(void *_data) WIN_CoInitialize(); - SDL_memset( &wincl, 0x0, sizeof(wincl) ); - wincl.hInstance = GetModuleHandle( NULL ); + SDL_memset(&wincl, 0x0, sizeof(wincl)); + wincl.hInstance = GetModuleHandle(NULL); wincl.lpszClassName = L"Message"; wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */ wincl.cbSize = sizeof (WNDCLASSEX); - if (!RegisterClassEx (&wincl)) - { - return WIN_SetError( "Failed to create register class for joystick autodetect"); + if (!RegisterClassEx (&wincl)) { + return WIN_SetError("Failed to create register class for joystick autodetect"); } - messageWindow = (HWND)CreateWindowEx( 0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); - if ( !messageWindow ) - { + messageWindow = (HWND)CreateWindowEx(0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + if (!messageWindow) { return WIN_SetError("Failed to create message window for joystick autodetect"); } @@ -515,34 +520,31 @@ SDL_JoystickThread(void *_data) dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; dbh.dbcc_classguid = GUID_DEVINTERFACE_HID; - hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); - if ( !hNotify ) - { - return WIN_SetError( "Failed to create notify device for joystick autodetect"); + hNotify = RegisterDeviceNotification(messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE); + if (!hNotify) { + return WIN_SetError("Failed to create notify device for joystick autodetect"); } - SDL_LockMutex( s_mutexJoyStickEnum ); - while ( s_bJoystickThreadQuit == SDL_FALSE ) - { + SDL_LockMutex(s_mutexJoyStickEnum); + while (s_bJoystickThreadQuit == SDL_FALSE) { MSG messages; SDL_bool bXInputChanged = SDL_FALSE; - SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 ); + SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 300); - while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) ) - { - if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) { + while (s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE)) { + if (GetMessage(&messages, messageWindow, 0, 0) != 0) { TranslateMessage(&messages); DispatchMessage(&messages); } } - if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) { + if (s_bXInputEnabled && XINPUTGETCAPABILITIES) { /* scan for any change in XInput devices */ Uint8 userId; for (userId = 0; userId < SDL_XINPUT_MAX_DEVICES; userId++) { XINPUT_CAPABILITIES capabilities; - const DWORD result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); + const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities); const SDL_bool available = (result == ERROR_SUCCESS); if (bOpenedXInputDevices[userId] != available) { bXInputChanged = SDL_TRUE; @@ -552,24 +554,24 @@ SDL_JoystickThread(void *_data) } if (s_bWindowsDeviceChanged || bXInputChanged) { - SDL_UnlockMutex( s_mutexJoyStickEnum ); /* let main thread go while we SDL_Delay(). */ - SDL_Delay( 300 ); /* wait for direct input to find out about this device */ - SDL_LockMutex( s_mutexJoyStickEnum ); + SDL_UnlockMutex(s_mutexJoyStickEnum); /* let main thread go while we SDL_Delay(). */ + SDL_Delay(300); /* wait for direct input to find out about this device */ + SDL_LockMutex(s_mutexJoyStickEnum); s_bDeviceRemoved = SDL_TRUE; s_bDeviceAdded = SDL_TRUE; s_bWindowsDeviceChanged = SDL_FALSE; } } - SDL_UnlockMutex( s_mutexJoyStickEnum ); + SDL_UnlockMutex(s_mutexJoyStickEnum); - if ( hNotify ) - UnregisterDeviceNotification( hNotify ); + if (hNotify) + UnregisterDeviceNotification(hNotify); - if ( messageWindow ) - DestroyWindow( messageWindow ); + if (messageWindow) + DestroyWindow(messageWindow); - UnregisterClass( wincl.lpszClassName, wincl.hInstance ); + UnregisterClass(wincl.lpszClassName, wincl.hInstance); messageWindow = 0; WIN_CoUninitialize(); return 1; @@ -629,19 +631,18 @@ SDL_SYS_JoystickInit(void) SDL_SYS_JoystickDetect(); - if ( !s_threadJoystick ) - { + if (!s_threadJoystick) { s_bJoystickThreadQuit = SDL_FALSE; /* spin up the thread to detect hotplug of devices */ #if defined(__WIN32__) && !defined(HAVE_LIBC) #undef SDL_CreateThread #if SDL_DYNAMIC_API - s_threadJoystick= SDL_CreateThread_REAL( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); + s_threadJoystick= SDL_CreateThread_REAL(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL); #else - s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); + s_threadJoystick= SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL); #endif #else - s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL ); + s_threadJoystick = SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL); #endif } return SDL_SYS_NumJoysticks(); @@ -652,8 +653,7 @@ int SDL_SYS_NumJoysticks() { int nJoysticks = 0; JoyStick_DeviceData *device = SYS_Joystick; - while ( device ) - { + while (device) { nJoysticks++; device = device->pNext; } @@ -663,27 +663,22 @@ int SDL_SYS_NumJoysticks() /* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK - EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { JoyStick_DeviceData *pNewJoystick; JoyStick_DeviceData *pPrevJoystick = NULL; - if (SDL_IsXInputDevice( &pdidInstance->guidProduct )) { + if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ } pNewJoystick = *(JoyStick_DeviceData **)pContext; - while ( pNewJoystick ) - { - if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) ) - { + while (pNewJoystick) { + if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) { /* if we are replacing the front of the list then update it */ - if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) - { + if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; - } - else if ( pPrevJoystick ) - { + } else if (pPrevJoystick) { pPrevJoystick->pNext = pNewJoystick->pNext; } @@ -697,7 +692,7 @@ static BOOL CALLBACK pNewJoystick = pNewJoystick->pNext; } - pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) ); + pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); if (!pNewJoystick) { return DIENUM_CONTINUE; /* better luck next time? */ } @@ -713,9 +708,9 @@ static BOOL CALLBACK sizeof(DIDEVICEINSTANCE)); pNewJoystick->XInputUserId = INVALID_XINPUT_USERID; - pNewJoystick->send_add_event = 1; + pNewJoystick->send_add_event = SDL_TRUE; pNewJoystick->nInstanceID = ++s_nInstanceID; - SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) ); + SDL_memcpy(&pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid)); pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; @@ -724,15 +719,63 @@ static BOOL CALLBACK return DIENUM_CONTINUE; /* get next device, please */ } -static void -AddXInputDevice(const Uint8 userid, JoyStick_DeviceData **pContext) +static char * +GetXInputName(const Uint8 userid, BYTE SubType) { char name[32]; + + if (SDL_XInputUseOldJoystickMapping()) { + SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); + } else { + switch (SubType) { + case XINPUT_DEVSUBTYPE_GAMEPAD: + SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_WHEEL: + SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_ARCADE_STICK: + SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_FLIGHT_STICK: + SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_DANCE_PAD: + SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_GUITAR: + case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE: + case XINPUT_DEVSUBTYPE_GUITAR_BASS: + SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_DRUM_KIT: + SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid); + break; + case XINPUT_DEVSUBTYPE_ARCADE_PAD: + SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid); + break; + default: + SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid); + break; + } + } + return SDL_strdup(name); +} + +static void +AddXInputDevice(const Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) +{ JoyStick_DeviceData *pPrevJoystick = NULL; - JoyStick_DeviceData *pNewJoystick = *pContext; + JoyStick_DeviceData *pNewJoystick = *pContext; + + if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) + return; + + if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN) + return; while (pNewJoystick) { - if ((pNewJoystick->bXInputDevice) && (pNewJoystick->XInputUserId == userid)) { + if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *pContext) { *pContext = pNewJoystick->pNext; @@ -755,16 +798,27 @@ AddXInputDevice(const Uint8 userid, JoyStick_DeviceData **pContext) } SDL_zerop(pNewJoystick); - SDL_snprintf(name, sizeof (name), "XInput Controller #%u", ((unsigned int) userid) + 1); - pNewJoystick->joystickname = SDL_strdup(name); + pNewJoystick->joystickname = GetXInputName(userid,SubType); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return; /* better luck next time? */ } pNewJoystick->bXInputDevice = SDL_TRUE; - pNewJoystick->XInputUserId = userid; - pNewJoystick->send_add_event = 1; + if (SDL_XInputUseOldJoystickMapping()) { + SDL_zero(pNewJoystick->guid); + } else { + pNewJoystick->guid.data[0] = 'x'; + pNewJoystick->guid.data[1] = 'i'; + pNewJoystick->guid.data[2] = 'n'; + pNewJoystick->guid.data[3] = 'p'; + pNewJoystick->guid.data[4] = 'u'; + pNewJoystick->guid.data[5] = 't'; + pNewJoystick->guid.data[6] = SubType; + } + pNewJoystick->SubType = SubType; + pNewJoystick->XInputUserId = userid; + pNewJoystick->send_add_event = SDL_TRUE; pNewJoystick->nInstanceID = ++s_nInstanceID; pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; @@ -782,11 +836,7 @@ EnumXInputDevices(JoyStick_DeviceData **pContext) const Uint8 userid = (Uint8) iuserid; XINPUT_CAPABILITIES capabilities; if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) { - /* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */ - /* !!! FIXME: we might want to support steering wheels or guitars or whatever later. */ - if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) { - AddXInputDevice(userid, pContext); - } + AddXInputDevice(userid, capabilities.SubType, pContext); } } } @@ -881,7 +931,7 @@ void SDL_SYS_JoystickDetect() } } #endif /* !SDL_EVENTS_DISABLED */ - pNewJoystick->send_add_event = 0; + pNewJoystick->send_add_event = SDL_FALSE; } device_index++; pNewJoystick = pNewJoystick->pNext; @@ -929,13 +979,14 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) /* allocate memory for system specific hardware data */ joystick->instance_id = joystickdevice->nInstanceID; - joystick->closed = 0; + joystick->closed = SDL_FALSE; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); if (joystick->hwdata == NULL) { return SDL_OutOfMemory(); } SDL_zerop(joystick->hwdata); + joystick->hwdata->guid = joystickdevice->guid; if (joystickdevice->bXInputDevice) { const Uint8 userId = joystickdevice->XInputUserId; @@ -954,27 +1005,26 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) SDL_free(joystick->hwdata); joystick->hwdata = NULL; return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?"); - } else { - /* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */ - SDL_assert(capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD); - SDL_zero(state); - joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS); - joystick->hwdata->userid = userId; - - /* The XInput API has a hard coded button/axis mapping, so we just match it */ - joystick->naxes = 6; - joystick->nbuttons = 15; - joystick->nballs = 0; - joystick->nhats = 0; } + SDL_zero(state); + joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS); + joystick->hwdata->userid = userId; + + /* The XInput API has a hard coded button/axis mapping, so we just match it */ + if (SDL_XInputUseOldJoystickMapping()) { + joystick->naxes = 6; + joystick->nbuttons = 15; + } else { + joystick->naxes = 6; + joystick->nbuttons = 11; + joystick->nhats = 1; + } } else { /* use DirectInput, not XInput. */ LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; joystick->hwdata->buffered = 1; - joystick->hwdata->removed = 0; joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); - joystick->hwdata->guid = joystickdevice->guid; SDL_zero(dipdw); dipdw.diph.dwSize = sizeof(DIPROPDWORD); @@ -1036,7 +1086,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) return SetDIerror("IDirectInputDevice8::Acquire", result); } - /* reset all accuators. */ + /* reset all actuators. */ result = IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> InputDevice, @@ -1101,9 +1151,9 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) } /* return true if this joystick is plugged in right now */ -SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick ) +SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick) { - return joystick->closed == 0 && joystick->hwdata->removed == 0; + return !joystick->closed && !joystick->hwdata->removed; } @@ -1134,10 +1184,8 @@ SortDevObjects(SDL_Joystick *joystick) SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc); - for (n = 0; n < joystick->hwdata->NumInputs; n++) - { - switch (inputs[n].type) - { + for (n = 0; n < joystick->hwdata->NumInputs; n++) { + switch (inputs[n].type) { case BUTTON: inputs[n].num = nButtons; nButtons++; @@ -1166,12 +1214,12 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) if (dev->dwType & DIDFT_BUTTON) { in->type = BUTTON; in->num = joystick->nbuttons; - in->ofs = DIJOFS_BUTTON( in->num ); + in->ofs = DIJOFS_BUTTON(in->num); joystick->nbuttons++; } else if (dev->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; - in->ofs = DIJOFS_POV( in->num ); + in->ofs = DIJOFS_POV(in->num); joystick->nhats++; } else if (dev->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; @@ -1179,26 +1227,22 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) in->type = AXIS; in->num = joystick->naxes; - /* work our the axis this guy maps too, thanks for the code icculus! */ - if ( !SDL_memcmp( &dev->guidType, &GUID_XAxis, sizeof(dev->guidType) ) ) + if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_X; - else if ( !SDL_memcmp( &dev->guidType, &GUID_YAxis, sizeof(dev->guidType) ) ) + else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_Y; - else if ( !SDL_memcmp( &dev->guidType, &GUID_ZAxis, sizeof(dev->guidType) ) ) + else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_Z; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RxAxis, sizeof(dev->guidType) ) ) + else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RX; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RyAxis, sizeof(dev->guidType) ) ) + else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RY; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RzAxis, sizeof(dev->guidType) ) ) + else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType))) in->ofs = DIJOFS_RZ; - else if ( !SDL_memcmp( &dev->guidType, &GUID_Slider, sizeof(dev->guidType) ) ) - { - in->ofs = DIJOFS_SLIDER( joystick->hwdata->NumSliders ); + else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) { + in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders); ++joystick->hwdata->NumSliders; - } - else - { + } else { return DIENUM_CONTINUE; /* not an axis we can grok */ } @@ -1266,10 +1310,9 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) sizeof(DIJOYSTATE2), &state); } - if ( result != DI_OK ) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; + if (result != DI_OK) { + joystick->hwdata->send_remove_event = SDL_TRUE; + joystick->hwdata->removed = SDL_TRUE; return; } @@ -1281,54 +1324,40 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) case AXIS: switch (in->ofs) { case DIJOFS_X: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lX); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lX); break; case DIJOFS_Y: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lY); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lY); break; case DIJOFS_Z: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lZ); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lZ); break; case DIJOFS_RX: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRx); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lRx); break; case DIJOFS_RY: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRy); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lRy); break; case DIJOFS_RZ: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRz); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.lRz); break; case DIJOFS_SLIDER(0): - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.rglSlider[0]); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.rglSlider[0]); break; case DIJOFS_SLIDER(1): - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.rglSlider[1]); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) state.rglSlider[1]); break; } - break; case BUTTON: - SDL_PrivateJoystickButton_Int(joystick, in->num, - (Uint8) (state. - rgbButtons[in->ofs - - DIJOFS_BUTTON0] - ? SDL_PRESSED : - SDL_RELEASED)); + SDL_PrivateJoystickButton(joystick, in->num, + (Uint8) (state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { - Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - - DIJOFS_POV(0)]); - SDL_PrivateJoystickHat_Int(joystick, in->num, pos); + Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]); + SDL_PrivateJoystickHat(joystick, in->num, pos); break; } } @@ -1357,10 +1386,9 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) } /* Handle the events or punt */ - if (FAILED(result)) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; + if (FAILED(result)) { + joystick->hwdata->send_remove_event = SDL_TRUE; + joystick->hwdata->removed = SDL_TRUE; return; } @@ -1375,14 +1403,11 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) switch (in->type) { case AXIS: - SDL_PrivateJoystickAxis(joystick, in->num, - (Sint16) evtbuf[i].dwData); + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16) evtbuf[i].dwData); break; case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, - (Uint8) (evtbuf[i]. - dwData ? SDL_PRESSED : - SDL_RELEASED)); + (Uint8) (evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { @@ -1394,12 +1419,69 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) } } - -/* Function to return > 0 if a bit array of buttons differs after applying a mask -*/ -int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) +static void +UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState) { - return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask ); + static WORD s_XInputButtons[] = { + XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, + XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, + XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_GUIDE + }; + WORD wButtons = pXInputState->Gamepad.wButtons; + 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)pXInputState->Gamepad.sThumbRX); + SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY))); + SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768)); + SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768)); + + for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { + SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); + } +} + +static void +UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState) +{ + static WORD s_XInputButtons[] = { + XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, + XINPUT_GAMEPAD_GUIDE + }; + WORD wButtons = pXInputState->Gamepad.wButtons; + 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)); + + for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { + SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); + } + + if (wButtons & XINPUT_GAMEPAD_DPAD_UP) { + hat |= SDL_HAT_UP; + } + if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) { + hat |= SDL_HAT_DOWN; + } + if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) { + hat |= SDL_HAT_LEFT; + } + if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) { + hat |= SDL_HAT_RIGHT; + } + SDL_PrivateJoystickHat(joystick, 0, hat); } /* Function to update the state of a XInput style joystick. @@ -1408,71 +1490,29 @@ void SDL_SYS_JoystickUpdate_XInput(SDL_Joystick * joystick) { HRESULT result; + XINPUT_STATE_EX XInputState; - if ( !XINPUTGETSTATE ) + if (!XINPUTGETSTATE) return; - result = XINPUTGETSTATE( joystick->hwdata->userid, &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot] ); - if ( result == ERROR_DEVICE_NOT_CONNECTED ) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; + result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState); + if (result == ERROR_DEVICE_NOT_CONNECTED) { + joystick->hwdata->send_remove_event = SDL_TRUE; + joystick->hwdata->removed = SDL_TRUE; return; } /* only fire events if the data changed from last time */ - if ( joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != 0 - && joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot^1].dwPacketNumber ) - { - XINPUT_STATE_EX *pXInputState = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot]; - XINPUT_STATE_EX *pXInputStatePrev = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot ^ 1]; - - /* !!! FIXME: why isn't this just using SDL_PrivateJoystickAxis_Int()? */ - SDL_PrivateJoystickAxis( joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX ); - SDL_PrivateJoystickAxis( joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY)) ); - SDL_PrivateJoystickAxis( joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX ); - SDL_PrivateJoystickAxis( joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY)) ); - SDL_PrivateJoystickAxis( joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger*65535/255) - 32768)); - SDL_PrivateJoystickAxis( joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger*65535/255) - 32768)); - - /* !!! FIXME: why isn't this just using SDL_PrivateJoystickButton_Int(), instead of keeping these two alternating state buffers? */ - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) ) - SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) ) - SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) ) - SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) ) - SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) ) - SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) ) - SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) ) - SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) ) - SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) ) - SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) ) - SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) ) - SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) ) - SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) ) - SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) ) - SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) ) - SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); /* 0x400 is the undocumented code for the guide button */ - - joystick->hwdata->currentXInputSlot ^= 1; - + if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) { + if (SDL_XInputUseOldJoystickMapping()) { + UpdateXInputJoystickState_OLD(joystick, &XInputState); + } else { + UpdateXInputJoystickState(joystick, &XInputState); + } + joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber; } } - static Uint8 TranslatePOV(DWORD value) { @@ -1501,48 +1541,17 @@ TranslatePOV(DWORD value) return HAT_VALS[value]; } -/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to - * do it. */ -/* !!! FIXME: SDL_PrivateJoystickAxis _does_ discard duplicate events now. Ditch this code. */ -static int -SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) -{ - if (joystick->axes[axis] != value) - return SDL_PrivateJoystickAxis(joystick, axis, value); - return 0; -} - -static int -SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value) -{ - if (joystick->hats[hat] != value) - return SDL_PrivateJoystickHat(joystick, hat, value); - return 0; -} - -static int -SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, - Uint8 state) -{ - if (joystick->buttons[button] != state) - return SDL_PrivateJoystickButton(joystick, button, state); - return 0; -} - void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { HRESULT result; - if ( joystick->closed || !joystick->hwdata ) + if (joystick->closed || !joystick->hwdata) return; - if (joystick->hwdata->bXInputDevice) - { + if (joystick->hwdata->bXInputDevice) { SDL_SYS_JoystickUpdate_XInput(joystick); - } - else - { + } else { result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); @@ -1555,10 +1564,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) SDL_SYS_JoystickUpdate_Polled(joystick); } - if ( joystick->hwdata->removed ) - { - joystick->closed = 1; - joystick->uncentered = 1; + if (joystick->hwdata->removed) { + joystick->closed = SDL_TRUE; + joystick->uncentered = SDL_TRUE; } } @@ -1574,7 +1582,7 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick) /* free system specific hardware data */ SDL_free(joystick->hwdata); - joystick->closed = 1; + joystick->closed = SDL_TRUE; } /* Function to perform any system-specific joystick related cleanup */ @@ -1583,8 +1591,7 @@ SDL_SYS_JoystickQuit(void) { JoyStick_DeviceData *device = SYS_Joystick; - while ( device ) - { + while (device) { JoyStick_DeviceData *device_next = device->pNext; SDL_free(device->joystickname); SDL_free(device); @@ -1592,16 +1599,15 @@ SDL_SYS_JoystickQuit(void) } SYS_Joystick = NULL; - if ( s_threadJoystick ) - { - SDL_LockMutex( s_mutexJoyStickEnum ); + if (s_threadJoystick) { + SDL_LockMutex(s_mutexJoyStickEnum); s_bJoystickThreadQuit = SDL_TRUE; - SDL_CondBroadcast( s_condJoystickThread ); /* signal the joystick thread to quit */ - SDL_UnlockMutex( s_mutexJoyStickEnum ); - SDL_WaitThread( s_threadJoystick, NULL ); /* wait for it to bugger off */ + SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */ + SDL_UnlockMutex(s_mutexJoyStickEnum); + SDL_WaitThread(s_threadJoystick, NULL); /* wait for it to bugger off */ - SDL_DestroyMutex( s_mutexJoyStickEnum ); - SDL_DestroyCond( s_condJoystickThread ); + SDL_DestroyMutex(s_mutexJoyStickEnum); + SDL_DestroyCond(s_condJoystickThread); s_condJoystickThread= NULL; s_mutexJoyStickEnum = NULL; s_threadJoystick = NULL; @@ -1623,7 +1629,7 @@ SDL_SYS_JoystickQuit(void) } /* return the stable device guid for this device index */ -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index) { JoyStick_DeviceData *device = SYS_Joystick; int index; @@ -1639,8 +1645,7 @@ SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) return joystick->hwdata->guid; } -/* return SDL_TRUE if this device is using XInput */ -SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) +SDL_bool SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index) { JoyStick_DeviceData *device = SYS_Joystick; int index; @@ -1648,13 +1653,7 @@ SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) for (index = device_index; index > 0; index--) device = device->pNext; - return device->bXInputDevice; -} - -/* return SDL_TRUE if this device was opened with XInput */ -SDL_bool SDL_SYS_IsXInputJoystick(SDL_Joystick * joystick) -{ - return joystick->hwdata->bXInputDevice; + return (device->SubType == XINPUT_DEVSUBTYPE_GAMEPAD); } #endif /* SDL_JOYSTICK_DINPUT */ diff --git a/src/joystick/windows/SDL_dxjoystick_c.h b/src/joystick/windows/SDL_dxjoystick_c.h index 2808fed56..e0739587c 100644 --- a/src/joystick/windows/SDL_dxjoystick_c.h +++ b/src/joystick/windows/SDL_dxjoystick_c.h @@ -54,6 +54,43 @@ #define XINPUT_CAPS_FFB_SUPPORTED 0x0001 #endif +#ifndef XINPUT_DEVSUBTYPE_UNKNOWN +#define XINPUT_DEVSUBTYPE_UNKNOWN 0x00 +#endif +#ifndef XINPUT_DEVSUBTYPE_GAMEPAD +#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01 +#endif +#ifndef XINPUT_DEVSUBTYPE_WHEEL +#define XINPUT_DEVSUBTYPE_WHEEL 0x02 +#endif +#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK +#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03 +#endif +#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK +#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04 +#endif +#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD +#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR +#define XINPUT_DEVSUBTYPE_GUITAR 0x06 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE +#define XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE 0x07 +#endif +#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT +#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR_BASS +#define XINPUT_DEVSUBTYPE_GUITAR_BASS 0x0B +#endif +#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD +#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13 +#endif + +#ifndef XINPUT_GAMEPAD_GUIDE +#define XINPUT_GAMEPAD_GUIDE 0x0400 +#endif /* typedef's for XInput structs we use */ typedef struct @@ -138,13 +175,12 @@ struct joystick_hwdata input_t Inputs[MAX_INPUTS]; int NumInputs; int NumSliders; - Uint8 removed; - Uint8 send_remove_event; - Uint8 bXInputDevice; /* 1 if this device supports using the xinput API rather than DirectInput */ - Uint8 bXInputHaptic; /* Supports force feedback via XInput. */ + SDL_bool removed; + SDL_bool send_remove_event; + SDL_bool bXInputDevice; /* SDL_TRUE if this device supports using the xinput API rather than DirectInput */ + SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */ Uint8 userid; /* XInput userid index for this joystick */ - Uint8 currentXInputSlot; /* the current position to write to in XInputState below, used so we can compare old and new values */ - XINPUT_STATE_EX XInputState[2]; + DWORD dwPacketNumber; }; #endif /* SDL_JOYSTICK_DINPUT_H */