mirror of
https://github.com/glfw/glfw.git
synced 2025-06-16 12:37:43 +00:00
add linux rumble support
This commit is contained in:
parent
6d8d416c95
commit
b0840ad5bb
@ -122,6 +122,49 @@ static void pollAbsState(_GLFWjoystick* js)
|
||||
|
||||
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
|
||||
|
||||
static void checkForceFeedback(_GLFWjoystickLinux *linjs)
|
||||
{
|
||||
linjs->rumble = NULL;
|
||||
struct ff_effect* effect = NULL;
|
||||
|
||||
char ffBits[(FF_CNT + 7) / 8] = {0};
|
||||
if (ioctl(linjs->fd, EVIOCGBIT(EV_FF, sizeof(ffBits)), ffBits) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBitSet(FF_RUMBLE, ffBits))
|
||||
{
|
||||
effect = malloc(sizeof(struct ff_effect));
|
||||
*effect = (struct ff_effect)
|
||||
{
|
||||
.type = FF_RUMBLE,
|
||||
.id = -1,
|
||||
.direction = 0,
|
||||
.trigger = {
|
||||
.button = 0,
|
||||
.interval = 0
|
||||
},
|
||||
.replay = {
|
||||
.length = 2000, // xinput rumble lasts ~2 seconds
|
||||
.delay = 0
|
||||
},
|
||||
.u.rumble = {
|
||||
.strong_magnitude = 0,
|
||||
.weak_magnitude = 0
|
||||
}
|
||||
};
|
||||
|
||||
if (ioctl(linjs->fd, EVIOCSFF, effect) < 0)
|
||||
{
|
||||
free(effect);
|
||||
return;
|
||||
} else {
|
||||
linjs->rumble = effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to open the specified joystick device
|
||||
//
|
||||
static GLFWbool openJoystickDevice(const char* path)
|
||||
@ -135,7 +178,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
}
|
||||
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
linjs.fd = open(path, O_RDWR | O_NONBLOCK);
|
||||
if (linjs.fd == -1)
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -222,6 +265,8 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
}
|
||||
}
|
||||
|
||||
checkForceFeedback(&linjs);
|
||||
|
||||
_GLFWjoystick* js =
|
||||
_glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
if (!js)
|
||||
@ -246,6 +291,8 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
close(js->linjs.fd);
|
||||
if (js->linjs.rumble)
|
||||
free(js->linjs.rumble);
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
}
|
||||
@ -431,3 +478,32 @@ void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int _glfwPlatformSetGamepadRumble(_GLFWjoystick* js, float slowMotorSpeed, float fastMotorSpeed)
|
||||
{
|
||||
_GLFWjoystickLinux *linjs = &js->linjs;
|
||||
|
||||
if (!js->linjs.rumble)
|
||||
return GLFW_FALSE;
|
||||
|
||||
js->linjs.rumble->u.rumble = (struct ff_rumble_effect)
|
||||
{
|
||||
.strong_magnitude = 65535 * slowMotorSpeed,
|
||||
.weak_magnitude = 65535 * fastMotorSpeed
|
||||
};
|
||||
|
||||
struct input_event play =
|
||||
{
|
||||
.type = EV_FF,
|
||||
.code = linjs->rumble->id,
|
||||
.value = 1
|
||||
};
|
||||
|
||||
if (ioctl(linjs->fd, EVIOCSFF, linjs->rumble) < 0 ||
|
||||
write(linjs->fd, (const void*) &play, sizeof(play)) < 0)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
@ -43,6 +43,7 @@ typedef struct _GLFWjoystickLinux
|
||||
int absMap[ABS_CNT];
|
||||
struct input_absinfo absInfo[ABS_CNT];
|
||||
int hats[4][2];
|
||||
struct ff_effect *rumble;
|
||||
} _GLFWjoystickLinux;
|
||||
|
||||
// Linux-specific joystick API data
|
||||
|
Loading…
Reference in New Issue
Block a user