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