| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | misrepresented as being the original software. |
| | | 3. This notice may not be removed or altered from any source distribution. |
| | | */ |
| | | #include "SDL_config.h" |
| | | #include "../../SDL_internal.h" |
| | | |
| | | #ifdef SDL_JOYSTICK_DINPUT |
| | | |
| | |
| | | |
| | | #define INITGUID /* Only set here, if set twice will cause mingw32 to break. */ |
| | | #include "SDL_dxjoystick_c.h" |
| | | |
| | | #if SDL_HAPTIC_DINPUT |
| | | #include "../../haptic/windows/SDL_syshaptic_c.h" /* For haptic hot plugging */ |
| | | #endif |
| | | |
| | | #ifndef DIDFT_OPTIONAL |
| | | #define DIDFT_OPTIONAL 0x80000000 |
| | |
| | | /* 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 ); |
| | | #else |
| | | s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); |
| | | #endif |
| | | #else |
| | | s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL ); |
| | | #endif |
| | |
| | | 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 laster. */ |
| | | /* !!! FIXME: we might want to support steering wheels or guitars or whatever later. */ |
| | | if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) { |
| | | AddXInputDevice(userid, pContext); |
| | | } |
| | |
| | | while ( pCurList ) |
| | | { |
| | | JoyStick_DeviceData *pListNext = NULL; |
| | | |
| | | #if SDL_HAPTIC_DINPUT |
| | | if (pCurList->bXInputDevice) { |
| | | XInputHaptic_MaybeRemoveDevice(pCurList->XInputUserId); |
| | | } else { |
| | | DirectInputHaptic_MaybeRemoveDevice(&pCurList->dxdevice); |
| | | } |
| | | #endif |
| | | |
| | | #if !SDL_EVENTS_DISABLED |
| | | { |
| | | SDL_Event event; |
| | | event.type = SDL_JOYDEVICEREMOVED; |
| | | |
| | |
| | | || (*SDL_EventOK) (SDL_EventOKParam, &event)) { |
| | | SDL_PushEvent(&event); |
| | | } |
| | | } |
| | | } |
| | | #endif /* !SDL_EVENTS_DISABLED */ |
| | | |
| | |
| | | { |
| | | if ( pNewJoystick->send_add_event ) |
| | | { |
| | | #if SDL_HAPTIC_DINPUT |
| | | if (pNewJoystick->bXInputDevice) { |
| | | XInputHaptic_MaybeAddDevice(pNewJoystick->XInputUserId); |
| | | } else { |
| | | DirectInputHaptic_MaybeAddDevice(&pNewJoystick->dxdevice); |
| | | } |
| | | #endif |
| | | |
| | | #if !SDL_EVENTS_DISABLED |
| | | { |
| | | SDL_Event event; |
| | | event.type = SDL_JOYDEVICEADDED; |
| | | |
| | |
| | | || (*SDL_EventOK) (SDL_EventOKParam, &event)) { |
| | | SDL_PushEvent(&event); |
| | | } |
| | | } |
| | | } |
| | | #endif /* !SDL_EVENTS_DISABLED */ |
| | | pNewJoystick->send_add_event = 0; |
| | |
| | | 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, 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_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) |
| | | { |