diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index ade7f9e2235..94d82470049 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -82,6 +82,9 @@ extern int id_to_object(LPCDIDATAFORMAT df, int id); extern int id_to_offset(const DataFormat *df, int id); extern int find_property(const DataFormat *df, LPCDIPROPHEADER ph); +/* Common joystick stuff */ +extern DWORD joystick_map_pov(POINTL *p); + /** * Callback Data used by specific callback * for EnumObject on 'W' interfaces diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c index 79c7bc16cf5..25dcf7ff231 100644 --- a/dlls/dinput/joystick_linux.c +++ b/dlls/dinput/joystick_linux.c @@ -83,11 +83,6 @@ typedef struct { LONG lSaturation; } ObjProps; -typedef struct { - LONG lX; - LONG lY; -} POV; - typedef struct JoystickImpl JoystickImpl; static const IDirectInputDevice8AVtbl JoystickAvt; static const IDirectInputDevice8WVtbl JoystickWvt; @@ -107,7 +102,7 @@ struct JoystickImpl int *axis_map; int axes; int buttons; - POV povs[4]; + POINTL povs[4]; }; static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */ @@ -506,7 +501,10 @@ static HRESULT alloc_device(REFGUID rguid, const void *jvt, IDirectInputImpl *di 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 */ + } } for (i = 0; i < newDevice->buttons; i++) { @@ -700,34 +698,6 @@ static LONG map_axis(JoystickImpl * This, short val, short index) return fret; } -static LONG calculate_pov(JoystickImpl *This, int index) -{ - if (This->povs[index].lX < -16384) { - if (This->povs[index].lY < -16384) - This->js.rgdwPOV[index] = 31500; - else if (This->povs[index].lY > 16384) - This->js.rgdwPOV[index] = 22500; - else - This->js.rgdwPOV[index] = 27000; - } else if (This->povs[index].lX > 16384) { - if (This->povs[index].lY < -16384) - This->js.rgdwPOV[index] = 4500; - else if (This->povs[index].lY > 16384) - This->js.rgdwPOV[index] = 13500; - else - This->js.rgdwPOV[index] = 9000; - } else { - if (This->povs[index].lY < -16384) - This->js.rgdwPOV[index] = 0; - else if (This->povs[index].lY > 16384) - This->js.rgdwPOV[index] = 18000; - else - This->js.rgdwPOV[index] = -1; - } - - return This->js.rgdwPOV[index]; -} - static void joy_polldev(JoystickImpl *This) { struct pollfd plfd; struct js_event jse; @@ -761,70 +731,36 @@ static void joy_polldev(JoystickImpl *This) { { int number = This->axis_map[jse.number]; /* wine format object index */ - if (number < 12) - { - 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)); - /* FIXME do deadzone and saturation here */ + 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)); - TRACE("changing axis %d => %d\n", jse.number, number); - switch (number) { - case 0: - This->js.lX = value; - break; - case 1: - This->js.lY = value; - break; - case 2: - This->js.lZ = value; - break; - case 3: - This->js.lRx = value; - break; - case 4: - This->js.lRy = value; - break; - case 5: - This->js.lRz = value; - break; - case 6: - This->js.rglSlider[0] = value; - break; - case 7: - This->js.rglSlider[1] = value; - break; - case 8: - /* FIXME don't go off array */ - if (This->axis_map[jse.number + 1] == number) - This->povs[0].lX = jse.value; - else if (This->axis_map[jse.number - 1] == number) - This->povs[0].lY = jse.value; - value = calculate_pov(This, 0); - break; - case 9: - if (This->axis_map[jse.number + 1] == number) - This->povs[1].lX = jse.value; - else if (This->axis_map[jse.number - 1] == number) - This->povs[1].lY = jse.value; - value = calculate_pov(This, 1); - break; - case 10: - if (This->axis_map[jse.number + 1] == number) - This->povs[2].lX = jse.value; - else if (This->axis_map[jse.number - 1] == number) - This->povs[2].lY = jse.value; - value = calculate_pov(This, 2); - break; - case 11: - if (This->axis_map[jse.number + 1] == number) - This->povs[3].lX = jse.value; - else if (This->axis_map[jse.number - 1] == number) - This->povs[3].lY = jse.value; - value = calculate_pov(This, 3); + TRACE("changing axis %d => %d\n", jse.number, number); + switch (number) + { + case 0: This->js.lX = value; break; + case 1: This->js.lY = value; break; + case 2: This->js.lZ = value; break; + case 3: This->js.lRx = value; break; + case 4: This->js.lRy = value; break; + case 5: This->js.lRz = value; break; + case 6: This->js.rglSlider[0] = value; break; + case 7: This->js.rglSlider[1] = value; break; + case 8: case 9: case 10: case 11: + { + int idx = number - 8; + + if (jse.number % 2) + This->povs[idx].y = jse.value; + else + This->povs[idx].x = jse.value; + + This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]); break; } - } else - WARN("axis %d not supported\n", number); + default: + WARN("axis %d not supported\n", number); + } } if (inst_id >= 0) queue_event((LPDIRECTINPUTDEVICE8A)This, diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index f4c80188a9a..bfbd026dea7 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -65,6 +65,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput); + +/* + * Maps POV x & y event values to a DX "clock" position: + * 0 + * 31500 4500 + * 27000 -1 9000 + * 22500 13500 + * 18000 + */ +DWORD joystick_map_pov(POINTL *p) +{ + if (p->x > 0) + return p->y < 0 ? 4500 : !p->y ? 9000 : 13500; + else if (p->x < 0) + return p->y < 0 ? 31500 : !p->y ? 27000 : 22500; + else + return p->y < 0 ? 0 : !p->y ? -1 : 18000; +} + + #ifdef HAVE_CORRECT_LINUXINPUT_H #define EVDEVPREFIX "/dev/input/event" @@ -139,6 +159,7 @@ struct JoystickImpl struct ObjProps props[ABS_MAX]; int axes[ABS_MAX]; + POINTL povs[4]; /* LUT for KEY_ to offset in rgbButtons */ BYTE buttons[KEY_MAX]; @@ -153,7 +174,6 @@ struct JoystickImpl }; static void fake_current_js_state(JoystickImpl *ji); -static DWORD map_pov(int event_value, int is_x); static void find_joydevs(void); /* This GUID is slightly different from the linux joystick one. Take note. */ @@ -596,31 +616,6 @@ static void fake_current_js_state(JoystickImpl *ji) } } -/* - * 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; -} - /* convert wine format offset to user format object index */ static void joy_polldev(JoystickImpl *This) { @@ -678,25 +673,21 @@ static void joy_polldev(JoystickImpl *This) case ABS_RZ: This->js.lRz = value; break; case ABS_THROTTLE: This->js.rglSlider[0] = value; break; case ABS_RUDDER: This->js.rglSlider[1] = value; break; - case ABS_HAT0X: - case ABS_HAT0Y: - This->js.rgdwPOV[0] = value = map_pov(ie.value, ie.code==ABS_HAT0X); - break; - case ABS_HAT1X: - case ABS_HAT1Y: - This->js.rgdwPOV[1] = value = map_pov(ie.value, ie.code==ABS_HAT1X); - break; - case ABS_HAT2X: - case ABS_HAT2Y: - This->js.rgdwPOV[2] = value = map_pov(ie.value, ie.code==ABS_HAT2X); - break; - case ABS_HAT3X: - case ABS_HAT3Y: - This->js.rgdwPOV[3] = value = map_pov(ie.value, ie.code==ABS_HAT3X); + case ABS_HAT0X: case ABS_HAT0Y: case ABS_HAT1X: case ABS_HAT1Y: + case ABS_HAT2X: case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y: + { + int idx = (ie.code - ABS_HAT0X) / 2; + + if (ie.code % 2) + This->povs[idx].y = ie.value; + else + This->povs[idx].x = ie.value; + + This->js.rgdwPOV[idx] = value = joystick_map_pov(&This->povs[idx]); break; + } default: FIXME("unhandled joystick axis event (code %d, value %d)\n",ie.code,ie.value); - break; } break; }