diff --git a/dlls/xinput1_3/tests/xinput.c b/dlls/xinput1_3/tests/xinput.c index 2a07f2d76b9..5261425f0ea 100644 --- a/dlls/xinput1_3/tests/xinput.c +++ b/dlls/xinput1_3/tests/xinput.c @@ -24,6 +24,7 @@ #include "wine/test.h" static DWORD (WINAPI *pXInputGetState)(DWORD, XINPUT_STATE*); +static DWORD (WINAPI *pXInputGetStateEx)(DWORD, XINPUT_STATE_EX*); static DWORD (WINAPI *pXInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*); static DWORD (WINAPI *pXInputSetState)(DWORD, XINPUT_VIBRATION*); static void (WINAPI *pXInputEnable)(BOOL); @@ -62,41 +63,63 @@ static void test_set_state(void) static void test_get_state(void) { - - XINPUT_STATE controllerState; - DWORD controllerNum; + union + { + XINPUT_STATE state; + XINPUT_STATE_EX state_ex; + } xinput; + DWORD controllerNum, i; DWORD result; - for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++) + for (i = 0; i < (pXInputGetStateEx ? 2 : 1); i++) { - ZeroMemory(&controllerState, sizeof(XINPUT_STATE)); - - result = pXInputGetState(controllerNum, &controllerState); - ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetState failed with (%d)\n", result); - - if (ERROR_DEVICE_NOT_CONNECTED == result) - { - skip("Controller %d is not connected\n", controllerNum); - } - else + for (controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++) { + ZeroMemory(&xinput, sizeof(xinput)); + + if (i == 0) + result = pXInputGetState(controllerNum, &xinput.state); + else + result = pXInputGetStateEx(controllerNum, &xinput.state_ex); + ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, + "%s failed with (%d)\n", i == 0 ? "XInputGetState" : "XInputGetStateEx", result); + + if (ERROR_DEVICE_NOT_CONNECTED == result) + { + skip("Controller %d is not connected\n", controllerNum); + continue; + } + trace("-- Results for controller %d --\n", controllerNum); - trace("XInputGetState: %d\n", result); - trace("State->dwPacketNumber: %d\n", controllerState.dwPacketNumber); + if (i == 0) + trace("XInputGetState: %d\n", result); + else + trace("XInputGetStateEx: %d\n", result); + trace("State->dwPacketNumber: %d\n", xinput.state.dwPacketNumber); trace("Gamepad Variables --\n"); - trace("Gamepad.wButtons: %#x\n", controllerState.Gamepad.wButtons); - trace("Gamepad.bLeftTrigger: 0x%08x\n", controllerState.Gamepad.bLeftTrigger); - trace("Gamepad.bRightTrigger: 0x%08x\n", controllerState.Gamepad.bRightTrigger); - trace("Gamepad.sThumbLX: %d\n", controllerState.Gamepad.sThumbLX); - trace("Gamepad.sThumbLY: %d\n", controllerState.Gamepad.sThumbLY); - trace("Gamepad.sThumbRX: %d\n", controllerState.Gamepad.sThumbRX); - trace("Gamepad.sThumbRY: %d\n", controllerState.Gamepad.sThumbRY); + trace("Gamepad.wButtons: %#x\n", xinput.state.Gamepad.wButtons); + trace("Gamepad.bLeftTrigger: 0x%08x\n", xinput.state.Gamepad.bLeftTrigger); + trace("Gamepad.bRightTrigger: 0x%08x\n", xinput.state.Gamepad.bRightTrigger); + trace("Gamepad.sThumbLX: %d\n", xinput.state.Gamepad.sThumbLX); + trace("Gamepad.sThumbLY: %d\n", xinput.state.Gamepad.sThumbLY); + trace("Gamepad.sThumbRX: %d\n", xinput.state.Gamepad.sThumbRX); + trace("Gamepad.sThumbRY: %d\n", xinput.state.Gamepad.sThumbRY); } } - ZeroMemory(&controllerState, sizeof(XINPUT_STATE)); - result = pXInputGetState(XUSER_MAX_COUNT+1, &controllerState); + result = pXInputGetState(XUSER_MAX_COUNT, &xinput.state); ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result); + + result = pXInputGetState(XUSER_MAX_COUNT+1, &xinput.state); + ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result); + if (pXInputGetStateEx) + { + result = pXInputGetStateEx(XUSER_MAX_COUNT, &xinput.state_ex); + ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result); + + result = pXInputGetStateEx(XUSER_MAX_COUNT+1, &xinput.state_ex); + ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result); + } } static void test_get_keystroke(void) @@ -196,6 +219,7 @@ static void test_get_batteryinformation(void) START_TEST(xinput) { HMODULE hXinput; + void *pXInputGetStateEx_Ordinal; hXinput = LoadLibraryA( "xinput1_3.dll" ); if (!hXinput) @@ -207,11 +231,18 @@ START_TEST(xinput) pXInputEnable = (void*)GetProcAddress(hXinput, "XInputEnable"); pXInputSetState = (void*)GetProcAddress(hXinput, "XInputSetState"); pXInputGetState = (void*)GetProcAddress(hXinput, "XInputGetState"); + pXInputGetStateEx = (void*)GetProcAddress(hXinput, "XInputGetStateEx"); /* Win >= 8 */ + pXInputGetStateEx_Ordinal = (void*)GetProcAddress(hXinput, (LPCSTR) 100); pXInputGetKeystroke = (void*)GetProcAddress(hXinput, "XInputGetKeystroke"); pXInputGetCapabilities = (void*)GetProcAddress(hXinput, "XInputGetCapabilities"); pXInputGetDSoundAudioDeviceGuids = (void*)GetProcAddress(hXinput, "XInputGetDSoundAudioDeviceGuids"); pXInputGetBatteryInformation = (void*)GetProcAddress(hXinput, "XInputGetBatteryInformation"); + if (pXInputGetStateEx_Ordinal) + ok (pXInputGetStateEx_Ordinal == pXInputGetStateEx, "XInputGetStateEx in the wrong ordinal\n"); + else + ok (broken(1), "XInputGetStateEx not found in this dll version\n"); + test_set_state(); test_get_state(); test_get_keystroke(); diff --git a/dlls/xinput1_3/xinput1_3.spec b/dlls/xinput1_3/xinput1_3.spec index 67805d1528f..0023016afde 100644 --- a/dlls/xinput1_3/xinput1_3.spec +++ b/dlls/xinput1_3/xinput1_3.spec @@ -6,3 +6,4 @@ 6 stdcall XInputGetDSoundAudioDeviceGuids(long ptr ptr) 7 stdcall XInputGetBatteryInformation(long long ptr) 8 stdcall XInputGetKeystroke(long long ptr) +100 stdcall XInputGetStateEx(long ptr) diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c index a088913ab8b..227ab7ae4a8 100644 --- a/dlls/xinput1_3/xinput1_3_main.c +++ b/dlls/xinput1_3/xinput1_3_main.c @@ -85,6 +85,21 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetState(DWORD index, XINPUT_STATE* state) return ERROR_NOT_SUPPORTED; } +DWORD WINAPI DECLSPEC_HOTPATCH XInputGetStateEx(DWORD index, XINPUT_STATE_EX* state_ex) +{ + static int warn_once; + + if (!warn_once++) + FIXME("(index %u, state %p) Stub!\n", index, state_ex); + + if (index >= XUSER_MAX_COUNT) + return ERROR_BAD_ARGUMENTS; + if (!controllers[index].connected) + return ERROR_DEVICE_NOT_CONNECTED; + + return ERROR_NOT_SUPPORTED; +} + DWORD WINAPI XInputGetKeystroke(DWORD index, DWORD reserved, PXINPUT_KEYSTROKE keystroke) { FIXME("(index %u, reserved %u, keystroke %p) Stub!\n", index, reserved, keystroke); diff --git a/include/xinput.h b/include/xinput.h index 98d23a30af7..ccdc0233431 100644 --- a/include/xinput.h +++ b/include/xinput.h @@ -170,11 +170,27 @@ typedef struct _XINPUT_GAMEPAD { SHORT sThumbRY; } XINPUT_GAMEPAD, *PXINPUT_GAMEPAD; +typedef struct _XINPUT_GAMEPAD_EX { + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; + DWORD dwPaddingReserved; +} XINPUT_GAMEPAD_EX, *PXINPUT_GAMEPAD_EX; + typedef struct _XINPUT_STATE { DWORD dwPacketNumber; XINPUT_GAMEPAD Gamepad; } XINPUT_STATE, *PXINPUT_STATE; +typedef struct _XINPUT_STATE_EX { + DWORD dwPacketNumber; + XINPUT_GAMEPAD_EX Gamepad; +} XINPUT_STATE_EX, *PXINPUT_STATE_EX; + /* * Defines the structure of how much vibration is set on both the * right and left motors in a joystick. If you're not using a 360 @@ -232,6 +248,8 @@ DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*); DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*); DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*); +DWORD WINAPI XInputGetStateEx(DWORD, XINPUT_STATE_EX*); + #ifdef __cplusplus } #endif