Module: wine Branch: refs/heads/master Commit: 034a030d374674b14a95a606f5348eb22db2e456 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=034a030d374674b14a95a606...
Author: Christoph Frick rid@zefix.tv Date: Fri Mar 10 09:58:14 2006 +0100
dinput/joystick_linuxinput: Add POV detection and reporting.
Mapping of ABS_HAT[0-3][XY] to the four POV used by dinput.
---
dlls/dinput/joystick_linuxinput.c | 75 +++++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index 5530c16..7de164d 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -67,6 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
/* Wine joystick driver object instances */ #define WINE_JOYSTICK_AXIS_BASE 0 +#define WINE_JOYSTICK_POV_BASE 6 #define WINE_JOYSTICK_BUTTON_BASE 8
typedef struct EffectListItem EffectListItem; @@ -148,8 +149,9 @@ static GUID DInput_Wine_Joystick_GUID =
static void fake_current_js_state(JoystickImpl *ji); static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph); +static DWORD map_pov(int event_value, int is_x);
-#define test_bit(arr,bit) (((BYTE*)arr)[bit>>3]&(1<<(bit&7))) +#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
static int joydev_have(BOOL require_ff) { @@ -618,6 +620,8 @@ map_axis(JoystickImpl* This, int axis, i */ static void fake_current_js_state(JoystickImpl *ji) { + int i; + /* center the axes */ ji->js.lX = map_axis(ji, ABS_X, ji->axes[ABS_X ][AXE_ABS]); ji->js.lY = map_axis(ji, ABS_Y, ji->axes[ABS_Y ][AXE_ABS]); ji->js.lZ = map_axis(ji, ABS_Z, ji->axes[ABS_Z ][AXE_ABS]); @@ -626,6 +630,35 @@ static void fake_current_js_state(Joysti ji->js.lRz = map_axis(ji, ABS_RZ, ji->axes[ABS_RZ][AXE_ABS]); ji->js.rglSlider[0] = map_axis(ji, ABS_THROTTLE, ji->axes[ABS_THROTTLE][AXE_ABS]); ji->js.rglSlider[1] = map_axis(ji, ABS_RUDDER, ji->axes[ABS_RUDDER ][AXE_ABS]); + /* POV center is -1 */ + for (i=0; i<4; i++) { + ji->js.rgdwPOV[i] = -1; + } +} + +/* + * Maps an event value to a DX "clock" position: + * 0 + * 27000 -1 9000 + * 18000 + */ +static DWORD map_pov(int event_value, int is_x) +{ + DWORD ret = -1; + if (is_x) { + if (event_value<0) { + ret = 27000; + } else if (event_value>0) { + ret = 9000; + } + } else { + if (event_value<0) { + ret = 0; + } else if (event_value>0) { + ret = 18000; + } + } + return ret; }
static int find_property_offset(JoystickImpl *This, LPCDIPROPHEADER ph) @@ -717,6 +750,26 @@ static void joy_polldev(JoystickImpl *Th This->js.rglSlider[1] = map_axis(This,ABS_RUDDER,ie.value); GEN_EVENT(DIJOFS_SLIDER(1),This->js.rglSlider[1],ie.time.tv_usec,(This->dinput->evsequence)++); break; + case ABS_HAT0X: + case ABS_HAT0Y: + This->js.rgdwPOV[0] = map_pov(ie.value,ie.code==ABS_HAT0X); + GEN_EVENT(DIJOFS_POV(0),This->js.rgdwPOV[0],ie.time.tv_usec,(This->dinput->evsequence)++); + break; + case ABS_HAT1X: + case ABS_HAT1Y: + This->js.rgdwPOV[1] = map_pov(ie.value,ie.code==ABS_HAT1X); + GEN_EVENT(DIJOFS_POV(1),This->js.rgdwPOV[1],ie.time.tv_usec,(This->dinput->evsequence)++); + break; + case ABS_HAT2X: + case ABS_HAT2Y: + This->js.rgdwPOV[2] = map_pov(ie.value,ie.code==ABS_HAT2X); + GEN_EVENT(DIJOFS_POV(2),This->js.rgdwPOV[2],ie.time.tv_usec,(This->dinput->evsequence)++); + break; + case ABS_HAT3X: + case ABS_HAT3Y: + This->js.rgdwPOV[3] = map_pov(ie.value,ie.code==ABS_HAT3X); + GEN_EVENT(DIJOFS_POV(3),This->js.rgdwPOV[3],ie.time.tv_usec,(This->dinput->evsequence)++); + break; default: FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value); break; @@ -1078,6 +1131,26 @@ static HRESULT WINAPI JoystickAImpl_Enum }
if ((dwFlags == DIDFT_ALL) || + (dwFlags & DIDFT_POV)) { + int i; + ddoi.guidType = GUID_POV; + for (i=0; i<4; i++) { + if (test_bit(This->absbits,ABS_HAT0X+(i<<1)) && test_bit(This->absbits,ABS_HAT0Y+(i<<1))) { + ddoi.dwOfs = DIJOFS_POV(i); + ddoi.dwType = DIDFT_MAKEINSTANCE(i << WINE_JOYSTICK_POV_BASE) | DIDFT_POV; + sprintf(ddoi.tszName, "%d-POV", i); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) { + /* return to unaquired state if that's where we were */ + if (xfd == -1) + IDirectInputDevice8_Unacquire(iface); + return DI_OK; + } + } + } + } + + if ((dwFlags == DIDFT_ALL) || (dwFlags & DIDFT_BUTTON)) { int i, btncount=0;