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