mirror of
https://github.com/libretro/RetroArch
synced 2025-02-21 18:40:09 +00:00
Update udev rumble strength atomically.
This commit is contained in:
parent
623ff98b8a
commit
fe8b6c3c0f
@ -58,6 +58,7 @@ struct udev_joypad
|
|||||||
int effects[2]; // [0] - strong, [1] - weak
|
int effects[2]; // [0] - strong, [1] - weak
|
||||||
bool has_set_ff[2];
|
bool has_set_ff[2];
|
||||||
uint16_t strength[2];
|
uint16_t strength[2];
|
||||||
|
uint16_t configured_strength[2];
|
||||||
|
|
||||||
char *ident;
|
char *ident;
|
||||||
char *path;
|
char *path;
|
||||||
@ -184,22 +185,22 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, uint16_
|
|||||||
|
|
||||||
if (pad->fd < 0)
|
if (pad->fd < 0)
|
||||||
return false;
|
return false;
|
||||||
if (pad->num_effects < 3) // Need one effect to overlap.
|
if (pad->num_effects < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pad->strength[effect] == strength)
|
uint16_t old_strength = pad->strength[effect];
|
||||||
|
if (old_strength == strength)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int old_effect = pad->has_set_ff[effect] ? pad->effects[effect] : -1;
|
int old_effect = pad->has_set_ff[effect] ? pad->effects[effect] : -1;
|
||||||
pad->strength[effect] = strength;
|
|
||||||
pad->has_set_ff[effect] = false;
|
|
||||||
|
|
||||||
if (strength)
|
if (strength && strength != pad->configured_strength[effect])
|
||||||
{
|
{
|
||||||
|
// Create new or update old playing state.
|
||||||
struct ff_effect e;
|
struct ff_effect e;
|
||||||
memset(&e, 0, sizeof(e));
|
memset(&e, 0, sizeof(e));
|
||||||
e.type = FF_RUMBLE;
|
e.type = FF_RUMBLE;
|
||||||
e.id = -1;
|
e.id = old_effect;
|
||||||
switch (effect)
|
switch (effect)
|
||||||
{
|
{
|
||||||
case RETRO_RUMBLE_STRONG: e.u.rumble.strong_magnitude = strength; break;
|
case RETRO_RUMBLE_STRONG: e.u.rumble.strong_magnitude = strength; break;
|
||||||
@ -213,14 +214,20 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, uint16_
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pad->has_set_ff[effect] = true;
|
|
||||||
pad->effects[effect] = e.id;
|
pad->effects[effect] = e.id;
|
||||||
|
pad->has_set_ff[effect] = true;
|
||||||
|
pad->configured_strength[effect] = strength;
|
||||||
|
}
|
||||||
|
pad->strength[effect] = strength;
|
||||||
|
|
||||||
|
// It seems that we can update strength with EVIOCSFF atomically.
|
||||||
|
if ((!!strength) != (!!old_strength))
|
||||||
|
{
|
||||||
struct input_event play;
|
struct input_event play;
|
||||||
memset(&play, 0, sizeof(play));
|
memset(&play, 0, sizeof(play));
|
||||||
play.type = EV_FF;
|
play.type = EV_FF;
|
||||||
play.code = pad->effects[effect];
|
play.code = pad->effects[effect];
|
||||||
play.value = 1;
|
play.value = !!strength;
|
||||||
if (write(pad->fd, &play, sizeof(play)) < (ssize_t)sizeof(play))
|
if (write(pad->fd, &play, sizeof(play)) < (ssize_t)sizeof(play))
|
||||||
{
|
{
|
||||||
RARCH_ERR("[udev]: Failed to play rumble effect #%u on pad #%u.\n",
|
RARCH_ERR("[udev]: Failed to play rumble effect #%u on pad #%u.\n",
|
||||||
@ -229,12 +236,6 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, uint16_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_effect >= 0)
|
|
||||||
{
|
|
||||||
if (ioctl(pad->fd, EVIOCRMFF, (void*)(uintptr_t)old_effect) < 0)
|
|
||||||
RARCH_WARN("[udev]: Failed to remove effect.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user