diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
index f63116d04..468f85536 100644
--- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
+++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj
@@ -75,9 +75,9 @@
-
+
true
@@ -426,7 +426,7 @@
Console
false
false
- xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)
+ xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)
@@ -440,7 +440,7 @@
Console
false
false
- xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)
+ xinput.lib;xaudio2.lib;d2d1.lib;d3d11.lib;dxgi.lib;ole32.lib;windowscodecs.lib;dwrite.lib;kernel32.lib;%(AdditionalDependencies)
diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters
index 90608e46a..74dd2dc86 100644
--- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters
+++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj.filters
@@ -192,9 +192,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -267,6 +264,9 @@
Source Files
+
+ Source Files
+
diff --git a/include/SDL_config_windowsrt.h b/include/SDL_config_windowsrt.h
index 5e48338f4..b6ecc00fe 100644
--- a/include/SDL_config_windowsrt.h
+++ b/include/SDL_config_windowsrt.h
@@ -144,8 +144,12 @@ typedef unsigned int uintptr_t;
/* Enable various input drivers */
// TODO, WinRT: Get haptic support working
#define SDL_HAPTIC_DISABLED 1
-// TODO, WinRT: Get joystick support working
-#define SDL_JOYSTICK_DISABLED 1
+
+#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+#define SDL_JOYSTICK_DISABLED 1
+#else
+#define SDL_JOYSTICK_XINPUT 1
+#endif
/* Enable various shared object loading systems */
#define SDL_LOADSO_WINDOWS 1
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index 2e856d359..9bf87a30c 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -89,8 +89,10 @@ typedef struct _ControllerMapping_t
/* default mappings we support */
const char *s_ControllerMappings [] =
{
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
"xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5",
+#endif
+#ifdef SDL_JOYSTICK_DINPUT
"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7",
"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12",
"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
@@ -119,7 +121,7 @@ const char *s_ControllerMappings [] =
};
static ControllerMapping_t *s_pSupportedControllers = NULL;
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
static ControllerMapping_t *s_pXInputMapping = NULL;
#endif
@@ -310,7 +312,7 @@ ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *gu
*/
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
{
return s_pXInputMapping;
@@ -699,7 +701,7 @@ SDL_GameControllerAddMapping( const char *mappingString )
char *pchMapping;
SDL_JoystickGUID jGUID;
ControllerMapping_t *pControllerMapping;
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
SDL_bool is_xinput_mapping = SDL_FALSE;
#endif
@@ -707,7 +709,7 @@ SDL_GameControllerAddMapping( const char *mappingString )
if (!pchGUID) {
return -1;
}
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
is_xinput_mapping = SDL_TRUE;
}
@@ -742,7 +744,7 @@ SDL_GameControllerAddMapping( const char *mappingString )
SDL_free( pchMapping );
return SDL_OutOfMemory();
}
-#ifdef SDL_JOYSTICK_DINPUT
+#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT)
if ( is_xinput_mapping )
{
s_pXInputMapping = pControllerMapping;
diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h
index 4a5019e73..f75aabc07 100644
--- a/src/joystick/SDL_sysjoystick.h
+++ b/src/joystick/SDL_sysjoystick.h
@@ -108,7 +108,7 @@ extern SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index);
/* Function to return the stable GUID for a opened joystick */
extern SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick);
-#ifdef SDL_JOYSTICK_DINPUT
+#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 );
#endif
diff --git a/src/joystick/windowsrt/SDL_xinputjoystick.c b/src/joystick/windowsrt/SDL_xinputjoystick.c
new file mode 100644
index 000000000..63e8a1ff1
--- /dev/null
+++ b/src/joystick/windowsrt/SDL_xinputjoystick.c
@@ -0,0 +1,378 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2013 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#if SDL_JOYSTICK_XINPUT
+
+/* SDL_xinputjoystick.c implements an XInput-only joystick and game controller
+ backend that is suitable for use on WinRT. SDL's DirectInput backend, also
+ XInput-capable, was not used as DirectInput is not available on WinRT (or,
+ at least, it isn't a public API). Some portions of this XInput backend
+ may copy parts of the XInput-using code from the DirectInput backend.
+ Refactoring the common parts into one location may be good to-do at some
+ point.
+
+ TODO, WinRT: add hotplug support for XInput based game controllers
+*/
+
+#include "SDL_joystick.h"
+#include "../SDL_sysjoystick.h"
+#include "../SDL_joystick_c.h"
+#include "SDL_events.h"
+
+#include
+#include
+
+struct joystick_hwdata {
+ //Uint8 bXInputHaptic; // Supports force feedback via XInput.
+ DWORD userIndex; // The XInput device index, in the range [0, XUSER_MAX_COUNT-1] (probably [0,3]).
+ XINPUT_STATE XInputState; // the last-read in XInputState, kept around to compare old and new values
+ SDL_bool isDeviceConnected; // was the device connected (on the last polling, or during backend-initialization)?
+};
+
+/* Keep track of data on all XInput devices, regardless of whether or not
+ they've been opened (via SDL_JoystickOpen).
+ */
+static struct joystick_hwdata g_XInputData[XUSER_MAX_COUNT];
+
+/* Function to scan the system for joysticks.
+ * It should return 0, or -1 on an unrecoverable fatal error.
+ */
+int
+SDL_SYS_JoystickInit(void)
+{
+ HRESULT result = S_OK;
+ XINPUT_STATE tempXInputState;
+ int i;
+
+ SDL_zero(g_XInputData);
+
+ /* Make initial notes on whether or not devices are connected (or not).
+ */
+ for (i = 0; i < XUSER_MAX_COUNT; ++i) {
+ result = XInputGetState(i, &tempXInputState);
+ if (result == ERROR_SUCCESS) {
+ g_XInputData[i].isDeviceConnected = SDL_TRUE;
+ }
+ }
+
+ return (0);
+}
+
+int SDL_SYS_NumJoysticks()
+{
+ int joystickCount = 0;
+ DWORD i;
+
+ /* Iterate through each possible XInput device and see if something
+ was connected (at joystick init, or during the last polling).
+ */
+ for (i = 0; i < XUSER_MAX_COUNT; ++i) {
+ if (g_XInputData[i].isDeviceConnected) {
+ ++joystickCount;
+ }
+ }
+
+ return joystickCount;
+}
+
+void SDL_SYS_JoystickDetect()
+{
+}
+
+SDL_bool SDL_SYS_JoystickNeedsPolling()
+{
+ return SDL_FALSE;
+}
+
+/* Internal function to retreive device capabilities.
+ This function will return an SDL-standard value of 0 on success
+ (a device is connected, and data on it was retrieved), or -1
+ on failure (no device was connected, or some other error
+ occurred. SDL_SetError() will be invoked to set an appropriate
+ error message.
+ */
+static int
+SDL_XInput_GetDeviceCapabilities(int device_index, XINPUT_CAPABILITIES * pDeviceCaps)
+{
+ HRESULT dwResult;
+
+ /* Make sure that the device index is a valid one. If not, return to the
+ caller with an error.
+ */
+ if (device_index < 0 || device_index >= XUSER_MAX_COUNT) {
+ return SDL_SetError("invalid/unavailable device index");
+ }
+
+ /* See if a device exists, and if so, what its capabilities are. If a
+ device is not available, return to the caller with an error.
+ */
+ switch ((dwResult = XInputGetCapabilities(device_index, 0, pDeviceCaps))) {
+ case ERROR_SUCCESS:
+ /* A device is available, and its capabilities were retrieved! */
+ return 0;
+ case ERROR_DEVICE_NOT_CONNECTED:
+ return SDL_SetError("no device is connected at joystick index, %d", device_index);
+ default:
+ return SDL_SetError("an unknown error occurred when retrieving info on a device at joystick index, %d", device_index);
+ }
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char *
+SDL_SYS_JoystickNameForDeviceIndex(int device_index)
+{
+ XINPUT_CAPABILITIES deviceCaps;
+
+ if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) {
+ /* Uh oh. Device capabilities couldn't be retrieved. Return to the
+ caller. SDL_SetError() has already been invoked (with relevant
+ information).
+ */
+ return NULL;
+ }
+
+ switch (deviceCaps.SubType) {
+ default:
+ if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) {
+ return "Undefined game controller";
+ } else {
+ return "Undefined controller";
+ }
+ case XINPUT_DEVSUBTYPE_UNKNOWN:
+ if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) {
+ return "Unknown game controller";
+ } else {
+ return "Unknown controller";
+ }
+ case XINPUT_DEVSUBTYPE_GAMEPAD:
+ return "Gamepad controller";
+ case XINPUT_DEVSUBTYPE_WHEEL:
+ return "Racing wheel controller";
+ case XINPUT_DEVSUBTYPE_ARCADE_STICK:
+ return "Arcade stick controller";
+ case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
+ return "Flight stick controller";
+ case XINPUT_DEVSUBTYPE_DANCE_PAD:
+ return "Dance pad controller";
+ case XINPUT_DEVSUBTYPE_GUITAR:
+ return "Guitar controller";
+ case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
+ return "Guitar controller, Alternate";
+ case XINPUT_DEVSUBTYPE_GUITAR_BASS:
+ return "Guitar controller, Bass";
+ case XINPUT_DEVSUBTYPE_DRUM_KIT:
+ return "Drum controller";
+ case XINPUT_DEVSUBTYPE_ARCADE_PAD:
+ return "Arcade pad controller";
+ }
+}
+
+/* Function to perform the mapping from device index to the instance id for this index */
+SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
+{
+ return device_index;
+}
+
+/* Function to open a joystick for use.
+ The joystick to open is specified by the index field of the joystick.
+ This should fill the nbuttons and naxes fields of the joystick structure.
+ It returns 0, or -1 if there is an error.
+ */
+int
+SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
+{
+ XINPUT_CAPABILITIES deviceCaps;
+
+ if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) {
+ /* Uh oh. Device capabilities couldn't be retrieved. Return to the
+ caller. SDL_SetError() has already been invoked (with relevant
+ information).
+ */
+ return -1;
+ }
+
+ /* For now, only game pads are supported. If the device is something other
+ than that, return an error to the caller.
+ */
+ if (deviceCaps.Type != XINPUT_DEVTYPE_GAMEPAD) {
+ return SDL_SetError("a device is connected (at joystick index, %d), but it is of an unknown device type (deviceCaps.Flags=%ul)",
+ device_index, (unsigned int)deviceCaps.Flags);
+ }
+
+ /* Create the joystick data structure */
+ joystick->instance_id = device_index;
+ joystick->hwdata = &g_XInputData[device_index];
+
+ // 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;
+
+ /* We're done! */
+ return (0);
+}
+
+/* Function to determine is this joystick is attached to the system right now */
+SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
+{
+ return joystick->hwdata->isDeviceConnected;
+}
+
+/* Function to return > 0 if a bit array of buttons differs after applying a mask
+*/
+static int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask )
+{
+ return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask );
+}
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+void
+SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
+{
+ HRESULT result;
+
+ /* Before polling for new data, make note of the old data */
+ XINPUT_STATE prevXInputState = joystick->hwdata->XInputState;
+
+ /* Poll for new data */
+ result = XInputGetState(joystick->hwdata->userIndex, &joystick->hwdata->XInputState);
+ if (result == ERROR_DEVICE_NOT_CONNECTED) {
+ /* TODO, WinRT: set a flag to indicate that a device-removal event
+ needs to be emitted.
+ */
+ //joystick->hwdata->send_remove_event = 1;
+ //joystick->hwdata->removed = 1;
+ joystick->hwdata->isDeviceConnected = SDL_FALSE;
+ return;
+ }
+
+ /* Make sure the device is marked as connected */
+ joystick->hwdata->isDeviceConnected = SDL_TRUE;
+
+ // only fire events if the data changed from last time
+ if ( joystick->hwdata->XInputState.dwPacketNumber != 0
+ && joystick->hwdata->XInputState.dwPacketNumber != prevXInputState.dwPacketNumber )
+ {
+ XINPUT_STATE *pXInputState = &joystick->hwdata->XInputState;
+ XINPUT_STATE *pXInputStatePrev = &prevXInputState;
+
+ SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX );
+ SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) );
+ SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX );
+ SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) );
+ SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) );
+ SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) );
+
+ 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
+ }
+}
+
+/* Function to close a joystick after use */
+void
+SDL_SYS_JoystickClose(SDL_Joystick * joystick)
+{
+ /* Clear cached button data on the joystick */
+ SDL_zero(joystick->hwdata->XInputState);
+
+ /* There's need to free 'hwdata', as it's a pointer to a global array.
+ The field will be cleared anyways, just to indicate that it's not
+ currently needed.
+ */
+ joystick->hwdata = NULL;
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+void
+SDL_SYS_JoystickQuit(void)
+{
+ return;
+}
+
+SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
+{
+ SDL_JoystickGUID guid;
+ // the GUID is just the first 16 chars of the name for now
+ const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
+ SDL_zero( guid );
+ SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
+ return guid;
+}
+
+
+SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
+{
+ SDL_JoystickGUID guid;
+ // the GUID is just the first 16 chars of the name for now
+ const char *name = joystick->name;
+ SDL_zero( guid );
+ SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
+ return guid;
+}
+
+SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index)
+{
+ /* The XInput-capable DirectInput joystick backend implements the same
+ function (SDL_SYS_IsXInputDeviceIndex), however in that case, not all
+ joystick devices are XInput devices. In this case, with the
+ WinRT-enabled XInput-only backend, all "joystick" devices are XInput
+ devices.
+ */
+ return SDL_TRUE;
+}
+
+#endif /* SDL_JOYSTICK_XINPUT */
+
+/* vi: set ts=4 sw=4 expandtab: */