winebus.sys: Rotate directions to match the backend conventions.
The first direction in HID PID reports seems to be in polar space, rotated by 90° compared to the spherical coordinate space used in dinput. We need to fixup the directions to match Linux FF or SDL direction coordinate space. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51922 Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8feeb883e1
commit
b431dceeca
|
@ -565,6 +565,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT
|
||||||
struct sdl_device *impl = impl_from_unix_device(iface);
|
struct sdl_device *impl = impl_from_unix_device(iface);
|
||||||
int id = impl->effect_ids[index];
|
int id = impl->effect_ids[index];
|
||||||
SDL_HapticEffect effect = {0};
|
SDL_HapticEffect effect = {0};
|
||||||
|
UINT16 direction;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
TRACE("iface %p, index %u, params %p.\n", iface, index, params);
|
TRACE("iface %p, index %u, params %p.\n", iface, index, params);
|
||||||
|
@ -572,6 +573,10 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT
|
||||||
if (params->effect_type == PID_USAGE_UNDEFINED) return STATUS_SUCCESS;
|
if (params->effect_type == PID_USAGE_UNDEFINED) return STATUS_SUCCESS;
|
||||||
if ((status = set_effect_type_from_usage(&effect, params->effect_type))) return status;
|
if ((status = set_effect_type_from_usage(&effect, params->effect_type))) return status;
|
||||||
|
|
||||||
|
/* The first direction we get from PID is in polar coordinate space, so we need to
|
||||||
|
* remove 90° to make it match SDL spherical coordinates. */
|
||||||
|
direction = (params->direction[0] - 9000) % 36000;
|
||||||
|
|
||||||
switch (params->effect_type)
|
switch (params->effect_type)
|
||||||
{
|
{
|
||||||
case PID_USAGE_ET_SINE:
|
case PID_USAGE_ET_SINE:
|
||||||
|
@ -584,7 +589,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT
|
||||||
effect.periodic.button = params->trigger_button;
|
effect.periodic.button = params->trigger_button;
|
||||||
effect.periodic.interval = params->trigger_repeat_interval;
|
effect.periodic.interval = params->trigger_repeat_interval;
|
||||||
effect.periodic.direction.type = SDL_HAPTIC_SPHERICAL;
|
effect.periodic.direction.type = SDL_HAPTIC_SPHERICAL;
|
||||||
effect.periodic.direction.dir[0] = params->direction[0];
|
effect.periodic.direction.dir[0] = direction;
|
||||||
effect.periodic.direction.dir[1] = params->direction[1];
|
effect.periodic.direction.dir[1] = params->direction[1];
|
||||||
effect.periodic.period = params->periodic.period;
|
effect.periodic.period = params->periodic.period;
|
||||||
effect.periodic.magnitude = params->periodic.magnitude;
|
effect.periodic.magnitude = params->periodic.magnitude;
|
||||||
|
@ -605,7 +610,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT
|
||||||
effect.condition.button = params->trigger_button;
|
effect.condition.button = params->trigger_button;
|
||||||
effect.condition.interval = params->trigger_repeat_interval;
|
effect.condition.interval = params->trigger_repeat_interval;
|
||||||
effect.condition.direction.type = SDL_HAPTIC_SPHERICAL;
|
effect.condition.direction.type = SDL_HAPTIC_SPHERICAL;
|
||||||
effect.condition.direction.dir[0] = params->direction[0];
|
effect.condition.direction.dir[0] = direction;
|
||||||
effect.condition.direction.dir[1] = params->direction[1];
|
effect.condition.direction.dir[1] = params->direction[1];
|
||||||
if (params->condition_count >= 1)
|
if (params->condition_count >= 1)
|
||||||
{
|
{
|
||||||
|
@ -633,7 +638,7 @@ static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYT
|
||||||
effect.constant.button = params->trigger_button;
|
effect.constant.button = params->trigger_button;
|
||||||
effect.constant.interval = params->trigger_repeat_interval;
|
effect.constant.interval = params->trigger_repeat_interval;
|
||||||
effect.constant.direction.type = SDL_HAPTIC_SPHERICAL;
|
effect.constant.direction.type = SDL_HAPTIC_SPHERICAL;
|
||||||
effect.constant.direction.dir[0] = params->direction[0];
|
effect.constant.direction.dir[0] = direction;
|
||||||
effect.constant.direction.dir[1] = params->direction[1];
|
effect.constant.direction.dir[1] = params->direction[1];
|
||||||
effect.constant.level = params->constant_force.magnitude;
|
effect.constant.level = params->constant_force.magnitude;
|
||||||
effect.constant.attack_length = params->envelope.attack_time;
|
effect.constant.attack_length = params->envelope.attack_time;
|
||||||
|
|
|
@ -1031,8 +1031,15 @@ static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, B
|
||||||
effect.replay.delay = params->start_delay;
|
effect.replay.delay = params->start_delay;
|
||||||
effect.trigger.button = params->trigger_button;
|
effect.trigger.button = params->trigger_button;
|
||||||
effect.trigger.interval = params->trigger_repeat_interval;
|
effect.trigger.interval = params->trigger_repeat_interval;
|
||||||
/* only supports polar with one direction angle */
|
|
||||||
effect.direction = params->direction[0] * 0x800 / 1125;
|
/* 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;
|
||||||
|
|
||||||
switch (params->effect_type)
|
switch (params->effect_type)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue