joystick GetDeviceState

Rob Crittenden <[email protected]>
Newsgroups gmane.comp.emulators.winex.devel
Message-ID <[email protected]>
I implemented the Joystick function GetDeviceState based on the existing
mouse and keyboard functions (though mostly mouse). This required a minor
change to the mouse code to add an overflow flag. I'm not actually doing
anything with it in mouse but it needs to be there since mouse and joystick
share the same queueing code.

I haven't had luck testing this with BF1942 yet. The keymapping is very
strange and once I map a joystick axis, clicking on any other field tries to
map that same axis again. I was able to map a button to fire ok but it
didn't actually work for me. No events end up being returned.

Testing with some modified sample code from the DX 9 SDK seems to work fine.

In any case, it's a start. As usual, you have license to use it in WineX.

rob

_______________________________________________
winex-devel mailing list
[email protected]
http://lists.transgaming.org/cgi-bin/mailman/listinfo/winex-devel
joystick.diff (text/plain, 5.5 KB)
Index: dinput/device_private.h
===================================================================
RCS file: /cvsroot/winex/dlls/dinput/device_private.h,v
retrieving revision 1.11
diff -u -r1.11 device_private.h
--- dinput/device_private.h	15 Nov 2003 01:15:01 -0000	1.11
+++ dinput/device_private.h	23 Feb 2004 15:14:52 -0000
@@ -58,6 +58,8 @@
       This->data_queue[This->queue_head].dwSequence = seq;			\
       This->queue_head = nq;							\
     }										\
+    else									\
+      This->overflow = TRUE;							\
   }										\
 }
 
Index: dinput/joystick/main.c
===================================================================
RCS file: /cvsroot/winex/dlls/dinput/joystick/main.c,v
retrieving revision 1.7
diff -u -r1.7 main.c
--- dinput/joystick/main.c	18 Feb 2004 22:27:38 -0000	1.7
+++ dinput/joystick/main.c	23 Feb 2004 15:14:55 -0000
@@ -83,8 +83,10 @@
 	DataFormat*			wine_df;
 	ObjProps*			props;
         HANDLE				hEvent;
+        CRITICAL_SECTION                crit;
         LPDIDEVICEOBJECTDATA 		data_queue;
         int				queue_head, queue_tail, queue_len;
+        BOOL				overflow;
 
 	/* effects */
 	DWORD				dwAutoCenter;
@@ -208,9 +210,13 @@
       newDevice->props[u].lMax = 0xFFFF;
       newDevice->props[u].lDeadZone = 1000; /* 10% */
       newDevice->props[u].lSaturation = 0; /* 0% */
+      newDevice->queue_len = -1; /* unbuffered */
+      newDevice->overflow = FALSE;
     }
   }
 
+  InitializeCriticalSection(&(newDevice->crit));
+
   newDevice->dwGain = 10000;
   newDevice->dwAutoCenter = 0;
   for (u=0; u<MAX_EFFECTS; u++)
@@ -292,6 +298,8 @@
   if (This->data_queue != NULL)
     HeapFree(GetProcessHeap(),0,This->data_queue);
 
+  DeleteCriticalSection(&(This->crit));
+
   /* Free the DataFormat */
   HeapFree(GetProcessHeap(), 0, This->offset_array);
   HeapFree(GetProcessHeap(), 0, This->buffer);
@@ -448,21 +456,56 @@
 					      DWORD flags
 ) {
   ICOM_THIS(JoystickAImpl,iface);
+  DWORD len, count, nqtail;
+  int ret = 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)
     return DIERR_NOTACQUIRED;
 
-  joy_polldev(This, FALSE, TRUE);
-  if (flags & DIGDD_PEEK)
-    FIXME("DIGDD_PEEK\n");
-  *entries = 0;
+  if (This->queue_len == -1)
+    return DIERR_NOTBUFFERED;
+
+  if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
+    return DIERR_INVALIDPARAM;
 
-  if (dod == NULL) {
-  } else {
+  EnterCriticalSection(&(This->crit));
+
+  len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
+      + (This->queue_head - This->queue_tail);
+  if (len > *entries) len = *entries;
+
+  count = 0;
+  nqtail = This->queue_tail;
+  while ((count < *entries || *entries == INFINITE) && count < len) {
+    if (dod != NULL) {
+      LPDIDEVICEOBJECTDATA pd = (LPDIDEVICEOBJECTDATA)((BYTE *)dod + dodsize * count);
+      pd->dwOfs       = This->data_queue[nqtail].dwOfs;
+      pd->dwData      = This->data_queue[nqtail].dwData;
+      pd->dwTimeStamp = This->data_queue[nqtail].dwTimeStamp;
+      pd->dwSequence  = This->data_queue[nqtail].dwSequence;
+    }
+    nqtail++;
+    if (nqtail >= This->queue_len) nqtail -= This->queue_len;
+    count++;
   }
-  return 0;
+
+  if (This->overflow)
+    ret = DI_BUFFEROVERFLOW;
+
+  if (!(flags & DIGDD_PEEK)) {
+    This->queue_tail = nqtail;
+    This->overflow = FALSE;
+  }
+
+  TRACE("%s %ld events %s\n", *entries == INFINITE ? "Flushing" : "Returning", count, ret == DI_OK ? "" : "BUFFEROVERFLOW");
+
+  *entries = count;
+
+  LeaveCriticalSection(&(This->crit));
+
+  return ret;
 }
 
 int find_object(JoystickAImpl *This, DWORD dwHow, DWORD dwObj)
@@ -519,7 +562,13 @@
     case (DWORD) DIPROP_BUFFERSIZE: {
       LPCDIPROPDWORD	pd = (LPCDIPROPDWORD)ph;
 
-      FIXME("buffersize = %ld\n",pd->dwData);
+      TRACE("buffersize(%ld)\n", pd->dwData);
+     
+      This->data_queue = (LPDIDEVICEOBJECTDATA)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: {
Index: dinput/mouse/main.c
===================================================================
RCS file: /cvsroot/winex/dlls/dinput/mouse/main.c,v
retrieving revision 1.47
diff -u -r1.47 main.c
--- dinput/mouse/main.c	18 Feb 2004 22:27:38 -0000	1.47
+++ dinput/mouse/main.c	23 Feb 2004 15:14:58 -0000
@@ -136,6 +136,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;
Index: wininet/http.c
===================================================================
RCS file: /cvsroot/winex/dlls/wininet/http.c,v
retrieving revision 1.14
diff -u -r1.14 http.c
--- wininet/http.c	20 Feb 2004 12:50:35 -0000	1.14
+++ wininet/http.c	23 Feb 2004 15:15:07 -0000
@@ -153,10 +153,10 @@
         LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
 {
     CHAR *szHeader = NULL;
+    BOOL ret = FALSE;
 
     TRACE("->\n");
 
-    BOOL ret = FALSE;
 
     if (lpszHeader)
     {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.