dludwig@8471: /* dludwig@8471: Simple DirectMedia Layer dludwig@8471: Copyright (C) 1997-2013 Sam Lantinga dludwig@8471: dludwig@8471: This software is provided 'as-is', without any express or implied dludwig@8471: warranty. In no event will the authors be held liable for any damages dludwig@8471: arising from the use of this software. dludwig@8471: dludwig@8471: Permission is granted to anyone to use this software for any purpose, dludwig@8471: including commercial applications, and to alter it and redistribute it dludwig@8471: freely, subject to the following restrictions: dludwig@8471: dludwig@8471: 1. The origin of this software must not be misrepresented; you must not dludwig@8471: claim that you wrote the original software. If you use this software dludwig@8471: in a product, an acknowledgment in the product documentation would be dludwig@8471: appreciated but is not required. dludwig@8471: 2. Altered source versions must be plainly marked as such, and must not be dludwig@8471: misrepresented as being the original software. dludwig@8471: 3. This notice may not be removed or altered from any source distribution. dludwig@8471: */ dludwig@8471: #include "SDL_config.h" dludwig@8471: dludwig@8471: #if SDL_JOYSTICK_XINPUT dludwig@8471: dludwig@8471: /* SDL_xinputjoystick.c implements an XInput-only joystick and game controller dludwig@8471: backend that is suitable for use on WinRT. SDL's DirectInput backend, also dludwig@8471: XInput-capable, was not used as DirectInput is not available on WinRT (or, dludwig@8471: at least, it isn't a public API). Some portions of this XInput backend dludwig@8471: may copy parts of the XInput-using code from the DirectInput backend. dludwig@8471: Refactoring the common parts into one location may be good to-do at some dludwig@8471: point. dludwig@8471: dludwig@8471: TODO, WinRT: add hotplug support for XInput based game controllers dludwig@8471: */ dludwig@8471: dludwig@8471: #include "SDL_joystick.h" dludwig@8471: #include "../SDL_sysjoystick.h" dludwig@8471: #include "../SDL_joystick_c.h" dludwig@8471: #include "SDL_events.h" dludwig@8473: #include "../../events/SDL_events_c.h" dludwig@8471: dludwig@8471: #include dludwig@8471: #include dludwig@8471: dludwig@8471: struct joystick_hwdata { dludwig@8471: //Uint8 bXInputHaptic; // Supports force feedback via XInput. dludwig@8471: DWORD userIndex; // The XInput device index, in the range [0, XUSER_MAX_COUNT-1] (probably [0,3]). dludwig@8471: XINPUT_STATE XInputState; // the last-read in XInputState, kept around to compare old and new values dludwig@8471: SDL_bool isDeviceConnected; // was the device connected (on the last polling, or during backend-initialization)? dludwig@8473: SDL_bool isDeviceRemovalEventPending; // was the device removed, and is the associated removal event pending? dludwig@8471: }; dludwig@8471: dludwig@8471: /* Keep track of data on all XInput devices, regardless of whether or not dludwig@8471: they've been opened (via SDL_JoystickOpen). dludwig@8471: */ dludwig@8471: static struct joystick_hwdata g_XInputData[XUSER_MAX_COUNT]; dludwig@8471: dludwig@8471: /* Function to scan the system for joysticks. dludwig@8471: * It should return 0, or -1 on an unrecoverable fatal error. dludwig@8471: */ dludwig@8471: int dludwig@8471: SDL_SYS_JoystickInit(void) dludwig@8471: { dludwig@8471: HRESULT result = S_OK; dludwig@8471: XINPUT_STATE tempXInputState; dludwig@8471: int i; dludwig@8471: dludwig@8471: SDL_zero(g_XInputData); dludwig@8471: dludwig@8471: /* Make initial notes on whether or not devices are connected (or not). dludwig@8471: */ dludwig@8471: for (i = 0; i < XUSER_MAX_COUNT; ++i) { dludwig@8471: result = XInputGetState(i, &tempXInputState); dludwig@8471: if (result == ERROR_SUCCESS) { dludwig@8471: g_XInputData[i].isDeviceConnected = SDL_TRUE; dludwig@8471: } dludwig@8471: } dludwig@8471: dludwig@8471: return (0); dludwig@8471: } dludwig@8471: dludwig@8471: int SDL_SYS_NumJoysticks() dludwig@8471: { dludwig@8471: int joystickCount = 0; dludwig@8471: DWORD i; dludwig@8471: dludwig@8471: /* Iterate through each possible XInput device and see if something dludwig@8471: was connected (at joystick init, or during the last polling). dludwig@8471: */ dludwig@8471: for (i = 0; i < XUSER_MAX_COUNT; ++i) { dludwig@8471: if (g_XInputData[i].isDeviceConnected) { dludwig@8471: ++joystickCount; dludwig@8471: } dludwig@8471: } dludwig@8471: dludwig@8471: return joystickCount; dludwig@8471: } dludwig@8471: dludwig@8471: void SDL_SYS_JoystickDetect() dludwig@8471: { dludwig@8473: DWORD i; dludwig@8473: XINPUT_STATE tempXInputState; dludwig@8473: HRESULT result; dludwig@8473: SDL_Event event; dludwig@8473: dludwig@8473: /* Iterate through each possible XInput device, seeing if any devices dludwig@8473: have been connected, or if they were removed. dludwig@8473: */ dludwig@8473: for (i = 0; i < XUSER_MAX_COUNT; ++i) { dludwig@8473: /* See if any new devices are connected. */ dludwig@8473: if (!g_XInputData[i].isDeviceConnected && !g_XInputData[i].isDeviceRemovalEventPending) { dludwig@8473: result = XInputGetState(i, &tempXInputState); dludwig@8473: if (result == ERROR_SUCCESS) { dludwig@8473: /* Yup, a device is connected. Mark the device as connected, dludwig@8473: then tell others about it (via an SDL_JOYDEVICEADDED event.) dludwig@8473: */ dludwig@8473: g_XInputData[i].isDeviceConnected = SDL_TRUE; dludwig@8473: dludwig@8473: #if !SDL_EVENTS_DISABLED dludwig@8473: SDL_zero(event); dludwig@8473: event.type = SDL_JOYDEVICEADDED; dludwig@8473: dludwig@8473: if (SDL_GetEventState(event.type) == SDL_ENABLE) { dludwig@8473: event.jdevice.which = i; dludwig@8473: if ((SDL_EventOK == NULL) dludwig@8473: || (*SDL_EventOK) (SDL_EventOKParam, &event)) { dludwig@8473: SDL_PushEvent(&event); dludwig@8473: } dludwig@8473: } dludwig@8473: #endif dludwig@8473: } dludwig@8473: } else if (g_XInputData[i].isDeviceRemovalEventPending) { dludwig@8473: /* A device was previously marked as removed (by dludwig@8473: SDL_SYS_JoystickUpdate). Tell others about the device removal. dludwig@8473: */ dludwig@8473: dludwig@8473: g_XInputData[i].isDeviceRemovalEventPending = SDL_FALSE; dludwig@8473: dludwig@8473: #if !SDL_EVENTS_DISABLED dludwig@8473: SDL_zero(event); dludwig@8473: event.type = SDL_JOYDEVICEREMOVED; dludwig@8473: dludwig@8473: if (SDL_GetEventState(event.type) == SDL_ENABLE) { dludwig@8473: event.jdevice.which = i; //joystick->hwdata->userIndex; dludwig@8473: if ((SDL_EventOK == NULL) dludwig@8473: || (*SDL_EventOK) (SDL_EventOKParam, &event)) { dludwig@8473: SDL_PushEvent(&event); dludwig@8473: } dludwig@8473: } dludwig@8473: #endif dludwig@8473: } dludwig@8473: } dludwig@8471: } dludwig@8471: dludwig@8471: SDL_bool SDL_SYS_JoystickNeedsPolling() dludwig@8471: { dludwig@8473: /* Since XInput, or WinRT, provides any events to indicate when a game dludwig@8473: controller gets connected, and instead indicates device availability dludwig@8473: solely through polling, we'll poll (for new devices). dludwig@8473: */ dludwig@8473: return SDL_TRUE; dludwig@8471: } dludwig@8471: dludwig@8471: /* Internal function to retreive device capabilities. dludwig@8471: This function will return an SDL-standard value of 0 on success dludwig@8471: (a device is connected, and data on it was retrieved), or -1 dludwig@8471: on failure (no device was connected, or some other error dludwig@8471: occurred. SDL_SetError() will be invoked to set an appropriate dludwig@8471: error message. dludwig@8471: */ dludwig@8471: static int dludwig@8471: SDL_XInput_GetDeviceCapabilities(int device_index, XINPUT_CAPABILITIES * pDeviceCaps) dludwig@8471: { dludwig@8471: HRESULT dwResult; dludwig@8471: dludwig@8471: /* Make sure that the device index is a valid one. If not, return to the dludwig@8471: caller with an error. dludwig@8471: */ dludwig@8471: if (device_index < 0 || device_index >= XUSER_MAX_COUNT) { dludwig@8471: return SDL_SetError("invalid/unavailable device index"); dludwig@8471: } dludwig@8471: dludwig@8471: /* See if a device exists, and if so, what its capabilities are. If a dludwig@8471: device is not available, return to the caller with an error. dludwig@8471: */ dludwig@8471: switch ((dwResult = XInputGetCapabilities(device_index, 0, pDeviceCaps))) { dludwig@8471: case ERROR_SUCCESS: dludwig@8471: /* A device is available, and its capabilities were retrieved! */ dludwig@8471: return 0; dludwig@8471: case ERROR_DEVICE_NOT_CONNECTED: dludwig@8471: return SDL_SetError("no device is connected at joystick index, %d", device_index); dludwig@8471: default: dludwig@8471: return SDL_SetError("an unknown error occurred when retrieving info on a device at joystick index, %d", device_index); dludwig@8471: } dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to get the device-dependent name of a joystick */ dludwig@8471: const char * dludwig@8471: SDL_SYS_JoystickNameForDeviceIndex(int device_index) dludwig@8471: { dludwig@8471: XINPUT_CAPABILITIES deviceCaps; dludwig@8471: dludwig@8471: if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) { dludwig@8471: /* Uh oh. Device capabilities couldn't be retrieved. Return to the dludwig@8471: caller. SDL_SetError() has already been invoked (with relevant dludwig@8471: information). dludwig@8471: */ dludwig@8471: return NULL; dludwig@8471: } dludwig@8471: dludwig@8471: switch (deviceCaps.SubType) { dludwig@8471: default: dludwig@8471: if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) { dludwig@8471: return "Undefined game controller"; dludwig@8471: } else { dludwig@8471: return "Undefined controller"; dludwig@8471: } dludwig@8471: case XINPUT_DEVSUBTYPE_UNKNOWN: dludwig@8471: if (deviceCaps.Type == XINPUT_DEVTYPE_GAMEPAD) { dludwig@8471: return "Unknown game controller"; dludwig@8471: } else { dludwig@8471: return "Unknown controller"; dludwig@8471: } dludwig@8471: case XINPUT_DEVSUBTYPE_GAMEPAD: dludwig@8471: return "Gamepad controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_WHEEL: dludwig@8471: return "Racing wheel controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_ARCADE_STICK: dludwig@8471: return "Arcade stick controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_FLIGHT_STICK: dludwig@8471: return "Flight stick controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_DANCE_PAD: dludwig@8471: return "Dance pad controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_GUITAR: dludwig@8471: return "Guitar controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE: dludwig@8471: return "Guitar controller, Alternate"; dludwig@8471: case XINPUT_DEVSUBTYPE_GUITAR_BASS: dludwig@8471: return "Guitar controller, Bass"; dludwig@8471: case XINPUT_DEVSUBTYPE_DRUM_KIT: dludwig@8471: return "Drum controller"; dludwig@8471: case XINPUT_DEVSUBTYPE_ARCADE_PAD: dludwig@8471: return "Arcade pad controller"; dludwig@8471: } dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to perform the mapping from device index to the instance id for this index */ dludwig@8471: SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) dludwig@8471: { dludwig@8471: return device_index; dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to open a joystick for use. dludwig@8471: The joystick to open is specified by the index field of the joystick. dludwig@8471: This should fill the nbuttons and naxes fields of the joystick structure. dludwig@8471: It returns 0, or -1 if there is an error. dludwig@8471: */ dludwig@8471: int dludwig@8471: SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) dludwig@8471: { dludwig@8471: XINPUT_CAPABILITIES deviceCaps; dludwig@8471: dludwig@8471: if (SDL_XInput_GetDeviceCapabilities(device_index, &deviceCaps) != 0) { dludwig@8471: /* Uh oh. Device capabilities couldn't be retrieved. Return to the dludwig@8471: caller. SDL_SetError() has already been invoked (with relevant dludwig@8471: information). dludwig@8471: */ dludwig@8471: return -1; dludwig@8471: } dludwig@8471: dludwig@8471: /* For now, only game pads are supported. If the device is something other dludwig@8471: than that, return an error to the caller. dludwig@8471: */ dludwig@8471: if (deviceCaps.Type != XINPUT_DEVTYPE_GAMEPAD) { dludwig@8471: return SDL_SetError("a device is connected (at joystick index, %d), but it is of an unknown device type (deviceCaps.Flags=%ul)", dludwig@8471: device_index, (unsigned int)deviceCaps.Flags); dludwig@8471: } dludwig@8471: dludwig@8471: /* Create the joystick data structure */ dludwig@8471: joystick->instance_id = device_index; dludwig@8471: joystick->hwdata = &g_XInputData[device_index]; dludwig@8471: dludwig@8471: // The XInput API has a hard coded button/axis mapping, so we just match it dludwig@8471: joystick->naxes = 6; dludwig@8471: joystick->nbuttons = 15; dludwig@8471: joystick->nballs = 0; dludwig@8471: joystick->nhats = 0; dludwig@8471: dludwig@8471: /* We're done! */ dludwig@8471: return (0); dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to determine is this joystick is attached to the system right now */ dludwig@8471: SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) dludwig@8471: { dludwig@8471: return joystick->hwdata->isDeviceConnected; dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to return > 0 if a bit array of buttons differs after applying a mask dludwig@8471: */ dludwig@8471: static int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) dludwig@8471: { dludwig@8471: return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask ); dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to update the state of a joystick - called as a device poll. dludwig@8471: * This function shouldn't update the joystick structure directly, dludwig@8471: * but instead should call SDL_PrivateJoystick*() to deliver events dludwig@8471: * and update joystick device state. dludwig@8471: */ dludwig@8471: void dludwig@8471: SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) dludwig@8471: { dludwig@8471: HRESULT result; dludwig@8471: dludwig@8471: /* Before polling for new data, make note of the old data */ dludwig@8471: XINPUT_STATE prevXInputState = joystick->hwdata->XInputState; dludwig@8471: dludwig@8471: /* Poll for new data */ dludwig@8471: result = XInputGetState(joystick->hwdata->userIndex, &joystick->hwdata->XInputState); dludwig@8471: if (result == ERROR_DEVICE_NOT_CONNECTED) { dludwig@8473: if (joystick->hwdata->isDeviceConnected) { dludwig@8473: joystick->hwdata->isDeviceConnected = SDL_FALSE; dludwig@8473: joystick->hwdata->isDeviceRemovalEventPending = SDL_TRUE; dludwig@8473: /* TODO, WinRT: make sure isDeviceRemovalEventPending gets cleared as appropriate, and that quick re-plugs don't cause trouble */ dludwig@8473: } dludwig@8471: return; dludwig@8471: } dludwig@8471: dludwig@8471: /* Make sure the device is marked as connected */ dludwig@8471: joystick->hwdata->isDeviceConnected = SDL_TRUE; dludwig@8471: dludwig@8471: // only fire events if the data changed from last time dludwig@8471: if ( joystick->hwdata->XInputState.dwPacketNumber != 0 dludwig@8471: && joystick->hwdata->XInputState.dwPacketNumber != prevXInputState.dwPacketNumber ) dludwig@8471: { dludwig@8471: XINPUT_STATE *pXInputState = &joystick->hwdata->XInputState; dludwig@8471: XINPUT_STATE *pXInputStatePrev = &prevXInputState; dludwig@8471: dludwig@8471: SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX ); dludwig@8471: SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) ); dludwig@8471: SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX ); dludwig@8471: SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) ); dludwig@8471: SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) ); dludwig@8471: SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) ); dludwig@8471: dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED ); dludwig@8471: if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) ) dludwig@8471: SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); // 0x400 is the undocumented code for the guide button dludwig@8471: } dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to close a joystick after use */ dludwig@8471: void dludwig@8471: SDL_SYS_JoystickClose(SDL_Joystick * joystick) dludwig@8471: { dludwig@8471: /* Clear cached button data on the joystick */ dludwig@8471: SDL_zero(joystick->hwdata->XInputState); dludwig@8471: dludwig@8471: /* There's need to free 'hwdata', as it's a pointer to a global array. dludwig@8471: The field will be cleared anyways, just to indicate that it's not dludwig@8471: currently needed. dludwig@8471: */ dludwig@8471: joystick->hwdata = NULL; dludwig@8471: } dludwig@8471: dludwig@8471: /* Function to perform any system-specific joystick related cleanup */ dludwig@8471: void dludwig@8471: SDL_SYS_JoystickQuit(void) dludwig@8471: { dludwig@8471: return; dludwig@8471: } dludwig@8471: dludwig@8471: SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) dludwig@8471: { dludwig@8471: SDL_JoystickGUID guid; dludwig@8471: // the GUID is just the first 16 chars of the name for now dludwig@8471: const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); dludwig@8471: SDL_zero( guid ); dludwig@8471: SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); dludwig@8471: return guid; dludwig@8471: } dludwig@8471: dludwig@8471: dludwig@8471: SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) dludwig@8471: { dludwig@8471: SDL_JoystickGUID guid; dludwig@8471: // the GUID is just the first 16 chars of the name for now dludwig@8471: const char *name = joystick->name; dludwig@8471: SDL_zero( guid ); dludwig@8471: SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); dludwig@8471: return guid; dludwig@8471: } dludwig@8471: dludwig@8471: SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) dludwig@8471: { dludwig@8471: /* The XInput-capable DirectInput joystick backend implements the same dludwig@8471: function (SDL_SYS_IsXInputDeviceIndex), however in that case, not all dludwig@8471: joystick devices are XInput devices. In this case, with the dludwig@8471: WinRT-enabled XInput-only backend, all "joystick" devices are XInput dludwig@8471: devices. dludwig@8471: */ dludwig@8471: return SDL_TRUE; dludwig@8471: } dludwig@8471: dludwig@8471: #endif /* SDL_JOYSTICK_XINPUT */ dludwig@8471: dludwig@8471: /* vi: set ts=4 sw=4 expandtab: */