[v2 3/3] xinput/tests: Implemented interactive tests
Juan Jose Gonzalez
juanj.gh at gmail.com
Fri Feb 26 14:23:45 CST 2016
Signed-off-by: Juan Jose Gonzalez <juanj.gh at gmail.com>
---
dlls/xinput1_3/tests/xinput.c | 236 ++++++++++++++++++++++++++++++++++--------
1 file changed, 195 insertions(+), 41 deletions(-)
diff --git a/dlls/xinput1_3/tests/xinput.c b/dlls/xinput1_3/tests/xinput.c
index 2a07f2d..276df4e 100644
--- a/dlls/xinput1_3/tests/xinput.c
+++ b/dlls/xinput1_3/tests/xinput.c
@@ -1,6 +1,8 @@
/*
- * The Wine project - Xinput Joystick Library
+ * The Wine project - XInput Joystick Library
+ *
* Copyright 2008 Andrew Fenn
+ * Copyright 2016 Juan Jose Gonzalez
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,6 +25,12 @@
#include "xinput.h"
#include "wine/test.h"
+#define ENUMSTRING(e) case (e): return #e;
+
+static const int INTERACTIVE_LOOP_DELAY_MS = 100;
+static const int INTERACTIVE_LOOP_COUNT = 150;
+static const int INTERACTIVE_RUMBLE_DELAY_MS = 1000;
+
static DWORD (WINAPI *pXInputGetState)(DWORD, XINPUT_STATE*);
static DWORD (WINAPI *pXInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
static DWORD (WINAPI *pXInputSetState)(DWORD, XINPUT_VIBRATION*);
@@ -31,29 +39,96 @@ static DWORD (WINAPI *pXInputGetKeystroke)(DWORD, DWORD, PXINPUT_KEYSTROKE);
static DWORD (WINAPI *pXInputGetDSoundAudioDeviceGuids)(DWORD, GUID*, GUID*);
static DWORD (WINAPI *pXInputGetBatteryInformation)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
+
+static const char* get_vk_string(WORD VirtualKey) {
+ switch (VirtualKey) {
+ ENUMSTRING(VK_PAD_A)
+ ENUMSTRING(VK_PAD_B)
+ ENUMSTRING(VK_PAD_X)
+ ENUMSTRING(VK_PAD_Y)
+ ENUMSTRING(VK_PAD_RSHOULDER)
+ ENUMSTRING(VK_PAD_LSHOULDER)
+ ENUMSTRING(VK_PAD_LTRIGGER)
+ ENUMSTRING(VK_PAD_RTRIGGER)
+ ENUMSTRING(VK_PAD_DPAD_UP)
+ ENUMSTRING(VK_PAD_DPAD_DOWN)
+ ENUMSTRING(VK_PAD_DPAD_LEFT)
+ ENUMSTRING(VK_PAD_DPAD_RIGHT)
+ ENUMSTRING(VK_PAD_START)
+ ENUMSTRING(VK_PAD_BACK)
+ ENUMSTRING(VK_PAD_LTHUMB_PRESS)
+ ENUMSTRING(VK_PAD_RTHUMB_PRESS)
+ ENUMSTRING(VK_PAD_LTHUMB_UP)
+ ENUMSTRING(VK_PAD_LTHUMB_DOWN)
+ ENUMSTRING(VK_PAD_LTHUMB_RIGHT)
+ ENUMSTRING(VK_PAD_LTHUMB_LEFT)
+ ENUMSTRING(VK_PAD_LTHUMB_UPLEFT)
+ ENUMSTRING(VK_PAD_LTHUMB_UPRIGHT)
+ ENUMSTRING(VK_PAD_LTHUMB_DOWNRIGHT)
+ ENUMSTRING(VK_PAD_LTHUMB_DOWNLEFT)
+ ENUMSTRING(VK_PAD_RTHUMB_UP)
+ ENUMSTRING(VK_PAD_RTHUMB_DOWN)
+ ENUMSTRING(VK_PAD_RTHUMB_RIGHT)
+ ENUMSTRING(VK_PAD_RTHUMB_LEFT)
+ ENUMSTRING(VK_PAD_RTHUMB_UPLEFT)
+ ENUMSTRING(VK_PAD_RTHUMB_UPRIGHT)
+ ENUMSTRING(VK_PAD_RTHUMB_DOWNRIGHT)
+ ENUMSTRING(VK_PAD_RTHUMB_DOWNLEFT)
+ }
+ return "--UNKNOWN--";
+}
+
static void test_set_state(void)
{
XINPUT_VIBRATION vibrator;
DWORD controllerNum;
DWORD result;
+ pXInputEnable(1);
+
for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
{
ZeroMemory(&vibrator, sizeof(XINPUT_VIBRATION));
- vibrator.wLeftMotorSpeed = 0;
+ if (winetest_interactive)
+ trace("Controller %1d: Vibration sequence [left -> off -> left -> right -> off] in 1s intervals\n",
+ controllerNum);
+
+ vibrator.wLeftMotorSpeed = 0xffff;
vibrator.wRightMotorSpeed = 0;
result = pXInputSetState(controllerNum, &vibrator);
ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputSetState failed with (%d)\n", result);
+ if (result == ERROR_DEVICE_NOT_CONNECTED) {
+ skip("Controller %d is not connected\n", controllerNum);
+ continue;
+ }
+
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_RUMBLE_DELAY_MS);
+
pXInputEnable(0);
- vibrator.wLeftMotorSpeed = 65535;
- vibrator.wRightMotorSpeed = 65535;
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_RUMBLE_DELAY_MS);
+
+ pXInputEnable(1);
+
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_RUMBLE_DELAY_MS);
+
+ vibrator.wLeftMotorSpeed = 0;
+ vibrator.wRightMotorSpeed = 0xffff;
result = pXInputSetState(controllerNum, &vibrator);
ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputSetState failed with (%d)\n", result);
- pXInputEnable(1);
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_RUMBLE_DELAY_MS);
+
+ vibrator.wLeftMotorSpeed = 0;
+ vibrator.wRightMotorSpeed = 0;
+ result = pXInputSetState(controllerNum, &vibrator);
+ ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputSetState failed with (%d)\n", result);
}
result = pXInputSetState(XUSER_MAX_COUNT+1, &vibrator);
@@ -62,35 +137,53 @@ static void test_set_state(void)
static void test_get_state(void)
{
-
XINPUT_STATE controllerState;
DWORD controllerNum;
DWORD result;
+ int i, count;
+ char oldstate[248], curstate[248];
for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
{
- 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
- {
- trace("-- Results for controller %d --\n", controllerNum);
- trace("XInputGetState: %d\n", result);
- trace("State->dwPacketNumber: %d\n", controllerState.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);
+ if (winetest_interactive) {
+ trace("Testing controller %1d\n", controllerNum);
+ trace("You have %d seconds to test all axes, sliders, POVs and buttons\n",
+ (INTERACTIVE_LOOP_DELAY_MS * INTERACTIVE_LOOP_COUNT) / 1000);
+ count = INTERACTIVE_LOOP_COUNT;
+ } else
+ count = 1;
+
+ for (i = count; i > 0; 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);
+ break;
+ }
+ else
+ {
+ sprintf(curstate, "PN0x%08x: BTN0x%04x"
+ " LX%6d LY%6d RX%6d RY%6d LT%3u RT%3u",
+ controllerState.dwPacketNumber,
+ controllerState.Gamepad.wButtons,
+ controllerState.Gamepad.sThumbLX,
+ controllerState.Gamepad.sThumbLY,
+ controllerState.Gamepad.sThumbRX,
+ controllerState.Gamepad.sThumbRY,
+ controllerState.Gamepad.bLeftTrigger,
+ controllerState.Gamepad.bRightTrigger);
+ if (strcmp(oldstate, curstate) != 0) {
+ trace("%s\n", curstate);
+ strcpy(oldstate, curstate);
+ }
+ }
+
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_LOOP_DELAY_MS);
}
}
@@ -99,24 +192,81 @@ static void test_get_state(void)
ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
}
-static void test_get_keystroke(void)
-{
+static void test_get_keystroke_single(DWORD controllerNum) {
XINPUT_KEYSTROKE keystroke;
- DWORD controllerNum;
DWORD result;
+ int i, count;
+ const char *flagsString;
- for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
- {
+ if (winetest_interactive) {
+ if (controllerNum == XUSER_INDEX_ANY)
+ trace("Testing all controllers at the same time\n");
+ else
+ trace("Testing controller %1d\n", controllerNum);
+ trace("You have %d seconds to test all axes, sliders, POVs and buttons\n",
+ (INTERACTIVE_LOOP_DELAY_MS * INTERACTIVE_LOOP_COUNT) / 1000);
+ count = INTERACTIVE_LOOP_COUNT;
+ } else
+ count = 1;
+
+ for (i = count; i > 0; i--) {
ZeroMemory(&keystroke, sizeof(XINPUT_KEYSTROKE));
- result = pXInputGetKeystroke(controllerNum, XINPUT_FLAG_GAMEPAD, &keystroke);
- ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetKeystroke failed with (%d)\n", result);
+ /* Checking for keystroke.Flags != 0 due to a bug in Microsoft's xinput1_3 XInputGetKeystroke
+ * function that returns ERROR_SUCCESS and Flags = 0 instead of ERROR_DEVICE_NOT_CONNECTED */
+ while ((result = pXInputGetKeystroke(controllerNum, XINPUT_FLAG_GAMEPAD, &keystroke))
+ == ERROR_SUCCESS && keystroke.Flags != 0) {
+ switch (keystroke.Flags) {
+ case XINPUT_KEYSTROKE_KEYDOWN:
+ flagsString = "D ";
+ break;
+ case XINPUT_KEYSTROKE_KEYDOWN | XINPUT_KEYSTROKE_REPEAT:
+ flagsString = "DR";
+ break;
+ case XINPUT_KEYSTROKE_KEYUP:
+ flagsString = "U ";
+ break;
+ case XINPUT_KEYSTROKE_KEYUP | XINPUT_KEYSTROKE_REPEAT:
+ flagsString = "UR";
+ break;
+ default:
+ flagsString = NULL;
+ }
+ ok(flagsString != NULL, "XInputGetKeystroke set Flags to (%d)\n",
+ keystroke.Flags);
+ if (flagsString == NULL)
+ break;
+
+ trace("%s: VK(%5d: %s) Unicode(%4x) Idx(%1d) HidCode(%2x)\n",
+ flagsString, keystroke.VirtualKey, get_vk_string(keystroke.VirtualKey), keystroke.Unicode,
+ keystroke.UserIndex, keystroke.HidCode);
+ }
+ ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED || result == ERROR_EMPTY,
+ "XInputGetKeystroke failed with (%d)\n", result);
+ if (result != ERROR_SUCCESS && result != ERROR_DEVICE_NOT_CONNECTED && result != ERROR_EMPTY)
+ break;
- if (ERROR_DEVICE_NOT_CONNECTED == result)
- {
+ if (result == ERROR_DEVICE_NOT_CONNECTED || (result == ERROR_SUCCESS && keystroke.Flags == 0)) {
skip("Controller %d is not connected\n", controllerNum);
+ break;
}
+
+ if (winetest_interactive)
+ Sleep(INTERACTIVE_LOOP_DELAY_MS);
}
+}
+
+static void test_get_keystroke(void)
+{
+ XINPUT_KEYSTROKE keystroke;
+ DWORD controllerNum;
+ DWORD result;
+
+ for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
+ {
+ test_get_keystroke_single(controllerNum);
+ }
+ test_get_keystroke_single(XUSER_INDEX_ANY);
ZeroMemory(&keystroke, sizeof(XINPUT_KEYSTROKE));
result = pXInputGetKeystroke(XUSER_MAX_COUNT+1, XINPUT_FLAG_GAMEPAD, &keystroke);
@@ -139,6 +289,9 @@ static void test_get_capabilities(void)
if (ERROR_DEVICE_NOT_CONNECTED == result)
{
skip("Controller %d is not connected\n", controllerNum);
+ } else {
+ ok(capabilities.Type == XINPUT_DEVTYPE_GAMEPAD, "XInputGetCapabilities returned Type (%d)\n",
+ capabilities.Type);
}
}
@@ -182,11 +335,12 @@ static void test_get_batteryinformation(void)
result = pXInputGetBatteryInformation(controllerNum, BATTERY_DEVTYPE_GAMEPAD, &batteryInfo);
ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetBatteryInformation failed with (%d)\n", result);
- if (ERROR_DEVICE_NOT_CONNECTED == result)
- {
- ok(batteryInfo.BatteryLevel == BATTERY_TYPE_DISCONNECTED, "Failed to report device as being disconnected.\n");
+ if (ERROR_DEVICE_NOT_CONNECTED == result) {
+ ok(batteryInfo.BatteryType == BATTERY_TYPE_DISCONNECTED, "Failed to report device as being disconnected.\n");
skip("Controller %d is not connected\n", controllerNum);
- }
+ } else if (ERROR_SUCCESS == result)
+ trace("Controller %d Battery: Type=%3u Level=%3u\n", controllerNum, batteryInfo.BatteryType,
+ batteryInfo.BatteryLevel);
}
result = pXInputGetBatteryInformation(XUSER_MAX_COUNT+1, BATTERY_DEVTYPE_GAMEPAD, &batteryInfo);
--
2.7.1
More information about the wine-patches
mailing list