Fixes to force feedback.
This commit is contained in:
parent
3a2e3ce277
commit
0415ccf97e
|
@ -56,7 +56,7 @@ struct udev_joypad
|
||||||
|
|
||||||
int num_effects;
|
int num_effects;
|
||||||
int effects[2]; // [0] - strong, [1] - weak
|
int effects[2]; // [0] - strong, [1] - weak
|
||||||
bool support_ff[2];
|
bool has_set_ff[2];
|
||||||
|
|
||||||
char *ident;
|
char *ident;
|
||||||
char *path;
|
char *path;
|
||||||
|
@ -183,9 +183,37 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, bool st
|
||||||
|
|
||||||
if (pad->fd < 0)
|
if (pad->fd < 0)
|
||||||
return false;
|
return false;
|
||||||
if (!pad->support_ff[effect])
|
if (pad->num_effects < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Have to defer the force feedback settings to here.
|
||||||
|
// For some reason, effects are getting dropped when they're set at init.
|
||||||
|
// Setting at init seems to work for pads which are hotplugged ...
|
||||||
|
//
|
||||||
|
// This approach might be cleaner in the end if we end up supporting configurable force feedback.
|
||||||
|
if (!pad->has_set_ff[effect])
|
||||||
|
{
|
||||||
|
struct ff_effect e;
|
||||||
|
memset(&e, 0, sizeof(e));
|
||||||
|
e.type = FF_RUMBLE;
|
||||||
|
e.id = -1;
|
||||||
|
switch (effect)
|
||||||
|
{
|
||||||
|
case RETRO_RUMBLE_STRONG: e.u.rumble.strong_magnitude = 0xc000; break;
|
||||||
|
case RETRO_RUMBLE_WEAK: e.u.rumble.weak_magnitude = 0xc000; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(pad->fd, EVIOCSFF, &e) < 0)
|
||||||
|
{
|
||||||
|
RARCH_ERR("Failed to set rumble effect on pad #%u.\n", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pad->has_set_ff[effect] = true;
|
||||||
|
pad->effects[effect] = e.id;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -214,12 +242,84 @@ static void udev_joypad_poll(void)
|
||||||
(((1UL << ((nr) % (sizeof(long) * CHAR_BIT))) & ((addr)[(nr) / (sizeof(long) * CHAR_BIT)])) != 0)
|
(((1UL << ((nr) % (sizeof(long) * CHAR_BIT))) & ((addr)[(nr) / (sizeof(long) * CHAR_BIT)])) != 0)
|
||||||
#define NBITS(x) ((((x) - 1) / (sizeof(long) * CHAR_BIT)) + 1)
|
#define NBITS(x) ((((x) - 1) / (sizeof(long) * CHAR_BIT)) + 1)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void test_initial_rumble(int fd, const char *path)
|
||||||
|
{
|
||||||
|
// Check for rumble features.
|
||||||
|
unsigned long ffbit[NBITS(FF_MAX)] = {0};
|
||||||
|
if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0)
|
||||||
|
{
|
||||||
|
if (test_bit(FF_RUMBLE, ffbit))
|
||||||
|
RARCH_LOG("[udev]: Pad (%s) supports force feedback.\n",
|
||||||
|
path);
|
||||||
|
|
||||||
|
int effects;
|
||||||
|
if (ioctl(fd, EVIOCGEFFECTS, &effects) >= 0)
|
||||||
|
RARCH_LOG("[udev]: Pad (%s) supports %d force feedback effects.\n", path, effects);
|
||||||
|
|
||||||
|
if (effects >= 2)
|
||||||
|
{
|
||||||
|
struct ff_effect effect;
|
||||||
|
bool support_ff[2];
|
||||||
|
int effects[2] = {-1, -1};
|
||||||
|
|
||||||
|
// Strong rumble.
|
||||||
|
memset(&effect, 0, sizeof(effect));
|
||||||
|
effect.type = FF_RUMBLE;
|
||||||
|
effect.id = -1;
|
||||||
|
effect.u.rumble.strong_magnitude = 0x8000;
|
||||||
|
effect.u.rumble.weak_magnitude = 0;
|
||||||
|
support_ff[0] = ioctl(fd, EVIOCSFF, &effect) == 0;
|
||||||
|
if (support_ff[0])
|
||||||
|
{
|
||||||
|
RARCH_LOG("[udev]: (%s) supports \"strong\" rumble effect (id %d).\n",
|
||||||
|
path, effect.id);
|
||||||
|
effects[RETRO_RUMBLE_STRONG] = effect.id; // Gets updated by ioctl().
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weak rumble.
|
||||||
|
memset(&effect, 0, sizeof(effect));
|
||||||
|
effect.type = FF_RUMBLE;
|
||||||
|
effect.id = -1;
|
||||||
|
effect.u.rumble.strong_magnitude = 0;
|
||||||
|
effect.u.rumble.weak_magnitude = 0xc000;
|
||||||
|
support_ff[1] = ioctl(fd, EVIOCSFF, &effect) == 0;
|
||||||
|
if (support_ff[1])
|
||||||
|
{
|
||||||
|
RARCH_LOG("[udev]: Pad (%s) supports \"weak\" rumble effect (id %d).\n",
|
||||||
|
path, effect.id);
|
||||||
|
effects[RETRO_RUMBLE_WEAK] = effect.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct input_event play;
|
||||||
|
memset(&play, 0, sizeof(play));
|
||||||
|
play.type = EV_FF;
|
||||||
|
play.code = effects[0];
|
||||||
|
play.value = true;
|
||||||
|
write(fd, &play, sizeof(play));
|
||||||
|
rarch_sleep(500);
|
||||||
|
play.value = false;
|
||||||
|
write(fd, &play, sizeof(play));
|
||||||
|
rarch_sleep(500);
|
||||||
|
play.code = effects[1];
|
||||||
|
play.value = true;
|
||||||
|
write(fd, &play, sizeof(play));
|
||||||
|
rarch_sleep(500);
|
||||||
|
play.value = false;
|
||||||
|
write(fd, &play, sizeof(play));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int open_joystick(const char *path)
|
static int open_joystick(const char *path)
|
||||||
{
|
{
|
||||||
int fd = open(path, O_RDWR | O_NONBLOCK);
|
int fd = open(path, O_RDWR | O_NONBLOCK);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
|
|
||||||
unsigned long evbit[NBITS(EV_MAX)] = {0};
|
unsigned long evbit[NBITS(EV_MAX)] = {0};
|
||||||
unsigned long keybit[NBITS(KEY_MAX)] = {0};
|
unsigned long keybit[NBITS(KEY_MAX)] = {0};
|
||||||
unsigned long absbit[NBITS(ABS_MAX)] = {0};
|
unsigned long absbit[NBITS(ABS_MAX)] = {0};
|
||||||
|
@ -233,6 +333,7 @@ static int open_joystick(const char *path)
|
||||||
if (!test_bit(EV_KEY, evbit))
|
if (!test_bit(EV_KEY, evbit))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -272,6 +373,7 @@ static bool add_pad(unsigned i, int fd, const char *path)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RARCH_LOG("[udev]: Plugged pad: %s on port #%u.\n", pad->ident, i);
|
RARCH_LOG("[udev]: Plugged pad: %s on port #%u.\n", pad->ident, i);
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -333,39 +435,6 @@ static bool add_pad(unsigned i, int fd, const char *path)
|
||||||
|
|
||||||
if (ioctl(fd, EVIOCGEFFECTS, &pad->num_effects) >= 0)
|
if (ioctl(fd, EVIOCGEFFECTS, &pad->num_effects) >= 0)
|
||||||
RARCH_LOG("[udev]: Pad #%u (%s) supports %d force feedback effects.\n", i, path, pad->num_effects);
|
RARCH_LOG("[udev]: Pad #%u (%s) supports %d force feedback effects.\n", i, path, pad->num_effects);
|
||||||
|
|
||||||
if (pad->num_effects >= 2)
|
|
||||||
{
|
|
||||||
struct ff_effect effect;
|
|
||||||
|
|
||||||
// Strong rumble.
|
|
||||||
memset(&effect, 0, sizeof(effect));
|
|
||||||
effect.type = FF_RUMBLE;
|
|
||||||
effect.id = -1;
|
|
||||||
effect.u.rumble.strong_magnitude = 0x8000;
|
|
||||||
effect.u.rumble.weak_magnitude = 0;
|
|
||||||
pad->support_ff[0] = ioctl(fd, EVIOCSFF, &effect) == 0;
|
|
||||||
if (pad->support_ff[0])
|
|
||||||
{
|
|
||||||
RARCH_LOG("[udev]: Pad #%u (%s) supports \"strong\" rumble effect (id %d).\n",
|
|
||||||
i, path, effect.id);
|
|
||||||
pad->effects[RETRO_RUMBLE_STRONG] = effect.id; // Gets updated by ioctl().
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weak rumble.
|
|
||||||
memset(&effect, 0, sizeof(effect));
|
|
||||||
effect.type = FF_RUMBLE;
|
|
||||||
effect.id = -1;
|
|
||||||
effect.u.rumble.strong_magnitude = 0;
|
|
||||||
effect.u.rumble.weak_magnitude = 0xc000;
|
|
||||||
pad->support_ff[1] = ioctl(fd, EVIOCSFF, &effect) == 0;
|
|
||||||
if (pad->support_ff[1])
|
|
||||||
{
|
|
||||||
RARCH_LOG("[udev]: Pad #%u (%s) supports \"weak\" rumble effect (id %d).\n",
|
|
||||||
i, path, effect.id);
|
|
||||||
pad->effects[RETRO_RUMBLE_WEAK] = effect.id; // Gets updated by ioctl().
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -407,6 +476,10 @@ static void check_device(const char *path, bool hotplugged)
|
||||||
#else
|
#else
|
||||||
(void)hotplugged;
|
(void)hotplugged;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
test_initial_rumble(fd, path);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue