Linux/evdev: Add Force Feedback/Rumble support

This commit is contained in:
Jan Holthuis 2015-12-14 01:09:03 +01:00
parent c42986e63f
commit cc5719e845
3 changed files with 62 additions and 2 deletions

View File

@ -102,6 +102,7 @@
this->data_y.init(this->fd, this->mapping->Axis_Analog_Y, this->mapping->Axis_Analog_Y_Inverted);
this->data_trigger_left.init(this->fd, this->mapping->Axis_Trigger_Left, this->mapping->Axis_Trigger_Left_Inverted);
this->data_trigger_right.init(this->fd, this->mapping->Axis_Trigger_Right, this->mapping->Axis_Trigger_Right_Inverted);
this->rumble_effect_id = -1;
}
std::map<std::string, EvdevControllerMapping> loaded_mappings;
@ -202,7 +203,7 @@
printf("evdev: Trying to open device at '%s'\n", device);
int fd = open(device, O_RDONLY);
int fd = open(device, O_RDWR);
if (fd >= 0)
{
@ -446,5 +447,43 @@
}
}
}
void input_evdev_rumble(EvdevController* controller, u16 pow_strong, u16 pow_weak)
{
if (controller->fd < 0 || controller->rumble_effect_id == -2)
{
// Either the controller is not used or previous rumble effect failed
printf("RUMBLE: %s\n", "Skipped!");
return;
}
printf("RUMBLE: %u / %u (%d)\n", pow_strong, pow_weak, controller->rumble_effect_id);
struct ff_effect effect;
effect.type = FF_RUMBLE;
effect.id = controller->rumble_effect_id;
effect.u.rumble.strong_magnitude = pow_strong;
effect.u.rumble.weak_magnitude = pow_weak;
effect.replay.length = 0;
effect.replay.delay = 0;
if (ioctl(controller->fd, EVIOCSFF, &effect) == -1)
{
perror("evdev: Force feedback error");
controller->rumble_effect_id = -2;
}
else
{
controller->rumble_effect_id = effect.id;
// Let's play the effect
input_event play;
play.type = EV_FF;
play.code = effect.id;
play.value = 1;
if (write(controller->fd, (const void*) &play, sizeof(play)) == -1)
{
perror("evdev: Force feedback error");
controller->rumble_effect_id = -2;
}
}
}
#endif

View File

@ -54,6 +54,7 @@ struct EvdevController
EvdevAxisData data_y;
EvdevAxisData data_trigger_left;
EvdevAxisData data_trigger_right;
int rumble_effect_id;
void init();
};
@ -72,3 +73,4 @@ struct EvdevController
extern int input_evdev_init(EvdevController* controller, const char* device, const char* mapping_fname);
extern bool input_evdev_handle(EvdevController* controller, u32 port);
extern void input_evdev_rumble(EvdevController* controller, u16 pow_strong, u16 pow_weak);

View File

@ -193,7 +193,26 @@ void UpdateInputState(u32 port)
void UpdateVibration(u32 port, u32 value)
{
#if defined(USE_EVDEV)
const u8 freq_l = 0x16;
//const u8 freq_h = 0x31;
u8 POW_POS = (value >> 8) & 0x3;
u8 POW_NEG = (value >> 12) & 0x3;
u8 FREQ = (value >> 16) & 0xFF;
double pow = (POW_POS + POW_NEG) / 7.0;
double pow_l = pow * (0x3B - FREQ) / 17.0;
double pow_r = pow * (FREQ / (double)freq_l);
if (pow_l > 1.0) pow_l = 1.0;
if (pow_r > 1.0) pow_r = 1.0;
u16 pow_strong = (u16)(65535 * pow_l);
u16 pow_weak = (u16)(65535 * pow_r);
input_evdev_rumble(&evdev_controllers[port], pow_strong, pow_weak);
#endif
}
void os_DoEvents()