Linux/evdev: Add Force Feedback/Rumble support
This commit is contained in:
parent
c42986e63f
commit
cc5719e845
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue