xbox 360 emulation with logitech cordless and dinput joy disable

Giovanni Ongaro giovanni.nicola at ticino.com
Tue Jun 12 16:48:53 CDT 2012


-------------- next part --------------
>From 30f04e23857310859e31a44e97425946c9d2edfc Mon Sep 17 00:00:00 2001
From: root <root at joe.(none)>
Date: Tue, 12 Jun 2012 23:36:36 +0200
Subject: patch emulation xbox360 joystick with logitech cordless rumblepad
 also includes fix for disabling dinput joys
many times it is necessary for axis conflicts betwwen dinput and xinput1_3 to disable dinput joysticks this can be done by launching wine in such manner LINIXFORCENOJOY=yes wine <jour>program

---
 dlls/dinput/joystick_linux.c      |   78 ++++------
 dlls/dinput/joystick_linuxinput.c |    9 -
 dlls/xinput1_3/xinput1_3_main.c   |  308 ++++++++++++++++++++++++++++++++-----
 3 files changed, 300 insertions(+), 95 deletions(-)

diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 5afd07c..59662e5 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -43,6 +43,9 @@
 # include <sys/ioctl.h>
 #endif
 #include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+#endif
 #ifdef HAVE_LINUX_IOCTL_H
 # include <linux/ioctl.h>
 #endif
@@ -212,6 +215,8 @@ static INT find_joystick_devices(void)
 
 static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id)
 {
+     if (getenv("LINIXFORCENOJOY") != NULL) return FALSE; /*JoeFix disable joystick*/
+    
     int fd = -1;
 
     if (id >= find_joystick_devices()) return FALSE;
@@ -256,7 +261,8 @@ static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTAN
 static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id)
 {
     int fd = -1;
-
+    if (getenv("LINIXFORCENOJOY") != NULL) return FALSE; /*JoeFix disable joystick*/
+    
     if (id >= find_joystick_devices()) return FALSE;
 
     if (dwFlags & DIEDFL_FORCEFEEDBACK) {
@@ -542,42 +548,6 @@ static HRESULT WINAPI JoystickLinuxAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
 }
 
 /******************************************************************************
-  *     GetProperty : get input device properties
-  */
-static HRESULT WINAPI JoystickLinuxWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8W(iface);
-
-    TRACE("(this=%p,%s,%p)\n", iface, debugstr_guid(rguid), pdiph);
-    _dump_DIPROPHEADER(pdiph);
-
-    if (!IS_DIPROP(rguid)) return DI_OK;
-
-    switch (LOWORD(rguid)) {
-
-        case (DWORD_PTR) DIPROP_JOYSTICKID:
-        {
-            LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-            pd->dwData = get_joystick_index(&This->generic.base.guid);
-            TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
-            break;
-        }
-
-    default:
-        return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
-    }
-
-    return DI_OK;
-}
-
-static HRESULT WINAPI JoystickLinuxAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph)
-{
-    JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
-    return JoystickLinuxWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph);
-}
-
-/******************************************************************************
   *     Unacquire : frees the joystick
   */
 static HRESULT WINAPI JoystickLinuxWImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
@@ -607,7 +577,7 @@ static HRESULT WINAPI JoystickLinuxAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
     JoystickImpl *This = impl_from_IDirectInputDevice8A(iface);
     return JoystickLinuxWImpl_Unacquire(IDirectInputDevice8W_from_impl(This));
 }
-
+#define DEAD_AXIS 4096
 static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
 {
     struct pollfd plfd;
@@ -633,7 +603,7 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
 	if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
 	    return;
 	}
-        TRACE("js_event: type 0x%x, number %d, value %d\n",
+        FIXME("js_event: type 0x%x, number %d, value %d\n",
               jse.type,jse.number,jse.value);
         if (jse.type & JS_EVENT_BUTTON)
         {
@@ -641,23 +611,38 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
 
             inst_id = DIDFT_MAKEINSTANCE(jse.number) | DIDFT_PSHBUTTON;
             This->generic.js.rgbButtons[jse.number] = value = jse.value ? 0x80 : 0x00;
+            if (jse.value == 1) {
+               FIXME("Button %d pressed\n",jse.number);
+            }
+            
         }
         else if (jse.type & JS_EVENT_AXIS)
         {
-            int number = This->generic.axis_map[jse.number];	/* wine format object index */
+            int number = This->generic.axis_map[jse.number];
+             
 
             if (number < 0) return;
             inst_id = number < 8 ?  DIDFT_MAKEINSTANCE(number) | DIDFT_ABSAXIS :
                                     DIDFT_MAKEINSTANCE(number - 8) | DIDFT_POV;
-            value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
+           if ((jse.value < DEAD_AXIS && jse.value > 0) ||    (jse.value > -DEAD_AXIS && jse.value < 0)) { //JoeFix DEAD ZONE     
+               value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], 0);
+            }
+            else  if (jse.number == 1 && (getenv("LINIXFORCEJOYYSWAP") != NULL)){//JoeFix Y axis swapped for unreal engine
+               value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], -jse.value);
 
+            }
+            else {
+               value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], jse.value);
+
+            }
+             
             TRACE("changing axis %d => %d\n", jse.number, number);
             switch (number)
             {
                 case 0: This->generic.js.lX  = value; break;
                 case 1: This->generic.js.lY  = value; break;
                 case 2: This->generic.js.lZ  = value; break;
-                case 3: This->generic.js.lRx = value; break;
+                case 3: This->generic.js.lRx = value; break;                       
                 case 4: This->generic.js.lRy = value; break;
                 case 5: This->generic.js.lRz = value; break;
                 case 6: This->generic.js.rglSlider[0] = value; break;
@@ -665,8 +650,9 @@ static void joy_polldev(LPDIRECTINPUTDEVICE8A iface)
                 case 8: case 9: case 10: case 11:
                 {
                     int idx = number - 8;
-
-                    if (jse.number % 2)
+                     FIXME("IDX=%d\n",idx);
+;
+                     if (jse.number % 2)
                         This->povs[idx].y = jse.value;
                     else
                         This->povs[idx].x = jse.value;
@@ -691,7 +677,7 @@ static const IDirectInputDevice8AVtbl JoystickAvt =
         IDirectInputDevice2AImpl_Release,
 	JoystickAGenericImpl_GetCapabilities,
         IDirectInputDevice2AImpl_EnumObjects,
-	JoystickLinuxAImpl_GetProperty,
+	JoystickAGenericImpl_GetProperty,
 	JoystickAGenericImpl_SetProperty,
 	JoystickLinuxAImpl_Acquire,
 	JoystickLinuxAImpl_Unacquire,
@@ -727,7 +713,7 @@ static const IDirectInputDevice8WVtbl JoystickWvt =
     IDirectInputDevice2WImpl_Release,
     JoystickWGenericImpl_GetCapabilities,
     IDirectInputDevice2WImpl_EnumObjects,
-    JoystickLinuxWImpl_GetProperty,
+    JoystickWGenericImpl_GetProperty,
     JoystickWGenericImpl_SetProperty,
     JoystickLinuxWImpl_Acquire,
     JoystickLinuxWImpl_Unacquire,
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 3cab015..2902f9f 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -965,15 +965,6 @@ static HRESULT WINAPI JoystickWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF
         break;
     }
 
-    case (DWORD_PTR) DIPROP_JOYSTICKID:
-    {
-        LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
-
-        pd->dwData = get_joystick_index(&This->generic.base.guid);
-        TRACE("DIPROP_JOYSTICKID(%d)\n", pd->dwData);
-        break;
-    }
-
     default:
         return JoystickWGenericImpl_GetProperty(iface, rguid, pdiph);
     }
diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c
index 2b3a5f7..171795e 100644
--- a/dlls/xinput1_3/xinput1_3_main.c
+++ b/dlls/xinput1_3/xinput1_3_main.c
@@ -15,6 +15,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * ADAPTED FOR LOGITECH CORDLESS RUMBLEPAD BY JOE ON 11.08.11
  */
 
 #include "config.h"
@@ -28,11 +29,33 @@
 #include "winerror.h"
 
 #include "xinput.h"
+#include <linux/joystick.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+XINPUT_STATE prev_pstate;
+const WORD buttonIDs[10] = {
+	XINPUT_GAMEPAD_A,
+	XINPUT_GAMEPAD_B,
+	XINPUT_GAMEPAD_X,
+	XINPUT_GAMEPAD_Y,
+	XINPUT_GAMEPAD_LEFT_SHOULDER,
+	XINPUT_GAMEPAD_RIGHT_SHOULDER,
+	XINPUT_GAMEPAD_BACK,
+	XINPUT_GAMEPAD_START,
+	XINPUT_GAMEPAD_LEFT_THUMB,
+	XINPUT_GAMEPAD_RIGHT_THUMB,
+};
+int fdJoy;
 
 WINE_DEFAULT_DEBUG_CHANNEL(xinput);
 
 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
 {
+    fdJoy=open("/dev/input/js0",O_RDONLY | O_NONBLOCK);
+         
     switch(reason)
     {
     case DLL_WINE_PREATTACH:
@@ -55,58 +78,263 @@ void WINAPI XInputEnable(BOOL enable)
     FIXME("(%d) Stub!\n", enable);
 }
 
-DWORD WINAPI XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration)
-{
-    FIXME("(%d %p) Stub!\n", dwUserIndex, pVibration);
-
-    if (dwUserIndex < XUSER_MAX_COUNT)
-    {
-        return ERROR_DEVICE_NOT_CONNECTED;
-        /* If controller exists then return ERROR_SUCCESS */
-    }
-    return ERROR_BAD_ARGUMENTS;
+DWORD WINAPI XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pstate)
+{       XINPUT_STATE *pState; 
+//        FIXME("IN XinputSetState\n");
+      
+	  
+        return ERROR_SUCCESS;
 }
 
+#define DEAD_ZONE 4096
+
+int dead_or_value(int value) {
+    if ((value > DEAD_ZONE && value > 0) || (value < -DEAD_ZONE && value < 0)) {
+        return value;
+    }
+    else {
+        return 0;
+}  }
+ 
 DWORD WINAPI XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState)
 {
-    static int warn_once;
+  	struct js_event e;
+  	int ret;
+        *pState =prev_pstate;  
+        while (read(fdJoy,&e,sizeof(struct js_event)) != -1) {
+	// timestamp packet
+          //pState->Gamepad.wButtons=0;
+	  pState->dwPacketNumber=GetTickCount();
+          //pState->dwPacketNumber=e.time; 
 
-    if (!warn_once++)
-        FIXME("(%u %p)\n", dwUserIndex, pState);
+          if (e.type == JS_EVENT_BUTTON) {
 
-    if (dwUserIndex < XUSER_MAX_COUNT)
-    {
-        return ERROR_DEVICE_NOT_CONNECTED;
-        /* If controller exists then return ERROR_SUCCESS */
-    }
-    return ERROR_BAD_ARGUMENTS;
-}
+           if (e.number == 0) {
+              if (e.value == 1) {
+                 FIXME("BUTTON X PRESSED\n");
 
-DWORD WINAPI XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserve, PXINPUT_KEYSTROKE pKeystroke)
-{
-    FIXME("(%d %d %p) Stub!\n", dwUserIndex, dwReserve, pKeystroke);
+                pState->Gamepad.wButtons |= buttonIDs[2];//X
+             }
+             else {
+               pState->Gamepad.wButtons &= ~buttonIDs[2];
+             } 
+           }   
+           
+           if (e.number == 1) {
+              if (e.value == 1) {
+                 FIXME("BUTTON A PRESSED\n");
 
-    if (dwUserIndex < XUSER_MAX_COUNT)
-    {
-        return ERROR_DEVICE_NOT_CONNECTED;
-        /* If controller exists then return ERROR_SUCCESS */
-    }
-    return ERROR_BAD_ARGUMENTS;
+                pState->Gamepad.wButtons |= buttonIDs[0];
+             }
+             else {
+               pState->Gamepad.wButtons &= ~buttonIDs[0];
+             } 
+           }   
+           if (e.number == 2) {
+              if (e.value == 1) {
+                 FIXME("BUTTON B PRESSED\n");
+
+                pState->Gamepad.wButtons |= buttonIDs[1];
+             }
+             else {
+               pState->Gamepad.wButtons &= ~buttonIDs[1];
+             } 
+           }   
+           if (e.number == 3) {
+              if (e.value == 1) {
+                 FIXME("BUTTON Y PRESSED\n");
+
+                pState->Gamepad.wButtons |= buttonIDs[3];
+             }
+             else {
+               pState->Gamepad.wButtons &= ~buttonIDs[3];
+             } 
+           }   
+
+           if (e.number == 4) {
+                 if (e.value == 1) {
+                   FIXME("TRIGGER LEFT PRESSED\n");
+                   pState->Gamepad.bLeftTrigger=32767;
+                 }
+                 else {
+                   pState->Gamepad.bLeftTrigger=0;
+                 }
+                  
+           }
+           if (e.number == 5) {
+                 if (e.value == 1) {
+                   FIXME("TRIGGER RIGHT PRESSED\n");
+                   pState->Gamepad.bRightTrigger=32767;
+                 }
+
+                 else {
+                  pState->Gamepad.bRightTrigger=0;
+                 }
+                  
+           }
+           if (e.number == 6) {
+                 if (e.value == 1) {
+                   FIXME("LEFT SHOULDER PRESSED\n");
+                   pState->Gamepad.wButtons |= buttonIDs[4];
+                 }
+                 else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[4];
+                 }
+
+                  
+
+           }
+           if (e.number == 7) {
+                 if (e.value == 1) {
+                   FIXME("RIGHT SHOULDER PRESSED\n");
+                   pState->Gamepad.wButtons |= buttonIDs[5];
+                 }
+                 else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[5];
+                 }
+ 
+
+           }
+
+           if (e.number == 8) {
+                 if (e.value == 1) {
+                   FIXME("BACK PRESSED\n");
+                   pState->Gamepad.wButtons |= buttonIDs[6];
+                 }
+                 else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[6];
+                 }
+
+                  
+           } 
+
+           if (e.number == 9) {
+                  if (e.value == 1) {
+                 
+                     FIXME("START PRESSED\n");
+                    pState->Gamepad.wButtons |= buttonIDs[7];
+                  }
+                  else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[7];
+                 }
+
+                  
+           }
+           if (e.number == 10) {
+                  if (e.value == 1) {
+                  
+                   FIXME("LEFT THUMB PRESSED\n");
+                   pState->Gamepad.wButtons |= buttonIDs[8];
+                  }
+                  else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[8];
+                 }
+
+           }
+           if (e.number == 11) {
+                  if (e.value == 1) {
+                  
+                   FIXME("RIGHT THUMB PRESSED\n");
+                   pState->Gamepad.wButtons |= buttonIDs[9];
+                  }
+                  else {
+                   pState->Gamepad.wButtons &= ~buttonIDs[9];
+                 }
+
+
+           }
+           
+         }
+#define JOYMAX 30000
+#define JOYMIN -30000
+        
+
+        if (e.type == JS_EVENT_AXIS) {
+            FIXME("AXIS %d VALUE=%d MOVED\n",e.number,e.value);
+            if (e.number == 0) {
+               pState->Gamepad.sThumbLX=dead_or_value(e.value);
+               
+            }
+
+            if (e.number == 1) {
+               pState->Gamepad.sThumbLY=dead_or_value(-e.value);
+               
+            }
+
+            if (e.number == 2) {
+               pState->Gamepad.sThumbRX=dead_or_value(e.value);;
+               
+            }
+
+            if (e.number == 3) {
+               //if (e.value == 0) {
+               //   pState->Gamepad.sThumbRY=-32768;
+               //}
+               pState->Gamepad.sThumbRY=dead_or_value(-e.value);
+               
+            }
+                
+            if (e.number == 4) {
+               if (e.value > JOYMAX) {
+                  pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_RIGHT;
+               }
+               else if (e.value < JOYMIN) {
+                   pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_LEFT;
+               }
+               else {
+                   pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_RIGHT ;
+                   pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_LEFT ;
+
+               }
+               
+                                       
+            }
+            if (e.number == 5) {
+               if (e.value > JOYMAX) {
+                  pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_DOWN;
+               }
+               else if (e.value < JOYMIN) {
+                   pState->Gamepad.wButtons |= XINPUT_GAMEPAD_DPAD_UP;
+               }
+               else {
+                   pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_UP;
+                   pState->Gamepad.wButtons &=~XINPUT_GAMEPAD_DPAD_DOWN ;
+               }
+                                       
+            }                          
+         }
+       }       
+       prev_pstate=*pState;
+                 
+       //FIXME("exiting XInputGetState\n");  
+    //FIXME("InXinputgetState\n");
+    return ERROR_SUCCESS;
 }
 
-DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
-{
-    static int warn_once;
+DWORD WINAPI XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserve, PXINPUT_KEYSTROKE pKeyStroke)
+{   int ret;
+    FIXME("In XInputGetKeyStroke\n");
+    //FIXME("(%d %d %p) Stub!\n", dwUserIndex, dwReserve, pKeyStroke);
+    return ERROR_SUCCESS;    
+}
 
-    if (!warn_once++)
-        FIXME("(%d %d %p)\n", dwUserIndex, dwFlags, pCapabilities);
+DWORD WINAPI XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* xCaps)
+{
+        xCaps->Type = XINPUT_DEVTYPE_GAMEPAD;
+	xCaps->SubType = XINPUT_DEVSUBTYPE_GAMEPAD;
+	xCaps->Flags = 0; // we do not support sound
+	xCaps->Vibration.wLeftMotorSpeed = xCaps->Vibration.wRightMotorSpeed = 0xFF;
+	xCaps->Gamepad.bLeftTrigger = xCaps->Gamepad.bRightTrigger = 0xFF;
+         
+	//MSDN lie, this is not range !
+	//Dumped from XInput device
+	xCaps->Gamepad.sThumbLX = (SHORT) -64;
+	xCaps->Gamepad.sThumbLY = (SHORT) -64;
+	xCaps->Gamepad.sThumbRX = (SHORT) -64;
+	xCaps->Gamepad.sThumbRY = (SHORT) -64;
+	xCaps->Gamepad.wButtons = (WORD) 0xF3FF;
+        return ERROR_SUCCESS;
 
-    if (dwUserIndex < XUSER_MAX_COUNT)
-    {
-        return ERROR_DEVICE_NOT_CONNECTED;
-        /* If controller exists then return ERROR_SUCCESS */
-    }
-    return ERROR_BAD_ARGUMENTS;
 }
 
 DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid)
-- 
1.7.7.6



More information about the wine-patches mailing list