Aric Stewart : xinput: Implement XInputSetState.

Alexandre Julliard julliard at winehq.org
Thu Feb 15 14:42:28 CST 2018


Module: wine
Branch: master
Commit: f3391311f3f1b730df97b65cf5650301c5714d16
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f3391311f3f1b730df97b65cf5650301c5714d16

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Feb 14 12:41:44 2018 -0600

xinput: Implement XInputSetState.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/xinput1_3/hid.c            | 42 +++++++++++++++++++++++++++++++++++++++++
 dlls/xinput1_3/xinput_main.c    |  6 ++++--
 dlls/xinput1_3/xinput_private.h |  1 +
 include/xinput.h                |  2 ++
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c
index 5d82f05..33a92e1 100644
--- a/dlls/xinput1_3/hid.c
+++ b/dlls/xinput1_3/hid.c
@@ -192,6 +192,11 @@ static BOOL VerifyGamepad(PHIDP_PREPARSED_DATA ppd, XINPUT_CAPABILITIES *xinput_
 
     xinput_caps->Type = XINPUT_DEVTYPE_GAMEPAD;
     xinput_caps->SubType = XINPUT_DEVSUBTYPE_GAMEPAD;
+
+    value_caps_count = caps->NumberOutputValueCaps;
+    if (value_caps_count > 0)
+        xinput_caps->Flags |= XINPUT_CAPS_FFB_SUPPORTED;
+
     return TRUE;
 }
 
@@ -411,3 +416,40 @@ void HID_update_state(xinput_controller* device)
     device->state.Gamepad.bLeftTrigger = SCALE_BYTE(value, private->LeftTriggerRange);
     LeaveCriticalSection(&private->crit);
 }
+
+DWORD HID_set_state(xinput_controller* device, XINPUT_VIBRATION* state)
+{
+    struct hid_platform_private *private = device->platform_private;
+
+    struct {
+        BYTE report;
+        BYTE pad1[2];
+        BYTE left;
+        BYTE right;
+        BYTE pad2[3];
+    } report;
+
+    if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
+    {
+        BOOLEAN rc;
+
+        device->caps.Vibration.wLeftMotorSpeed = state->wLeftMotorSpeed;
+        device->caps.Vibration.wRightMotorSpeed = state->wRightMotorSpeed;
+
+        report.report = 0;
+        report.pad1[0] = 0x8;
+        report.pad1[1] = 0x0;
+        report.left = (BYTE)(state->wLeftMotorSpeed / 255);
+        report.right = (BYTE)(state->wRightMotorSpeed / 255);
+        memset(&report.pad2, 0, sizeof(report.pad2));
+
+        EnterCriticalSection(&private->crit);
+        rc = HidD_SetOutputReport(private->device, &report, sizeof(report));
+        LeaveCriticalSection(&private->crit);
+        if (rc)
+            return ERROR_SUCCESS;
+        return GetLastError();
+    }
+
+    return ERROR_NOT_SUPPORTED;
+}
diff --git a/dlls/xinput1_3/xinput_main.c b/dlls/xinput1_3/xinput_main.c
index 83ecb71..680aba3 100644
--- a/dlls/xinput1_3/xinput_main.c
+++ b/dlls/xinput1_3/xinput_main.c
@@ -63,14 +63,16 @@ void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable)
 
 DWORD WINAPI XInputSetState(DWORD index, XINPUT_VIBRATION* vibration)
 {
-    FIXME("(index %u, vibration %p) Stub!\n", index, vibration);
+    TRACE("(index %u, vibration %p)\n", index, vibration);
+
+    HID_find_gamepads(controllers);
 
     if (index >= XUSER_MAX_COUNT)
         return ERROR_BAD_ARGUMENTS;
     if (!controllers[index].connected)
         return ERROR_DEVICE_NOT_CONNECTED;
 
-    return ERROR_NOT_SUPPORTED;
+    return HID_set_state(&controllers[index], vibration);
 }
 
 DWORD WINAPI DECLSPEC_HOTPATCH XInputGetState(DWORD index, XINPUT_STATE* state)
diff --git a/dlls/xinput1_3/xinput_private.h b/dlls/xinput1_3/xinput_private.h
index 67ddbe4..c10f869 100644
--- a/dlls/xinput1_3/xinput_private.h
+++ b/dlls/xinput1_3/xinput_private.h
@@ -29,3 +29,4 @@ typedef struct _xinput_controller
 void HID_find_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN;
 void HID_destroy_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN;
 void HID_update_state(xinput_controller* device) DECLSPEC_HIDDEN;
+DWORD HID_set_state(xinput_controller* device, XINPUT_VIBRATION* state) DECLSPEC_HIDDEN;
diff --git a/include/xinput.h b/include/xinput.h
index 99ff0cc..dae8cad 100644
--- a/include/xinput.h
+++ b/include/xinput.h
@@ -156,6 +156,8 @@
 #define XUSER_MAX_COUNT                 4
 #define XUSER_INDEX_ANY                 0x000000FF
 
+#define XINPUT_CAPS_FFB_SUPPORTED       0x0001
+
 /*
  * Defines the structure of an xbox 360 joystick.
  */




More information about the wine-cvs mailing list