From b06786940c95e11729438ad6d0cb0bae765d5d1e Mon Sep 17 00:00:00 2001 From: Vitaliy Margolen Date: Sun, 5 Aug 2007 12:24:04 -0600 Subject: [PATCH] dinput: Reuse common code and definition. Unify object properties structure and he common axis mapping function for both joystick drivers. --- dlls/dinput/device_private.h | 11 +++ dlls/dinput/joystick_linux.c | 28 +------ dlls/dinput/joystick_linuxinput.c | 124 +++++++++++++++--------------- 3 files changed, 77 insertions(+), 86 deletions(-) diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 94d82470049..6686577b13c 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -83,7 +83,18 @@ extern int id_to_offset(const DataFormat *df, int id); extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph); /* Common joystick stuff */ +typedef struct +{ + LONG lDevMin; + LONG lDevMax; + LONG lMin; + LONG lMax; + LONG lDeadZone; + LONG lSaturation; +} ObjProps; + extern DWORD joystick_map_pov(POINTL *p); +extern LONG joystick_map_axis(ObjProps *props, int val); /** * Callback Data used by specific callback diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c index 25dcf7ff231..4b1165f4c35 100644 --- a/dlls/dinput/joystick_linux.c +++ b/dlls/dinput/joystick_linux.c @@ -76,13 +76,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput); #define JOYDEV_NEW "/dev/input/js" #define JOYDEV_OLD "/dev/js" -typedef struct { - LONG lMin; - LONG lMax; - LONG lDeadZone; - LONG lSaturation; -} ObjProps; - typedef struct JoystickImpl JoystickImpl; static const IDirectInputDevice8AVtbl JoystickAvt; static const IDirectInputDevice8WVtbl JoystickWvt; @@ -520,6 +513,8 @@ static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *di /* initialize default properties */ for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) { + newDevice->props[i].lDevMin = -32767; + newDevice->props[i].lDevMax = +32767; newDevice->props[i].lMin = 0; newDevice->props[i].lMax = 0xffff; newDevice->props[i].lDeadZone = newDevice->deadzone; /* % * 1000 */ @@ -681,23 +676,6 @@ static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface) return DI_NOEFFECT; } -static LONG map_axis(JoystickImpl * This, short val, short index) -{ - double fval = val; - double fmin = This->props[index].lMin; - double fmax = This->props[index].lMax; - double fret; - - fret = (((fval + 32767.0) * (fmax - fmin)) / (32767.0*2.0)) + fmin; - - if (fret >= 0.0) - fret += 0.5; - else - fret -= 0.5; - - return fret; -} - static void joy_polldev(JoystickImpl *This) { struct pollfd plfd; struct js_event jse; @@ -733,7 +711,7 @@ static void joy_polldev(JoystickImpl *This) { if (number < 0) return; inst_id = DIDFT_MAKEINSTANCE(number) | (number < 8 ? DIDFT_ABSAXIS : DIDFT_POV); - value = map_axis(This, jse.value, id_to_object(This->base.data_format.wine_df, inst_id)); + value = joystick_map_axis(&This->props[id_to_object(This->base.data_format.wine_df, inst_id)], jse.value); TRACE("changing axis %d => %d\n", jse.number, number); switch (number) diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index bfbd026dea7..5ef0ea74e55 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -84,6 +84,28 @@ DWORD joystick_map_pov(POINTL *p) return p->y < 0 ? 0 : !p->y ? -1 : 18000; } +/* + * This maps the read value (from the input event) to a value in the + * 'wanted' range. + */ +LONG joystick_map_axis(ObjProps *props, int val) +{ + LONG ret; + + /* map the value from the hmin-hmax range into the wmin-wmax range */ + ret = MulDiv( val - props->lDevMin, props->lMax - props->lMin, + props->lDevMax - props->lDevMin ) + props->lMin; + + if ((ret >= -props->lDeadZone / 2 ) && (ret <= props->lDeadZone / 2)) + ret = (props->lMax - props->lMin) / 2 + props->lMin; + + TRACE( "(%d %d) -> (%d <%d> %d): val=%d ret=%d\n", + props->lDevMin, props->lDevMax, + props->lMin, props->lDeadZone, props->lDevMax, + val, ret ); + + return ret; +} #ifdef HAVE_CORRECT_LINUXINPUT_H @@ -156,7 +178,7 @@ struct JoystickImpl DIJOYSTATE2 js; - struct ObjProps props[ABS_MAX]; + ObjProps props[ABS_MAX]; int axes[ABS_MAX]; POINTL povs[4]; @@ -405,12 +427,13 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize); newDevice->axes[i] = idx; - newDevice->props[idx].havemin = newDevice->joydev->axes[i][AXIS_ABSMIN]; - newDevice->props[idx].havemax = newDevice->joydev->axes[i][AXIS_ABSMAX]; - newDevice->props[idx].wantmin = 0; - newDevice->props[idx].wantmax = 0xffff; - newDevice->props[idx].deadzone = MulDiv(newDevice->joydev->axes[i][AXIS_ABSFLAT], 0xffff, - newDevice->props[idx].havemax - newDevice->props[idx].havemin); + newDevice->props[idx].lDevMin = newDevice->joydev->axes[i][AXIS_ABSMIN]; + newDevice->props[idx].lDevMax = newDevice->joydev->axes[i][AXIS_ABSMAX]; + newDevice->props[idx].lMin = 0; + newDevice->props[idx].lMax = 0xffff; + newDevice->props[idx].lSaturation = 0; + newDevice->props[idx].lDeadZone = MulDiv(newDevice->joydev->axes[i][AXIS_ABSFLAT], 0xffff, + newDevice->props[idx].lDevMax - newDevice->props[idx].lDevMin); df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(newDevice->numAxes++) | DIDFT_ABSAXIS; } @@ -568,53 +591,32 @@ static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface) return res; } -/* - * This maps the read value (from the input event) to a value in the - * 'wanted' range. It also autodetects the possible range of the axis and - * adapts values accordingly. - */ -static int map_axis(JoystickImpl* This, int axis, int val) -{ - int hmax = This->props[axis].havemax; - int hmin = This->props[axis].havemin; - int wmin = This->props[axis].wantmin; - int wmax = This->props[axis].wantmax; - int deadz= This->props[axis].deadzone; - int ret; - - /* map the value from the hmin-hmax range into the wmin-wmax range */ - ret = MulDiv( val - hmin, wmax - wmin, hmax - hmin ) + wmin; - - if ((ret >= -deadz / 2 ) && (ret <= deadz / 2)) - ret = (wmax - wmin) / 2 + wmin; - - TRACE("[%d] hmin=%d hmax=%d wmin=%d wmax=%d deadz=%d val=%d ret=%d\n", - axis, hmin, hmax, wmin, wmax, deadz, val, ret); - - return ret; -} - /* * set the current state of the js device as it would be with the middle * values on the axes */ +#define CENTER_AXIS(a) \ + (ji->axes[a] == -1 ? 0 : joystick_map_axis( &ji->props[ji->axes[a]], \ + ji->joydev->axes[a][AXIS_ABS] )) static void fake_current_js_state(JoystickImpl *ji) { - int i; - /* center the axes */ - ji->js.lX = ji->axes[ABS_X]!=-1 ? map_axis(ji, ji->axes[ABS_X], ji->joydev->axes[ABS_X ][AXIS_ABS]) : 0; - ji->js.lY = ji->axes[ABS_Y]!=-1 ? map_axis(ji, ji->axes[ABS_Y], ji->joydev->axes[ABS_Y ][AXIS_ABS]) : 0; - ji->js.lZ = ji->axes[ABS_Z]!=-1 ? map_axis(ji, ji->axes[ABS_Z], ji->joydev->axes[ABS_Z ][AXIS_ABS]) : 0; - ji->js.lRx = ji->axes[ABS_RX]!=-1 ? map_axis(ji, ji->axes[ABS_RX], ji->joydev->axes[ABS_RX ][AXIS_ABS]) : 0; - ji->js.lRy = ji->axes[ABS_RY]!=-1 ? map_axis(ji, ji->axes[ABS_RY], ji->joydev->axes[ABS_RY ][AXIS_ABS]) : 0; - ji->js.lRz = ji->axes[ABS_RZ]!=-1 ? map_axis(ji, ji->axes[ABS_RZ], ji->joydev->axes[ABS_RZ ][AXIS_ABS]) : 0; - ji->js.rglSlider[0] = ji->axes[ABS_THROTTLE]!=-1 ? map_axis(ji, ji->axes[ABS_THROTTLE], ji->joydev->axes[ABS_THROTTLE][AXIS_ABS]) : 0; - ji->js.rglSlider[1] = ji->axes[ABS_RUDDER]!=-1 ? map_axis(ji, ji->axes[ABS_RUDDER], ji->joydev->axes[ABS_RUDDER ][AXIS_ABS]) : 0; - /* POV center is -1 */ - for (i=0; i<4; i++) { - ji->js.rgdwPOV[i] = -1; - } + int i; + + /* center the axes */ + ji->js.lX = CENTER_AXIS(ABS_X); + ji->js.lY = CENTER_AXIS(ABS_Y); + ji->js.lZ = CENTER_AXIS(ABS_Z); + ji->js.lRx = CENTER_AXIS(ABS_RX); + ji->js.lRy = CENTER_AXIS(ABS_RY); + ji->js.lRz = CENTER_AXIS(ABS_RZ); + ji->js.rglSlider[0] = CENTER_AXIS(ABS_THROTTLE); + ji->js.rglSlider[1] = CENTER_AXIS(ABS_RUDDER); + + /* POV center is -1 */ + for (i = 0; i < 4; i++) + ji->js.rgdwPOV[i] = -1; } +#undef CENTER_AXIS /* convert wine format offset to user format object index */ static void joy_polldev(JoystickImpl *This) @@ -662,7 +664,7 @@ static void joy_polldev(JoystickImpl *This) break; } inst_id = DIDFT_MAKEINSTANCE(axis) | (ie.code < ABS_HAT0X ? DIDFT_ABSAXIS : DIDFT_POV); - value = map_axis(This, id_to_object(This->base.data_format.wine_df, inst_id), ie.value); + value = joystick_map_axis(&This->props[id_to_object(This->base.data_format.wine_df, inst_id)], ie.value); switch (ie.code) { case ABS_X: This->js.lX = value; break; @@ -764,10 +766,10 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax); for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) { /* Scale dead-zone */ - This->props[i].deadzone = MulDiv(This->props[i].deadzone, pr->lMax - pr->lMin, - This->props[i].wantmax - This->props[i].wantmin); - This->props[i].wantmin = pr->lMin; - This->props[i].wantmax = pr->lMax; + This->props[i].lDeadZone = MulDiv(This->props[i].lDeadZone, pr->lMax - pr->lMin, + This->props[i].lMax - This->props[i].lMin); + This->props[i].lMin = pr->lMin; + This->props[i].lMax = pr->lMax; } } else { int obj = find_property(&This->base.data_format, ph); @@ -775,10 +777,10 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj); if (obj >= 0) { /* Scale dead-zone */ - This->props[obj].deadzone = MulDiv(This->props[obj].deadzone, pr->lMax - pr->lMin, - This->props[obj].wantmax - This->props[obj].wantmin); - This->props[obj].wantmin = pr->lMin; - This->props[obj].wantmax = pr->lMax; + This->props[obj].lDeadZone = MulDiv(This->props[obj].lDeadZone, pr->lMax - pr->lMin, + This->props[obj].lMax - This->props[obj].lMin); + This->props[obj].lMin = pr->lMin; + This->props[obj].lMax = pr->lMax; } } fake_current_js_state(This); @@ -790,14 +792,14 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, int i; TRACE("deadzone(%d) all\n", pd->dwData); for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) { - This->props[i].deadzone = pd->dwData; + This->props[i].lDeadZone = pd->dwData; } } else { int obj = find_property(&This->base.data_format, ph); TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj); if (obj >= 0) { - This->props[obj].deadzone = pd->dwData; + This->props[obj].lDeadZone = pd->dwData; } } fake_current_js_state(This); @@ -883,8 +885,8 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, if (obj < 0) return DIERR_OBJECTNOTFOUND; - pr->lMin = This->props[obj].wantmin; - pr->lMax = This->props[obj].wantmax; + pr->lMin = This->props[obj].lMin; + pr->lMax = This->props[obj].lMax; TRACE("range(%d, %d) obj=%d\n", pr->lMin, pr->lMax, obj); break; } @@ -895,7 +897,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, if (obj < 0) return DIERR_OBJECTNOTFOUND; - pd->dwData = This->props[obj].deadzone; + pd->dwData = This->props[obj].lDeadZone; TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj); break; }