Re-added balls to the SDL joystick API

It turns out these were being used on Linux and at least one virtual driver was making use of them (thanks @mrfixit2001!)
This commit is contained in:
Sam Lantinga 2024-03-10 21:06:14 -07:00
parent 53e86be22f
commit efbbafb3f1
16 changed files with 262 additions and 28 deletions

View file

@ -1091,15 +1091,21 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
joystick->guid = driver->GetDeviceGUID(device_index);
if (joystick->naxes > 0) {
joystick->axes = (SDL_JoystickAxisInfo *)SDL_calloc(joystick->naxes, sizeof(SDL_JoystickAxisInfo));
joystick->axes = (SDL_JoystickAxisInfo *)SDL_calloc(joystick->naxes, sizeof(*joystick->axes));
}
if (joystick->nballs > 0) {
joystick->balls = (SDL_JoystickBallData *)SDL_calloc(joystick->nballs, sizeof(*joystick->balls));
}
if (joystick->nhats > 0) {
joystick->hats = (Uint8 *)SDL_calloc(joystick->nhats, sizeof(Uint8));
joystick->hats = (Uint8 *)SDL_calloc(joystick->nhats, sizeof(*joystick->hats));
}
if (joystick->nbuttons > 0) {
joystick->buttons = (Uint8 *)SDL_calloc(joystick->nbuttons, sizeof(Uint8));
joystick->buttons = (Uint8 *)SDL_calloc(joystick->nbuttons, sizeof(*joystick->buttons));
}
if (((joystick->naxes > 0) && !joystick->axes) || ((joystick->nhats > 0) && !joystick->hats) || ((joystick->nbuttons > 0) && !joystick->buttons)) {
if (((joystick->naxes > 0) && !joystick->axes) ||
((joystick->nballs > 0) && !joystick->balls) ||
((joystick->nhats > 0) && !joystick->hats) ||
((joystick->nbuttons > 0) && !joystick->buttons)) {
SDL_CloseJoystick(joystick);
SDL_UnlockJoysticks();
return NULL;
@ -1324,6 +1330,16 @@ int SDL_GetNumJoystickHats(SDL_Joystick *joystick)
return retval;
}
/*
* Get the number of trackballs on a joystick
*/
int SDL_GetNumJoystickBalls(SDL_Joystick *joystick)
{
CHECK_JOYSTICK_MAGIC(joystick, -1);
return joystick->nballs;
}
/*
* Get the number of buttons on a joystick
*/
@ -1414,6 +1430,31 @@ Uint8 SDL_GetJoystickHat(SDL_Joystick *joystick, int hat)
return state;
}
/*
* Get the ball axis change since the last poll
*/
int SDL_GetJoystickBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
{
int retval;
CHECK_JOYSTICK_MAGIC(joystick, -1);
retval = 0;
if (ball < joystick->nballs) {
if (dx) {
*dx = joystick->balls[ball].dx;
}
if (dy) {
*dy = joystick->balls[ball].dy;
}
joystick->balls[ball].dx = 0;
joystick->balls[ball].dy = 0;
} else {
return SDL_SetError("Joystick only has %d balls", joystick->nballs);
}
return retval;
}
/*
* Get the current state of a button on a joystick
*/
@ -1781,6 +1822,7 @@ void SDL_CloseJoystick(SDL_Joystick *joystick)
SDL_free(joystick->path);
SDL_free(joystick->serial);
SDL_free(joystick->axes);
SDL_free(joystick->balls);
SDL_free(joystick->hats);
SDL_free(joystick->buttons);
for (i = 0; i < joystick->ntouchpads; i++) {
@ -2101,6 +2143,41 @@ int SDL_SendJoystickAxis(Uint64 timestamp, SDL_Joystick *joystick, Uint8 axis, S
return posted;
}
int SDL_SendJoystickBall(Uint64 timestamp, SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel)
{
int posted;
SDL_AssertJoysticksLocked();
/* Make sure we're not getting garbage events */
if (ball >= joystick->nballs) {
return 0;
}
/* We ignore events if we don't have keyboard focus. */
if (SDL_PrivateJoystickShouldIgnoreEvent()) {
return 0;
}
/* Update internal mouse state */
joystick->balls[ball].dx += xrel;
joystick->balls[ball].dy += yrel;
/* Post the event, if desired */
posted = 0;
if (SDL_EventEnabled(SDL_EVENT_JOYSTICK_BALL_MOTION)) {
SDL_Event event;
event.type = SDL_EVENT_JOYSTICK_BALL_MOTION;
event.common.timestamp = timestamp;
event.jball.which = joystick->instance_id;
event.jball.ball = ball;
event.jball.xrel = xrel;
event.jball.yrel = yrel;
posted = SDL_PushEvent(&event) == 1;
}
return posted;
}
int SDL_SendJoystickHat(Uint64 timestamp, SDL_Joystick *joystick, Uint8 hat, Uint8 value)
{
int posted;
@ -2310,6 +2387,7 @@ void SDL_UpdateJoysticks(void)
static const Uint32 SDL_joystick_event_list[] = {
SDL_EVENT_JOYSTICK_AXIS_MOTION,
SDL_EVENT_JOYSTICK_BALL_MOTION,
SDL_EVENT_JOYSTICK_HAT_MOTION,
SDL_EVENT_JOYSTICK_BUTTON_DOWN,
SDL_EVENT_JOYSTICK_BUTTON_UP,