Vitaliy Margolen : dinput: Evdev joystick driver - add ability to remap axis.

Alexandre Julliard julliard at winehq.org
Wed Aug 19 11:31:54 CDT 2009


Module: wine
Branch: master
Commit: 167457efc14c84292a9c2d31510b1d7d5fe81a7b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=167457efc14c84292a9c2d31510b1d7d5fe81a7b

Author: Vitaliy Margolen <wine-patches at kievinfo.com>
Date:   Sat Aug 15 11:58:47 2009 -0600

dinput: Evdev joystick driver - add ability to remap axis.

---

 dlls/dinput/joystick_linuxinput.c |  120 +++++++++++++++++++++----------------
 1 files changed, 68 insertions(+), 52 deletions(-)

diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index b82c4c7..1dda212 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -378,9 +378,6 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm
     JoystickImpl* newDevice;
     LPDIDATAFORMAT df = NULL;
     int i, idx = 0;
-    char buffer[MAX_PATH+16];
-    HKEY hkey, appkey;
-    LONG def_deadzone = 0;
 
     newDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JoystickImpl));
     if (!newDevice) return NULL;
@@ -405,57 +402,73 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm
     InitializeCriticalSection(&newDevice->generic.base.crit);
     newDevice->generic.base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->base.crit");
 
-    /* get options */
-    get_app_key(&hkey, &appkey);
+    /* Count number of available axes - supported Axis & POVs */
+    for (i = 0; i < WINE_JOYSTICK_MAX_AXES; i++)
+    {
+        if (test_bit(newDevice->joydev->absbits, i))
+        {
+            newDevice->generic.device_axis_count++;
+            newDevice->dev_axes_to_di[i] = idx;
+            newDevice->generic.props[idx].lDevMin = newDevice->joydev->axes[i].minimum;
+            newDevice->generic.props[idx].lDevMax = newDevice->joydev->axes[i].maximum;
+            idx++;
+        }
+        else
+            newDevice->dev_axes_to_di[i] = -1;
+    }
 
-    if (!get_config_key(hkey, appkey, "DefaultDeadZone", buffer, MAX_PATH))
+    for (i = 0; i < WINE_JOYSTICK_MAX_POVS; i++)
     {
-        def_deadzone = atoi(buffer);
-        TRACE("setting default deadzone to: %d\n", def_deadzone);
+        if (test_bit(newDevice->joydev->absbits, ABS_HAT0X + i * 2) &&
+            test_bit(newDevice->joydev->absbits, ABS_HAT0Y + i * 2))
+        {
+            newDevice->generic.device_axis_count += 2;
+            newDevice->generic.props[idx].lDevMin = newDevice->joydev->axes[ABS_HAT0X + i * 2].minimum;
+            newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = idx++;
+            newDevice->generic.props[idx].lDevMax = newDevice->joydev->axes[ABS_HAT0Y + i * 2].maximum;
+            newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = idx++;
+        }
+        else
+            newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = -1;
     }
-    if (appkey) RegCloseKey(appkey);
-    if (hkey) RegCloseKey(hkey);
+
+    /* do any user specified configuration */
+    if (setup_dinput_options(&newDevice->generic) != DI_OK) goto failed;
 
     /* Create copy of default data format */
     if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto failed;
     memcpy(df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
     if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed;
 
-    /* Supported Axis & POVs should map 1-to-1 */
-    for (i = 0; i < WINE_JOYSTICK_MAX_AXES; i++)
+
+    /* Construct internal data format */
+
+    /* Supported Axis & POVs */
+    for (i = 0, idx = 0; i < newDevice->generic.device_axis_count; i++)
     {
-        if (!test_bit(newDevice->joydev->absbits, i)) {
-            newDevice->dev_axes_to_di[i] = -1;
-            continue;
+        int wine_obj = newDevice->generic.axis_map[i];
+
+        if (wine_obj < 0) continue;
+
+        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[wine_obj], df->dwObjSize);
+        if (wine_obj < 8)
+            df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj) | DIDFT_ABSAXIS;
+        else
+        {
+            df->rgodf[idx].dwType = DIDFT_MAKEINSTANCE(wine_obj - 8) | DIDFT_POV;
+            i++; /* POV takes 2 axes */
         }
 
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize);
-        newDevice->dev_axes_to_di[i] = idx;
-        newDevice->generic.props[idx].lDevMin = newDevice->joydev->axes[i].minimum;
-        newDevice->generic.props[idx].lDevMax = newDevice->joydev->axes[i].maximum;
-        newDevice->generic.props[idx].lMin    = 0;
-        newDevice->generic.props[idx].lMax    = 0xffff;
+        newDevice->generic.props[idx].lMin        = 0;
+        newDevice->generic.props[idx].lMax        = 0xffff;
         newDevice->generic.props[idx].lSaturation = 0;
-        newDevice->generic.props[idx].lDeadZone = def_deadzone;
+        newDevice->generic.props[idx].lDeadZone   = newDevice->generic.deadzone;
 
         /* Linux supports force-feedback on X & Y axes only */
         if (newDevice->joydev->has_ff && (i == 0 || i == 1))
             df->rgodf[idx].dwFlags |= DIDOI_FFACTUATOR;
 
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->generic.devcaps.dwAxes++) | DIDFT_ABSAXIS;
-    }
-
-    for (i = 0; i < WINE_JOYSTICK_MAX_POVS; i++)
-    {
-        if (!test_bit(newDevice->joydev->absbits, ABS_HAT0X + i * 2) ||
-            !test_bit(newDevice->joydev->absbits, ABS_HAT0Y + i * 2)) {
-            newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = -1;
-            continue;
-        }
-
-        memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + WINE_JOYSTICK_MAX_AXES], df->dwObjSize);
-        newDevice->dev_axes_to_di[ABS_HAT0X + i * 2] = newDevice->dev_axes_to_di[ABS_HAT0Y + i * 2] = i;
-        df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->generic.devcaps.dwPOVs++) | DIDFT_POV;
+        idx++;
     }
 
     /* Buttons can be anywhere, so check all */
@@ -490,6 +503,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm
 failed:
     if (df) HeapFree(GetProcessHeap(), 0, df->rgodf);
     HeapFree(GetProcessHeap(), 0, df);
+    HeapFree(GetProcessHeap(), 0, newDevice->generic.axis_map);
     HeapFree(GetProcessHeap(), 0, newDevice);
     return NULL;
 }
@@ -752,25 +766,27 @@ static void joy_polldev(JoystickGenericImpl *iface)
 	case EV_ABS:
         {
             int axis = This->dev_axes_to_di[ie.code];
-            if (axis==-1) {
-                break;
-            }
-            inst_id = DIDFT_MAKEINSTANCE(axis) | (ie.code < ABS_HAT0X ? DIDFT_ABSAXIS : DIDFT_POV);
+
+            /* User axis remapping */
+            if (axis < 0) break;
+            axis = This->generic.axis_map[axis];
+            if (axis < 0) break;
+
+            inst_id = DIDFT_MAKEINSTANCE(axis) | (axis < 8 ? DIDFT_ABSAXIS : DIDFT_POV);
             value = joystick_map_axis(&This->generic.props[id_to_object(This->generic.base.data_format.wine_df, inst_id)], ie.value);
 
-	    switch (ie.code) {
-            case ABS_X:         This->generic.js.lX  = value; break;
-            case ABS_Y:         This->generic.js.lY  = value; break;
-            case ABS_Z:         This->generic.js.lZ  = value; break;
-            case ABS_RX:        This->generic.js.lRx = value; break;
-            case ABS_RY:        This->generic.js.lRy = value; break;
-            case ABS_RZ:        This->generic.js.lRz = value; break;
-            case ABS_THROTTLE:  This->generic.js.rglSlider[0] = value; break;
-            case ABS_RUDDER:    This->generic.js.rglSlider[1] = value; break;
-            case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y:
-            case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y:
+	    switch (axis) {
+            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 4: This->generic.js.lRy = value; break;
+            case 5: This->generic.js.lRz = value; break;
+            case 6: This->generic.js.rglSlider[0] = value; break;
+            case 7: This->generic.js.rglSlider[1] = value; break;
+            case 8: case 9: case 10: case 11:
             {
-                int idx = (ie.code - ABS_HAT0X) / 2;
+                int idx = axis - 8;
 
                 if (ie.code % 2)
                     This->povs[idx].y = ie.value;




More information about the wine-cvs mailing list