On Thu, Jan 11, 2007 at 10:25:51AM -0700, Vitaliy Margolen wrote: attached a patch with all the suggestions for Vitaliy.
Christoph Frick wrote:
with Vitaliy's patches i tried my games yesterday and everything seemed ok (RBR works again). but my clutch on the wheel did not work and also That's a good news. I was hopping not to brake too many things while reorganizing the dinput.
@@ -128,11 +122,20 @@ struct JoystickImpl /* The 'parent' DInput */ IDirectInputImpl *dinput;
+ /* autodetecting ranges per axe by following movement */ + LONG havemax[8]; + LONG havemin[8]; I could never understood why we need these? In other joystick_linux the range assumed to be 0 - 0xffff.
/* joystick private */ /* what range and deadzone the game wants */ - LONG wantmin[ABS_MAX]; - LONG wantmax[ABS_MAX]; - LONG deadz[ABS_MAX]; + LONG wantmin[8]; + LONG wantmax[8]; + LONG deadz[8]; Can we move these into separate struct like it's done in joystick_linux? It's much cleaner end eventually will allow a better integration of two.
And can you use spaces instead of tabs please?
@@ -395,19 +373,29 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm /* Supported Axis & POVs should map 1-to-1 */ for (i = 0; i < 8; i++) { - if (!test_bit(newDevice->joydev->absbits, i)) continue; + if (!test_bit(newDevice->joydev->absbits, i)) { + newDevice->axes[i] = -1; + continue; + } Can you please don't brake the good readable style? Please put that curly bracket into separate line, and use 4 space indentation.
+ fake_current_js_state(newDevice); + Can you explain what this suppose to do? Why do we need to "fake current state" everywhere?
+ int axe = This->axes[ie.code]; It's an "axis" not an "axe" :)
-- diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index e2f77f8..640c8d9 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -70,8 +70,8 @@ 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 +#define WINE_JOYSTICK_POV_BASE 8 +#define WINE_JOYSTICK_BUTTON_BASE 12 typedef struct EffectListItem EffectListItem; struct EffectListItem @@ -111,12 +111,15 @@ struct JoyDev { /* data returned by the EVIOCGABS() ioctl */ int axes[ABS_MAX][5]; - /* LUT for KEY_ to offset in rgbButtons */ - BYTE buttons[KEY_MAX]; +}; - /* autodetecting ranges per axe by following movement */ - LONG havemax[ABS_MAX]; - LONG havemin[ABS_MAX]; +struct ObjProps +{ + LONG havemin; + LONG havemax; + LONG wantmin; + LONG wantmax; + LONG deadzone; }; struct JoystickImpl @@ -128,11 +131,13 @@ struct JoystickImpl /* The 'parent' DInput */ IDirectInputImpl *dinput; - /* joystick private */ - /* what range and deadzone the game wants */ - LONG wantmin[ABS_MAX]; - LONG wantmax[ABS_MAX]; - LONG deadz[ABS_MAX]; + struct ObjProps props[8]; + + /* LUT for the mapping of used axes */ + int axes[ABS_MAX]; + + /* LUT for KEY_ to offset in rgbButtons */ + BYTE buttons[KEY_MAX]; int joyfd; @@ -177,7 +182,7 @@ static void find_joydevs(void) struct JoyDev joydev = {0}; int fd; int no_ff_check = 0; - int j, buttons; + int j; snprintf(buf,MAX_PATH,EVDEVPREFIX"%d",i); buf[MAX_PATH-1] = 0; @@ -246,7 +251,7 @@ static void find_joydevs(void) for (j=0;j<ABS_MAX;j++) { if (test_bit(joydev.absbits,j)) { if (-1!=ioctl(fd,EVIOCGABS(j),&(joydev.axes[j]))) { - TRACE(" ... with axe %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n", + TRACE(" ... with axis %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n", j, joydev.axes[j][AXE_ABS], joydev.axes[j][AXE_ABSMIN], @@ -254,21 +259,10 @@ static void find_joydevs(void) joydev.axes[j][AXE_ABSFUZZ], joydev.axes[j][AXE_ABSFLAT] ); - joydev.havemin[j] = joydev.axes[j][AXE_ABSMIN]; - joydev.havemax[j] = joydev.axes[j][AXE_ABSMAX]; } } } - buttons = 0; - for (j=0;j<KEY_MAX;j++) { - if (test_bit(joydev.keybits,j)) { - TRACE(" ... with button %d: %d\n", j, buttons); - joydev.buttons[j] = 0x80 | buttons; - buttons++; - } - } - if (have_joydevs==0) { joydevs = HeapAlloc(GetProcessHeap(), 0, sizeof(struct JoyDev)); } else { @@ -357,8 +351,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm { JoystickImpl* newDevice; LPDIDATAFORMAT df = NULL; - int i, idx = 0; - int axis = 0, pov = 0, btn = 0; + int i, idx = 0, btn=0; newDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JoystickImpl)); if (!newDevice) return NULL; @@ -373,19 +366,6 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm #ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION newDevice->ff_state = FF_STATUS_STOPPED; #endif - for (i=0;i<ABS_MAX;i++) { - /* apps expect the range to be the same they would get from the - * GetProperty/range method */ - newDevice->wantmin[i] = newDevice->joydev->havemin[i]; - newDevice->wantmax[i] = newDevice->joydev->havemax[i]; - /* TODO: - * direct input defines a default for the deadzone somewhere; but as long - * as in map_axis the code for the dead zone is commented out its no - * problem - */ - newDevice->deadz[i] = 0; - } - fake_current_js_state(newDevice); /* Create copy of default data format */ if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIJoystick2.dwSize))) goto failed; @@ -395,19 +375,31 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm /* Supported Axis & POVs should map 1-to-1 */ for (i = 0; i < 8; i++) { - if (!test_bit(newDevice->joydev->absbits, i)) continue; + if (!test_bit(newDevice->joydev->absbits, i)) + { + newDevice->axes[i] = -1; + continue; + } - memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[axis + WINE_JOYSTICK_AXIS_BASE], df->dwObjSize); - df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(axis++) | DIDFT_ABSAXIS; + memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i], df->dwObjSize); + newDevice->axes[i] = idx; + newDevice->props[idx].havemin = newDevice->props[idx].wantmin = newDevice->joydev->axes[i][AXE_ABSMIN]; + newDevice->props[idx].havemax = newDevice->props[idx].wantmax = newDevice->joydev->axes[i][AXE_ABSMAX]; + newDevice->props[idx].deadzone = 0; + df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_ABSAXIS; } for (i = 0; i < 4; i++) { if (!test_bit(newDevice->joydev->absbits, ABS_HAT0X + i * 2) || !test_bit(newDevice->joydev->absbits, ABS_HAT0Y + i * 2)) + { + newDevice->axes[ABS_HAT0X + i * 2] = newDevice->axes[ABS_HAT0Y + i * 2] = -1; continue; + } - memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[pov + WINE_JOYSTICK_POV_BASE], df->dwObjSize); - df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(pov++) | DIDFT_POV; + memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[i + WINE_JOYSTICK_POV_BASE], df->dwObjSize); + newDevice->axes[ABS_HAT0X + i * 2] = newDevice->axes[ABS_HAT0Y + i * 2] = i; + df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_POV; } /* Buttons can be anywhere, so check all */ for (i = 0; i < KEY_MAX && btn < 128; i++) @@ -415,10 +407,13 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm if (!test_bit(newDevice->joydev->keybits, i)) continue; memcpy(&df->rgodf[idx], &c_dfDIJoystick2.rgodf[btn + WINE_JOYSTICK_BUTTON_BASE], df->dwObjSize); + newDevice->buttons[i] = 0x80 | btn; df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(btn++) | DIDFT_PSHBUTTON; } df->dwNumObjs = idx; + fake_current_js_state(newDevice); + newDevice->base.data_format.wine_df = df; IDirectInput_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->dinput); return newDevice; @@ -578,28 +573,24 @@ static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface) /* * This maps the read value (from the input event) to a value in the - * 'wanted' range. It also autodetects the possible range of the axe and + * '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 xmin = This->joydev->axes[axis][AXE_ABSMIN]; - int xmax = This->joydev->axes[axis][AXE_ABSMAX]; - int hmax = This->joydev->havemax[axis]; - int hmin = This->joydev->havemin[axis]; - int wmin = This->wantmin[axis]; - int wmax = This->wantmax[axis]; + int hmin = This->props[axis].havemin; + int hmax = This->props[axis].havemax; + int wmin = This->props[axis].wantmin; + int wmax = This->props[axis].wantmax; int ret; - if (val > hmax) This->joydev->havemax[axis] = hmax = val; - if (val < hmin) This->joydev->havemin[axis] = hmin = val; - - if (xmin == xmax) return val; + if (val < hmin) This->props[axis].havemin = hmin = val; + if (val > hmax) This->props[axis].havemax = hmax = val; /* map the value from the hmin-hmax range into the wmin-wmax range */ ret = MulDiv( val - hmin, wmax - wmin, hmax - hmin ) + wmin; - TRACE("xmin=%d xmax=%d hmin=%d hmax=%d wmin=%d wmax=%d val=%d ret=%d\n", xmin, xmax, hmin, hmax, wmin, wmax, val, ret); + TRACE("hmin=%d hmax=%d wmin=%d wmax=%d val=%d ret=%d\n", hmin, hmax, wmin, wmax, val, ret); #if 0 /* deadzone doesn't work comfortably enough right now. needs more testing*/ @@ -619,14 +610,14 @@ static void fake_current_js_state(JoystickImpl *ji) { int i; /* center the axes */ - ji->js.lX = test_bit(ji->joydev->absbits, ABS_X) ? map_axis(ji, ABS_X, ji->joydev->axes[ABS_X ][AXE_ABS]) : 0; - ji->js.lY = test_bit(ji->joydev->absbits, ABS_Y) ? map_axis(ji, ABS_Y, ji->joydev->axes[ABS_Y ][AXE_ABS]) : 0; - ji->js.lZ = test_bit(ji->joydev->absbits, ABS_Z) ? map_axis(ji, ABS_Z, ji->joydev->axes[ABS_Z ][AXE_ABS]) : 0; - ji->js.lRx = test_bit(ji->joydev->absbits, ABS_RX) ? map_axis(ji, ABS_RX, ji->joydev->axes[ABS_RX ][AXE_ABS]) : 0; - ji->js.lRy = test_bit(ji->joydev->absbits, ABS_RY) ? map_axis(ji, ABS_RY, ji->joydev->axes[ABS_RY ][AXE_ABS]) : 0; - ji->js.lRz = test_bit(ji->joydev->absbits, ABS_RZ) ? map_axis(ji, ABS_RZ, ji->joydev->axes[ABS_RZ ][AXE_ABS]) : 0; - ji->js.rglSlider[0] = test_bit(ji->joydev->absbits, ABS_THROTTLE) ? map_axis(ji, ABS_THROTTLE, ji->joydev->axes[ABS_THROTTLE][AXE_ABS]) : 0; - ji->js.rglSlider[1] = test_bit(ji->joydev->absbits, ABS_RUDDER) ? map_axis(ji, ABS_RUDDER, ji->joydev->axes[ABS_RUDDER ][AXE_ABS]) : 0; + ji->js.lX = test_bit(ji->joydev->absbits, ABS_X) ? map_axis(ji, ji->axes[ABS_X], ji->joydev->axes[ABS_X ][AXE_ABS]) : 0; + ji->js.lY = test_bit(ji->joydev->absbits, ABS_Y) ? map_axis(ji, ji->axes[ABS_Y], ji->joydev->axes[ABS_Y ][AXE_ABS]) : 0; + ji->js.lZ = test_bit(ji->joydev->absbits, ABS_Z) ? map_axis(ji, ji->axes[ABS_Z], ji->joydev->axes[ABS_Z ][AXE_ABS]) : 0; + ji->js.lRx = test_bit(ji->joydev->absbits, ABS_RX) ? map_axis(ji, ji->axes[ABS_RX], ji->joydev->axes[ABS_RX ][AXE_ABS]) : 0; + ji->js.lRy = test_bit(ji->joydev->absbits, ABS_RY) ? map_axis(ji, ji->axes[ABS_RY], ji->joydev->axes[ABS_RY ][AXE_ABS]) : 0; + ji->js.lRz = test_bit(ji->joydev->absbits, ABS_RZ) ? map_axis(ji, ji->axes[ABS_RZ], ji->joydev->axes[ABS_RZ ][AXE_ABS]) : 0; + ji->js.rglSlider[0] = test_bit(ji->joydev->absbits, ABS_THROTTLE) ? map_axis(ji, ji->axes[ABS_THROTTLE], ji->joydev->axes[ABS_THROTTLE][AXE_ABS]) : 0; + ji->js.rglSlider[1] = test_bit(ji->joydev->absbits, ABS_RUDDER) ? map_axis(ji, ji->axes[ABS_RUDDER], ji->joydev->axes[ABS_RUDDER ][AXE_ABS]) : 0; /* POV center is -1 */ for (i=0; i<4; i++) { ji->js.rgdwPOV[i] = -1; @@ -658,45 +649,6 @@ static DWORD map_pov(int event_value, int is_x) return ret; } -/* defines how the linux input system offset mappings into c_dfDIJoystick2 */ -static int lxinput_to_user_index(JoystickImpl *This, int ie_type, int ie_code ) -{ - int offset = -1; - switch (ie_type) { - case EV_ABS: - switch (ie_code) { - case ABS_X: offset = 0; break; - case ABS_Y: offset = 1; break; - case ABS_Z: offset = 2; break; - case ABS_RX: offset = 3; break; - case ABS_RY: offset = 4; break; - case ABS_RZ: offset = 5; break; - case ABS_THROTTLE: offset = 6; break; - case ABS_RUDDER: offset = 7; break; - case ABS_HAT0X: case ABS_HAT0Y: offset = 8; break; - case ABS_HAT1X: case ABS_HAT1Y: offset = 9; break; - case ABS_HAT2X: case ABS_HAT2Y: offset = 10; break; - case ABS_HAT3X: case ABS_HAT3Y: offset = 11; break; - /* XXX when adding new axes here also fix the offset for the buttons bellow */ - default: - FIXME("Unhandled EV_ABS(0x%02X)\n", ie_code); - return -1; - } - break; - case EV_KEY: - if (ie_code >= 128) { - WARN("DX8 does not support more than 128 buttons\n"); - return -1; - } - offset = 12 + ie_code; /* XXX */ - break; - default: - FIXME("Unhandled type(0x%02X)\n", ie_type); - return -1; - } - return offset; -} - /* convert wine format offset to user format object index */ static void joy_polldev(JoystickImpl *This) { @@ -725,7 +677,7 @@ static void joy_polldev(JoystickImpl *This) switch (ie.type) { case EV_KEY: /* button */ { - int btn = This->joydev->buttons[ie.code]; + int btn = This->buttons[ie.code]; TRACE("(%p) %d -> %d\n", This, ie.code, btn); if (btn & 0x80) @@ -737,10 +689,13 @@ static void joy_polldev(JoystickImpl *This) break; } case EV_ABS: - if ((inst_id = lxinput_to_user_index(This, ie.type, ie.code)) == -1) - return; - inst_id = DIDFT_MAKEINSTANCE(inst_id) | (inst_id < ABS_HAT0X ? DIDFT_AXIS : DIDFT_POV); - value = map_axis(This, ie.code, ie.value); + { + int axis = This->axes[ie.code]; + if (axis==-1) { + break; + } + inst_id = DIDFT_MAKEINSTANCE(axis) | (ie.code < ABS_HAT0X ? DIDFT_ABSAXIS : DIDFT_POV); + value = map_axis(This, axis, ie.value); switch (ie.code) { case ABS_X: This->js.lX = value; break; @@ -768,10 +723,11 @@ static void joy_polldev(JoystickImpl *This) This->js.rgdwPOV[3] = value = map_pov(ie.value, ie.code==ABS_HAT3X); break; default: - FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value); + FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value); break; } break; + } #ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION case EV_FF_STATUS: This->ff_state = ie.value; @@ -844,16 +800,16 @@ static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, int i; TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax); for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++) { - This->wantmin[i] = pr->lMin; - This->wantmax[i] = pr->lMax; + This->props[i].wantmin = pr->lMin; + This->props[i].wantmax = pr->lMax; } } else { int obj = find_property(&This->base.data_format, ph); TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj); if (obj >= 0) { - This->wantmin[obj] = pr->lMin; - This->wantmax[obj] = pr->lMax; + This->props[obj].wantmin = pr->lMin; + This->props[obj].wantmax = pr->lMax; } } fake_current_js_state(This); @@ -865,14 +821,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->deadz[i] = pd->dwData; + This->props[i].deadzone = 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->deadz[obj] = pd->dwData; + This->props[obj].deadzone = pd->dwData; } } fake_current_js_state(This); @@ -982,8 +938,8 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, int obj = find_property(&This->base.data_format, pdiph); if (obj >= 0) { - pr->lMin = This->joydev->havemin[obj]; - pr->lMax = This->joydev->havemax[obj]; + pr->lMin = This->props[obj].havemin; + pr->lMax = This->props[obj].havemax; TRACE("range(%d, %d) obj=%d\n", pr->lMin, pr->lMax, obj); } break;