mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-19 01:38:12 +00:00
Automatically assign player indexes to game controllers, and allow changing the player index for game controllers and joysticks.
Added the functions SDL_JoystickFromPlayerIndex(), SDL_JoystickSetPlayerIndex(), SDL_GameControllerFromPlayerIndex(), and SDL_GameControllerSetPlayerIndex()
This commit is contained in:
@@ -83,6 +83,8 @@ static SDL_Joystick *SDL_joysticks = NULL;
|
||||
static SDL_bool SDL_updating_joystick = SDL_FALSE;
|
||||
static SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
|
||||
static SDL_atomic_t SDL_next_joystick_instance_id;
|
||||
static int SDL_joystick_player_count = 0;
|
||||
static SDL_JoystickID *SDL_joystick_players = NULL;
|
||||
|
||||
void
|
||||
SDL_LockJoysticks(void)
|
||||
@@ -100,6 +102,81 @@ SDL_UnlockJoysticks(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_FindFreePlayerIndex()
|
||||
{
|
||||
int player_index;
|
||||
|
||||
for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) {
|
||||
if (SDL_joystick_players[player_index] == -1) {
|
||||
return player_index;
|
||||
}
|
||||
}
|
||||
return player_index;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_GetPlayerIndexForJoystickID(SDL_JoystickID instance_id)
|
||||
{
|
||||
int player_index;
|
||||
|
||||
for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) {
|
||||
if (instance_id == SDL_joystick_players[player_index]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player_index == SDL_joystick_player_count) {
|
||||
player_index = -1;
|
||||
}
|
||||
return player_index;
|
||||
}
|
||||
|
||||
static SDL_JoystickID
|
||||
SDL_GetJoystickIDForPlayerIndex(int player_index)
|
||||
{
|
||||
if (player_index < 0 || player_index >= SDL_joystick_player_count) {
|
||||
return -1;
|
||||
}
|
||||
return SDL_joystick_players[player_index];
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id)
|
||||
{
|
||||
SDL_JoystickID existing_instance = SDL_GetJoystickIDForPlayerIndex(player_index);
|
||||
SDL_JoystickDriver *driver;
|
||||
int device_index;
|
||||
|
||||
if (player_index < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (player_index >= SDL_joystick_player_count) {
|
||||
SDL_JoystickID *new_players = (SDL_JoystickID *)SDL_realloc(SDL_joystick_players, (player_index + 1)*sizeof(*SDL_joystick_players));
|
||||
if (!new_players) {
|
||||
SDL_OutOfMemory();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_joystick_players = new_players;
|
||||
while (SDL_joystick_player_count <= player_index) {
|
||||
SDL_joystick_players[SDL_joystick_player_count++] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_joystick_players[player_index] = instance_id;
|
||||
|
||||
/* Update the driver with the new index */
|
||||
device_index = SDL_JoystickGetDeviceIndexFromInstanceID(instance_id);
|
||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
||||
driver->SetDevicePlayerIndex(device_index, player_index);
|
||||
}
|
||||
|
||||
/* Move any existing joystick to another slot */
|
||||
if (existing_instance >= 0) {
|
||||
SDL_SetJoystickIDForPlayerIndex(SDL_FindFreePlayerIndex(), existing_instance);
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
@@ -228,16 +305,16 @@ SDL_JoystickNameForIndex(int device_index)
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the player index of a joystick, or -1 if it's not available
|
||||
*/
|
||||
int
|
||||
SDL_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
SDL_JoystickDriver *driver;
|
||||
int player_index = -1;
|
||||
int player_index;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
||||
player_index = driver->GetDevicePlayerIndex(device_index);
|
||||
}
|
||||
player_index = SDL_GetPlayerIndexForJoystickID(SDL_JoystickGetDeviceInstanceID(device_index));
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return player_index;
|
||||
@@ -323,7 +400,6 @@ SDL_JoystickOpen(int device_index)
|
||||
joystick->driver = driver;
|
||||
joystick->instance_id = instance_id;
|
||||
joystick->attached = SDL_TRUE;
|
||||
joystick->player_index = -1;
|
||||
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
|
||||
|
||||
if (driver->Open(joystick, device_index) < 0) {
|
||||
@@ -391,16 +467,16 @@ SDL_JoystickOpen(int device_index)
|
||||
/*
|
||||
* Checks to make sure the joystick is valid.
|
||||
*/
|
||||
int
|
||||
SDL_bool
|
||||
SDL_PrivateJoystickValid(SDL_Joystick * joystick)
|
||||
{
|
||||
int valid;
|
||||
SDL_bool valid;
|
||||
|
||||
if (joystick == NULL) {
|
||||
SDL_SetError("Joystick hasn't been opened yet");
|
||||
valid = 0;
|
||||
valid = SDL_FALSE;
|
||||
} else {
|
||||
valid = 1;
|
||||
valid = SDL_TRUE;
|
||||
}
|
||||
|
||||
return valid;
|
||||
@@ -589,16 +665,36 @@ SDL_JoystickInstanceID(SDL_Joystick * joystick)
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the SDL_Joystick that owns this instance id
|
||||
* Return the SDL_Joystick associated with an instance id.
|
||||
*/
|
||||
SDL_Joystick *
|
||||
SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
|
||||
SDL_JoystickFromInstanceID(SDL_JoystickID instance_id)
|
||||
{
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
||||
if (joystick->instance_id == joyid) {
|
||||
if (joystick->instance_id == instance_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
return joystick;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SDL_Joystick associated with a player index.
|
||||
*/
|
||||
SDL_Joystick *
|
||||
SDL_JoystickFromPlayerIndex(int player_index)
|
||||
{
|
||||
SDL_JoystickID instance_id;
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
instance_id = SDL_GetJoystickIDForPlayerIndex(player_index);
|
||||
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
||||
if (joystick->instance_id == instance_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -619,13 +715,38 @@ SDL_JoystickName(SDL_Joystick * joystick)
|
||||
return SDL_FixupJoystickName(joystick->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player index of an opened joystick, or -1 if it's not available
|
||||
*/
|
||||
int
|
||||
SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick)
|
||||
{
|
||||
int player_index;
|
||||
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return -1;
|
||||
}
|
||||
return joystick->player_index;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
player_index = SDL_GetPlayerIndexForJoystickID(joystick->instance_id);
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return player_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the player index of an opened joystick
|
||||
*/
|
||||
void
|
||||
SDL_JoystickSetPlayerIndex(SDL_Joystick * joystick, int player_index)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockJoysticks();
|
||||
SDL_SetJoystickIDForPlayerIndex(player_index, joystick->instance_id);
|
||||
SDL_UnlockJoysticks();
|
||||
}
|
||||
|
||||
int
|
||||
@@ -718,6 +839,11 @@ SDL_JoystickQuit(void)
|
||||
SDL_joystick_drivers[i]->Quit();
|
||||
}
|
||||
|
||||
if (SDL_joystick_players) {
|
||||
SDL_free(SDL_joystick_players);
|
||||
SDL_joystick_players = NULL;
|
||||
SDL_joystick_player_count = 0;
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
@@ -755,20 +881,36 @@ SDL_PrivateJoystickShouldIgnoreEvent()
|
||||
|
||||
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
|
||||
{
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
int device_index;
|
||||
|
||||
device_index = SDL_JoystickGetDeviceIndexFromInstanceID(device_instance);
|
||||
SDL_JoystickDriver *driver;
|
||||
int driver_device_index;
|
||||
int player_index = -1;
|
||||
int device_index = SDL_JoystickGetDeviceIndexFromInstanceID(device_instance);
|
||||
if (device_index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
SDL_LockJoysticks();
|
||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &driver_device_index)) {
|
||||
player_index = driver->GetDevicePlayerIndex(driver_device_index);
|
||||
}
|
||||
if (player_index < 0 && SDL_IsGameController(device_index)) {
|
||||
player_index = SDL_FindFreePlayerIndex();
|
||||
}
|
||||
if (player_index >= 0) {
|
||||
SDL_SetJoystickIDForPlayerIndex(player_index, device_instance);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = device_index;
|
||||
SDL_PushEvent(&event);
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = device_index;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
}
|
||||
|
Reference in New Issue
Block a user