Added hotplug joystick support and simplified game controller API, courtesy of Alfred Reynolds

This commit is contained in:
Sam Lantinga 2012-11-26 16:37:54 -08:00
parent 2a4a81ad63
commit 34b88dfaae
30 changed files with 4191 additions and 580 deletions

View file

@ -298,7 +298,7 @@ CountLogicalJoysticks(int max)
ret = 0;
for (i = 0; i < max; i++) {
name = SDL_SYS_JoystickName(i);
name = SDL_SYS_JoystickNameForIndex(i);
fd = open(SDL_joylist[i].fname, O_RDONLY, 0);
if (fd >= 0) {
@ -390,6 +390,8 @@ EV_IsJoystick(int fd)
#endif /* SDL_INPUT_LINUXEV */
int SDL_SYS_numjoysticks = 0;
/* Function to scan the system for joysticks */
int
SDL_SYS_JoystickInit(void)
@ -491,7 +493,7 @@ SDL_SYS_JoystickInit(void)
will be duplicates but without extra information about their
hats or balls. Unfortunately, the event devices can't
currently be calibrated, so it's a win-lose situation.
So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
So : /dev/input/eventX = /dev/input/jsY = /dev/js
*/
if ((i == 0) && (numjoysticks > 0))
break;
@ -501,12 +503,13 @@ SDL_SYS_JoystickInit(void)
numjoysticks += CountLogicalJoysticks(numjoysticks);
#endif
SDL_SYS_numjoysticks = numjoysticks;
return (numjoysticks);
}
/* Function to get the device-dependent name of a joystick */
const char *
SDL_SYS_JoystickName(int index)
SDL_SYS_JoystickNameForIndex(int index)
{
int fd;
static char namebuf[128];
@ -601,7 +604,7 @@ JS_ConfigJoystick(SDL_Joystick * joystick, int fd)
joystick->nbuttons = n;
}
name = SDL_SYS_JoystickName(joystick->index);
name = SDL_SYS_JoystickNameForIndex(joystick->instance_id);
/* Generic analog joystick support */
if (SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat")) {
@ -774,8 +777,8 @@ ConfigLogicalJoystick(SDL_Joystick * joystick)
{
struct joystick_logical_layout *layout;
layout = SDL_joylist[joystick->index].map->layout +
SDL_joylist[joystick->index].logicalno;
layout = SDL_joylist[joystick->instance_id].map->layout +
SDL_joylist[joystick->instance_id].logicalno;
joystick->nbuttons = layout->nbuttons;
joystick->nhats = layout->nhats;
@ -791,7 +794,7 @@ ConfigLogicalJoystick(SDL_Joystick * joystick)
It returns 0, or -1 if there is an error.
*/
int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
{
int fd;
char *fname;
@ -800,8 +803,8 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
/* Open the joystick and set the joystick file descriptor */
#ifndef NO_LOGICAL_JOYSTICKS
if (SDL_joylist[joystick->index].fname == NULL) {
SDL_joylist_head(realindex, joystick->index);
if (SDL_joylist[joystick->instance_id].fname == NULL) {
SDL_joylist_head(realindex, joystick->instance_id);
realjoy = SDL_JoystickOpen(realindex);
if (realjoy == NULL)
@ -811,17 +814,17 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
fname = realjoy->hwdata->fname;
} else {
fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
fname = SDL_joylist[joystick->index].fname;
fd = open(SDL_joylist[joystick->instance_id].fname, O_RDONLY, 0);
fname = SDL_joylist[joystick->instance_id].fname;
}
SDL_joylist[joystick->index].joy = joystick;
SDL_joylist[joystick->instance_id].joy = joystick;
#else
fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
fname = SDL_joylist[joystick->index].fname;
fd = open(SDL_joylist[joystick->instance_id].fname, O_RDONLY, 0);
fname = SDL_joylist[joystick->instance_id].fname;
#endif
if (fd < 0) {
SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->index]);
SDL_SetError("Unable to open %s\n", SDL_joylist[joystick->instance_id]);
return (-1);
}
joystick->hwdata = (struct joystick_hwdata *)
@ -834,6 +837,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
joystick->hwdata->fd = fd;
joystick->hwdata->fname = fname;
joystick->instance_id = device_index;
/* Set the joystick to non-blocking read mode */
fcntl(fd, F_SETFL, O_NONBLOCK);
@ -861,7 +865,7 @@ FindLogicalJoystick(SDL_Joystick * joystick,
SDL_Joystick *logicaljoy;
register int i;
i = joystick->index;
i = joystick->instance_id;
logicaljoy = NULL;
/* get the fake joystick that will receive the event
@ -891,12 +895,12 @@ LogicalJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state)
/* if there's no map then this is just a regular joystick
*/
if (SDL_joylist[joystick->index].map == NULL)
if (SDL_joylist[joystick->instance_id].map == NULL)
return 0;
/* get the logical joystick that will receive the event
*/
buttons = SDL_joylist[joystick->index].map->buttonmap + button;
buttons = SDL_joylist[joystick->instance_id].map->buttonmap + button;
logicaljoy = FindLogicalJoystick(joystick, buttons);
if (logicaljoy == NULL)
@ -915,12 +919,12 @@ LogicalJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
/* if there's no map then this is just a regular joystick
*/
if (SDL_joylist[joystick->index].map == NULL)
if (SDL_joylist[joystick->instance_id].map == NULL)
return 0;
/* get the logical joystick that will receive the event
*/
axes = SDL_joylist[joystick->index].map->axismap + axis;
axes = SDL_joylist[joystick->instance_id].map->axismap + axis;
logicaljoy = FindLogicalJoystick(joystick, axes);
if (logicaljoy == NULL)
@ -958,11 +962,11 @@ HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value)
#ifndef NO_LOGICAL_JOYSTICKS
/* if there's no map then this is just a regular joystick
*/
if (SDL_joylist[stick->index].map != NULL) {
if (SDL_joylist[stick->instance_id].map != NULL) {
/* get the fake joystick that will receive the event
*/
hats = SDL_joylist[stick->index].map->hatmap + hat;
hats = SDL_joylist[stick->instance_id].map->hatmap + hat;
logicaljoy = FindLogicalJoystick(stick, hats);
}
@ -997,8 +1001,8 @@ JS_HandleEvents(SDL_Joystick * joystick)
Uint8 other_axis;
#ifndef NO_LOGICAL_JOYSTICKS
if (SDL_joylist[joystick->index].fname == NULL) {
SDL_joylist_head(i, joystick->index);
if (SDL_joylist[joystick->instance_id].fname == NULL) {
SDL_joylist_head(i, joystick->instance_id);
JS_HandleEvents(SDL_joylist[i].joy);
return;
}
@ -1089,8 +1093,8 @@ EV_HandleEvents(SDL_Joystick * joystick)
int code;
#ifndef NO_LOGICAL_JOYSTICKS
if (SDL_joylist[joystick->index].fname == NULL) {
SDL_joylist_head(i, joystick->index);
if (SDL_joylist[joystick->instance_id].fname == NULL) {
SDL_joylist_head(i, joystick->instance_id);
return EV_HandleEvents(SDL_joylist[i].joy);
}
#endif
@ -1198,15 +1202,15 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{
#ifndef NO_LOGICAL_JOYSTICKS
register int i;
if (SDL_joylist[joystick->index].fname == NULL) {
SDL_joylist_head(i, joystick->index);
if (SDL_joylist[joystick->instance_id].fname == NULL) {
SDL_joylist_head(i, joystick->instance_id);
SDL_JoystickClose(SDL_joylist[i].joy);
}
#endif
if (joystick->hwdata) {
#ifndef NO_LOGICAL_JOYSTICKS
if (SDL_joylist[joystick->index].fname != NULL)
if (SDL_joylist[joystick->instance_id].fname != NULL)
#endif
close(joystick->hwdata->fd);
if (joystick->hwdata->hats) {
@ -1218,6 +1222,7 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
SDL_free(joystick->hwdata);
joystick->hwdata = NULL;
}
joystick->closed = 1;
}
/* Function to perform any system-specific joystick related cleanup */
@ -1234,5 +1239,50 @@ SDL_SYS_JoystickQuit(void)
}
}
/* Function to perform the mapping from device index to the instance id for this index */
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int index)
{
return index;
}
/* Function to determine is this joystick is attached to the system right now */
int SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{
return joystick->closed;
}
int SDL_SYS_NumJoysticks()
{
return SDL_SYS_numjoysticks;
}
int SDL_SYS_JoystickNeedsPolling()
{
return 0;
}
void SDL_SYS_JoystickDetect()
{
}
JoystickGUID SDL_SYS_PrivateJoystickGetDeviceID( int device_index )
{
static JoystickGUID guid;
// the GUID is just the first 16 chars of the name for now
const char *name = SDL_SYS_JoystickNameForIndex( device_index );
SDL_memcpy( &guid, name, sizeof(guid) );
return guid;
}
JoystickGUID SDL_SYS_PrivateJoystickGetGUID(SDL_Joystick * joystick)
{
static JoystickGUID guid;
// the GUID is just the first 16 chars of the name for now
const char *name = SDL_SYS_JoystickNameForIndex( joystick->name );
SDL_memcpy( &guid, name, sizeof(guid) );
return guid;
}
#endif /* SDL_JOYSTICK_LINUX */
/* vi: set ts=4 sw=4 expandtab: */