dinput joystick buffered mode

Robert Reif reif at earthlink.net
Sat Sep 11 12:16:05 CDT 2004


Robert Reif wrote:

> Add buffered mode to joystick.
> Add JoystickWImpl_GetDeviceInfo.
>
>  
>
Sorry, wrong one.
-------------- next part --------------
Index: dlls/dinput/device_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dinput/device_private.h,v
retrieving revision 1.11
diff -u -r1.11 device_private.h
--- dlls/dinput/device_private.h	8 Sep 2004 01:37:25 -0000	1.11
+++ dlls/dinput/device_private.h	11 Sep 2004 17:13:31 -0000
@@ -70,7 +70,8 @@
       This->data_queue[This->queue_head].dwTimeStamp = xtime;			\
       This->data_queue[This->queue_head].dwSequence = seq;			\
       This->queue_head = nq;							\
-    }										\
+    } else                                                                      \
+      This->overflow = TRUE;                                                    \
   }										\
 }
 
Index: dlls/dinput/joystick_linux.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/joystick_linux.c,v
retrieving revision 1.14
diff -u -r1.14 joystick_linux.c
--- dlls/dinput/joystick_linux.c	9 Sep 2004 20:17:08 -0000	1.14
+++ dlls/dinput/joystick_linux.c	11 Sep 2004 17:13:33 -0000
@@ -23,8 +23,7 @@
  * To Do:
  *	support more than one device
  *	dead zone
- *	buffered mode
- *	force feadback
+ *	force feedback
  */
 
 #include "config.h"
@@ -114,6 +113,8 @@
 	int				axes;
 	int				buttons;
 	POV				povs[4];
+	CRITICAL_SECTION		crit;
+	BOOL				overflow;
 };
 
 static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
@@ -473,6 +474,7 @@
     newDevice->ref = 1;
     newDevice->dinput = dinput;
     newDevice->acquired = FALSE;
+    newDevice->overflow = FALSE;
     CopyMemory(&(newDevice->guid),rguid,sizeof(*rguid));
 
     /* setup_dinput_options may change these */
@@ -534,6 +536,8 @@
     calculate_ids(newDevice);
 
     IDirectInputDevice_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->dinput);
+    InitializeCriticalSection(&(newDevice->crit));
+    newDevice->crit.DebugInfo->Spare[1] = (DWORD)"DINPUT_Mouse";
 
     newDevice->devcaps.dwSize = sizeof(newDevice->devcaps);
     newDevice->devcaps.dwFlags = DIDC_ATTACHED;
@@ -666,6 +670,8 @@
     /* release the data transform filter */
     release_DataFormat(This->transform);
 
+    This->crit.DebugInfo->Spare[1] = 0;
+    DeleteCriticalSection(&(This->crit));
     IDirectInputDevice_Release((LPDIRECTINPUTDEVICE8A)This->dinput);
 
     HeapFree(GetProcessHeap(),0,This);
@@ -829,7 +835,7 @@
     return -1;
 }
 
-static void calculate_pov(JoystickImpl *This, int index)
+static LONG calculate_pov(JoystickImpl *This, int index)
 {
     if (This->povs[index].lX < 16384) {
         if (This->povs[index].lY < 16384)
@@ -853,6 +859,8 @@
         else
             This->js.rgdwPOV[index] = -1;
     }
+
+    return This->js.rgdwPOV[index];
 }
 
 static void joy_polldev(JoystickImpl *This) {
@@ -923,28 +931,28 @@
                         This->povs[0].lX = value;
                     else if (This->axis_map[jse.number - 1] == number)
                         This->povs[0].lY = value;
-                    calculate_pov(This, 0);
+                    value = calculate_pov(This, 0);
                     break;
                 case 9:
                     if (This->axis_map[jse.number + 1] == number)
                         This->povs[1].lX = value;
                     else if (This->axis_map[jse.number - 1] == number)
                         This->povs[1].lY = value;
-                    calculate_pov(This, 1);
+                    value = calculate_pov(This, 1);
                     break;
                 case 10:
                     if (This->axis_map[jse.number + 1] == number)
                         This->povs[2].lX = value;
                     else if (This->axis_map[jse.number - 1] == number)
                         This->povs[2].lY = value;
-                    calculate_pov(This, 2);
+                    value = calculate_pov(This, 2);
                     break;
                 case 11:
                     if (This->axis_map[jse.number + 1] == number)
                         This->povs[3].lX = value;
                     else if (This->axis_map[jse.number - 1] == number)
                         This->povs[3].lY = value;
-                    calculate_pov(This, 3);
+                    value = calculate_pov(This, 3);
                     break;
                 }
 
@@ -993,24 +1001,75 @@
     DWORD flags)
 {
     JoystickImpl *This = (JoystickImpl *)iface;
+    DWORD len;
+    int nqtail;
+    HRESULT hr = DI_OK;
 
-    FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
+    TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
 
     if (!This->acquired) {
         WARN("not acquired\n");
         return DIERR_NOTACQUIRED;
     }
 
+    EnterCriticalSection(&(This->crit));
+
     joy_polldev(This);
 
-    if (flags & DIGDD_PEEK)
-        FIXME("DIGDD_PEEK\n");
-    *entries = 0;
+    len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
+        + (This->queue_head - This->queue_tail);
+    if (len > *entries)
+        len = *entries;
 
     if (dod == NULL) {
+        if (len)
+            TRACE("Application discarding %ld event(s).\n", len);
+
+        *entries = len;
+        nqtail = This->queue_tail + len;
+        while (nqtail >= This->queue_len)
+            nqtail -= This->queue_len;
     } else {
+        if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) {
+            ERR("Wrong structure size !\n");
+            LeaveCriticalSection(&(This->crit));
+            return DIERR_INVALIDPARAM;
+        }
+
+        if (len)
+            TRACE("Application retrieving %ld event(s).\n", len);
+
+        *entries = 0;
+        nqtail = This->queue_tail;
+        while (len) {
+            DWORD span = ((This->queue_head < nqtail) ? This->queue_len : This->queue_head) - nqtail;
+            if (span > len)
+                span = len;
+
+            /* Copy the buffered data into the application queue */
+            memcpy(dod + *entries, This->data_queue + nqtail, span * dodsize);
+            /* Advance position */
+            nqtail += span;
+            if (nqtail >= This->queue_len)
+                nqtail -= This->queue_len;
+            *entries += span;
+            len -= span;
+        }
     }
-    return DI_OK;
+
+    if (This->overflow) {
+        hr = DI_BUFFEROVERFLOW;
+        if (!(flags & DIGDD_PEEK)) {
+            This->overflow = FALSE;
+        }
+    }
+
+    if (!(flags & DIGDD_PEEK))
+        This->queue_tail = nqtail;
+
+    LeaveCriticalSection(&(This->crit));
+
+    return hr;
 }
 
 int find_property(JoystickImpl * This, LPCDIPROPHEADER ph)
@@ -1049,7 +1108,14 @@
         switch ((DWORD)rguid) {
         case (DWORD) DIPROP_BUFFERSIZE: {
             LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
-            FIXME("buffersize = %ld\n",pd->dwData);
+            TRACE("buffersize = %ld\n",pd->dwData);
+            if (This->data_queue)
+                This->data_queue = HeapReAlloc(GetProcessHeap(),0, This->data_queue, pd->dwData * sizeof(DIDEVICEOBJECTDATA));
+            else
+                This->data_queue = HeapAlloc(GetProcessHeap(),0, pd->dwData * sizeof(DIDEVICEOBJECTDATA));
+            This->queue_head = 0;
+            This->queue_tail = 0;
+            This->queue_len  = pd->dwData;
             break;
         }
         case (DWORD)DIPROP_RANGE: {
@@ -1504,6 +1570,44 @@
     return DI_OK;
 }
 
+/******************************************************************************
+  *     GetDeviceInfo : get information about a device's identity
+  */
+HRESULT WINAPI JoystickWImpl_GetDeviceInfo(
+    LPDIRECTINPUTDEVICE8W iface,
+    LPDIDEVICEINSTANCEW pdidi)
+{
+    JoystickImpl *This = (JoystickImpl *)iface;
+
+    TRACE("(%p,%p)\n", iface, pdidi);
+
+    if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
+        (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW))) {
+        WARN("invalid parameter: pdidi->dwSize = %ld != %d or %d\n",
+             pdidi->dwSize, sizeof(DIDEVICEINSTANCE_DX3W),
+             sizeof(DIDEVICEINSTANCEW));
+        return DIERR_INVALIDPARAM;
+    }
+
+    /* Return joystick */
+    pdidi->guidInstance = GUID_Joystick;
+    pdidi->guidProduct = DInput_Wine_Joystick_GUID;
+    /* we only support traditional joysticks for now */
+    if (This->dinput->version >= 8)
+        pdidi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+    else
+        pdidi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+    MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, pdidi->tszInstanceName, MAX_PATH);
+    MultiByteToWideChar(CP_ACP, 0, This->name, -1, pdidi->tszProductName, MAX_PATH);
+    if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3W)) {
+        pdidi->guidFFDriver = GUID_NULL;
+        pdidi->wUsagePage = 0;
+        pdidi->wUsage = 0;
+    }
+
+    return DI_OK;
+}
+
 static IDirectInputDevice8AVtbl JoystickAvt =
 {
 	IDirectInputDevice2AImpl_QueryInterface,
@@ -1563,7 +1667,7 @@
 	XCAST(SetEventNotification)JoystickAImpl_SetEventNotification,
 	XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
 	IDirectInputDevice2WImpl_GetObjectInfo,
-	IDirectInputDevice2WImpl_GetDeviceInfo,
+	JoystickWImpl_GetDeviceInfo,
 	XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
 	XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
 	XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
Index: dlls/dinput/joystick_linuxinput.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/joystick_linuxinput.c,v
retrieving revision 1.9
diff -u -r1.9 joystick_linuxinput.c
--- dlls/dinput/joystick_linuxinput.c	9 Sep 2004 20:17:08 -0000	1.9
+++ dlls/dinput/joystick_linuxinput.c	11 Sep 2004 17:13:33 -0000
@@ -98,6 +98,7 @@
         HANDLE				hEvent;
         LPDIDEVICEOBJECTDATA 		data_queue;
         int				queue_head, queue_tail, queue_len;
+	BOOL				overflow;
 	DIJOYSTATE2			js;
 
 	/* data returned by the EVIOCGABS() ioctl */
Index: dlls/dinput/mouse.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/mouse.c,v
retrieving revision 1.8
diff -u -r1.8 mouse.c
--- dlls/dinput/mouse.c	9 Sep 2004 20:17:08 -0000	1.8
+++ dlls/dinput/mouse.c	11 Sep 2004 17:13:33 -0000
@@ -133,6 +133,7 @@
     DWORD			    win_centerX, win_centerY;
     LPDIDEVICEOBJECTDATA 	    data_queue;
     int				    queue_head, queue_tail, queue_len;
+    BOOL			    overflow;
     /* warping: whether we need to move mouse back to middle once we
      * reach window borders (for e.g. shooters, "surface movement" games) */
     WARP_STATUS		            need_warp;


More information about the wine-patches mailing list