From: Ivo Ivanov logos128@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 540a4da508f..88b5bddf532 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -949,7 +949,7 @@ static NTSTATUS lnxev_device_physical_device_set_gain(struct unix_device *iface, { .type = EV_FF, .code = FF_GAIN, - .value = percent, + .value = 0xffff * percent / 100, };
TRACE("iface %p, percent %#x.\n", iface, percent);
From: Ivo Ivanov logos128@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_sdl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index 76d90ab7912..37d75d0bc95 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -515,7 +515,7 @@ static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BY pSDL_HapticStopAll(impl->sdl_haptic); /* fallthrough */ case PID_USAGE_OP_EFFECT_START: - pSDL_HapticRunEffect(impl->sdl_haptic, id, iterations); + pSDL_HapticRunEffect(impl->sdl_haptic, id, (iterations == 0xff ? SDL_HAPTIC_INFINITY : iterations)); break; case PID_USAGE_OP_EFFECT_STOP: pSDL_HapticStopEffect(impl->sdl_haptic, id); @@ -592,7 +592,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT case PID_USAGE_ET_TRIANGLE: case PID_USAGE_ET_SAWTOOTH_UP: case PID_USAGE_ET_SAWTOOTH_DOWN: - effect.periodic.length = params->duration; + effect.periodic.length = (params->duration == 0xffff ? SDL_HAPTIC_INFINITY : params->duration); effect.periodic.delay = params->start_delay; effect.periodic.button = params->trigger_button; effect.periodic.interval = params->trigger_repeat_interval; @@ -613,7 +613,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT case PID_USAGE_ET_DAMPER: case PID_USAGE_ET_INERTIA: case PID_USAGE_ET_FRICTION: - effect.condition.length = params->duration; + effect.condition.length = (params->duration == 0xffff ? SDL_HAPTIC_INFINITY : params->duration); effect.condition.delay = params->start_delay; effect.condition.button = params->trigger_button; effect.condition.interval = params->trigger_repeat_interval; @@ -641,7 +641,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT break;
case PID_USAGE_ET_CONSTANT_FORCE: - effect.constant.length = params->duration; + effect.constant.length = (params->duration == 0xffff ? SDL_HAPTIC_INFINITY : params->duration); effect.constant.delay = params->start_delay; effect.constant.button = params->trigger_button; effect.constant.interval = params->trigger_repeat_interval; @@ -655,6 +655,8 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT effect.constant.fade_level = params->envelope.fade_level; break;
+ /* According to the SDL documentation, ramp effect doesn't + * support SDL_HAPTIC_INFINITY. */ case PID_USAGE_ET_RAMP: effect.ramp.length = params->duration; effect.ramp.delay = params->start_delay;
From: Ivo Ivanov logos128@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index 88b5bddf532..dfba65fd06d 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1045,7 +1045,7 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B if (params->effect_type == PID_USAGE_UNDEFINED) return STATUS_SUCCESS; if ((status = set_effect_type_from_usage(&effect, params->effect_type))) return status;
- effect.replay.length = params->duration; + effect.replay.length = (params->duration == 0xffff ? 0 : params->duration); effect.replay.delay = params->start_delay; effect.trigger.button = params->trigger_button; effect.trigger.interval = params->trigger_repeat_interval;
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c index 8680f8a088c..32628f1f2fd 100644 --- a/dlls/winebus.sys/hid.c +++ b/dlls/winebus.sys/hid.c @@ -641,7 +641,7 @@ static BOOL hid_descriptor_add_set_condition(struct unix_device *iface) USAGE(1, PID_USAGE_NEGATIVE_SATURATION), USAGE(1, PID_USAGE_DEAD_BAND), LOGICAL_MINIMUM(1, 0), - LOGICAL_MAXIMUM(2, 0x7fff), + LOGICAL_MAXIMUM(4, 0xffff), PHYSICAL_MINIMUM(1, 0), PHYSICAL_MAXIMUM(2, +10000), REPORT_SIZE(1, 16),
This partially reverts b431dceeca9aa0d4229c3597b833bcaf04de7110, which followed some misleading SDL comment, as well as the original dinput evdev backend code, and resulted in inverted directions instead.
On the Linux drivers side, both in the PID driver or the I-Force driver, the evdev direction is simply rescaled and passed to the device. It is then very likely that we should pass through the PID reports direction.
In some other drivers, the sine of the angle is used to modulate the force magnitude, although that doesn't really tell anything about the orientation of the direction itself.
The SDL comment is incorrect, and its code isn't actually doing any kind of conversion other than the rescaling. We now do the same here, and end up with identical values being sent to evdev, whether we use it directly or through the SDL library.
It's also been confirmed with hidraw PID capable devices, that with this change, the direction values in the hardware PID reports are consistent between the three backends (SDL, evdev, and hidraw).
If some devices are expecting inverted directions then it probably is something that will need to be solved on the Linux driver level.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/bus_udev.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index dfba65fd06d..5859078c097 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1050,14 +1050,9 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B effect.trigger.button = params->trigger_button; effect.trigger.interval = params->trigger_repeat_interval;
- /* Linux FF only supports polar direction, and uses an inverted convention compared - * to SDL or dinput (see SDL src/haptic/linux/SDL_syshaptic.c), where the force pulls - * into the specified direction, instead of coming from it. - * - * The first direction we get from PID is in polar coordinate space, so we need to - * add 180° to make it match Linux coordinates. */ - effect.direction = (params->direction[0] + 18000) % 36000; - effect.direction = effect.direction * 0x800 / 1125; + /* Linux FF only supports polar direction, and the first direction we get from PID + * is in polar coordinate space already. */ + effect.direction = params->direction[0] * 0x800 / 1125;
switch (params->effect_type) {