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:
Sam Lantinga 2019-12-20 20:12:03 -08:00
parent f050309ee9
commit 46e1377d49
26 changed files with 405 additions and 67 deletions

View file

@ -214,6 +214,11 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_
*/
extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid);
/**
* Return the SDL_GameController associated with a player index.
*/
extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(int player_index);
/**
* Return the name for this currently opened controller
*/
@ -231,6 +236,11 @@ extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_Gam
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
/**
* Set the player index of an opened game controller
*/
extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index);
/**
* Get the USB vendor ID of an opened controller, if available.
* If the vendor ID isn't available this function returns 0.

View file

@ -192,7 +192,12 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index);
/**
* Return the SDL_Joystick associated with an instance id.
*/
extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID joyid);
extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID instance_id);
/**
* Return the SDL_Joystick associated with a player index.
*/
extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_index);
/**
* Return the name for this currently opened joystick.
@ -207,6 +212,11 @@ extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
/**
* Set the player index of an opened joystick
*/
extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick * joystick, int player_index);
/**
* Return the GUID for this opened joystick
*/

View file

@ -733,3 +733,7 @@
#define SDL_wcsncmp SDL_wcsncmp_REAL
#define SDL_GameControllerTypeForIndex SDL_GameControllerTypeForIndex_REAL
#define SDL_GameControllerGetType SDL_GameControllerGetType_REAL
#define SDL_GameControllerFromPlayerIndex SDL_GameControllerFromPlayerIndex_REAL
#define SDL_GameControllerSetPlayerIndex SDL_GameControllerSetPlayerIndex_REAL
#define SDL_JoystickFromPlayerIndex SDL_JoystickFromPlayerIndex_REAL
#define SDL_JoystickSetPlayerIndex SDL_JoystickSetPlayerIndex_REAL

View file

@ -789,3 +789,7 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),r
SDL_DYNAPI_PROC(int,SDL_wcsncmp,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerTypeForIndex,(int a),(a),return)
SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerGetType,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromPlayerIndex,(int a),(a),return)
SDL_DYNAPI_PROC(void,SDL_GameControllerSetPlayerIndex,(SDL_GameController *a, int b),(a,b),)
SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromPlayerIndex,(int a),(a),return)
SDL_DYNAPI_PROC(void,SDL_JoystickSetPlayerIndex,(SDL_Joystick *a, int b),(a,b),)

View file

@ -1765,6 +1765,15 @@ SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
}
/**
* Set the player index of an opened game controller
*/
void
SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index)
{
SDL_JoystickSetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller), player_index);
}
Uint16
SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
{
@ -1809,7 +1818,7 @@ SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
/*
* Find the SDL_GameController that owns this instance id
* Return the SDL_GameController associated with an instance id.
*/
SDL_GameController *
SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
@ -1830,6 +1839,19 @@ SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
}
/**
* Return the SDL_GameController associated with a player index.
*/
SDL_GameController *SDL_GameControllerFromPlayerIndex(int player_index)
{
SDL_Joystick *joystick = SDL_JoystickFromPlayerIndex(player_index);
if (joystick) {
return SDL_GameControllerFromInstanceID(joystick->instance_id);
}
return NULL;
}
/*
* Get the SDL joystick layer binding for this controller axis mapping
*/

View file

@ -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 */
}

View file

@ -101,7 +101,7 @@ extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
SDL_JoystickPowerLevel ePowerLevel);
/* Internal sanity checking functions */
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
extern SDL_bool SDL_PrivateJoystickValid(SDL_Joystick * joystick);
#endif /* SDL_joystick_c_h_ */

View file

@ -43,7 +43,6 @@ struct _SDL_Joystick
{
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Joystick name - system dependent */
int player_index; /* Joystick player index, or -1 if unavailable */
SDL_JoystickGUID guid; /* Joystick guid */
int naxes; /* Number of axis controls on the joystick */
@ -110,6 +109,9 @@ typedef struct _SDL_JoystickDriver
/* Function to get the player index of a joystick */
int (*GetDevicePlayerIndex)(int device_index);
/* Function to get the player index of a joystick */
void (*SetDevicePlayerIndex)(int device_index, int player_index);
/* Function to return the stable GUID for a plugged in device */
SDL_JoystickGUID (*GetDeviceGUID)(int device_index);

View file

@ -587,6 +587,11 @@ ANDROID_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
ANDROID_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickGUID
ANDROID_JoystickGetDeviceGUID(int device_index)
{
@ -696,6 +701,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickDetect,
ANDROID_JoystickGetDeviceName,
ANDROID_JoystickGetDevicePlayerIndex,
ANDROID_JoystickSetDevicePlayerIndex,
ANDROID_JoystickGetDeviceGUID,
ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen,

View file

@ -276,6 +276,11 @@ BSD_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
/* Function to perform the mapping from device index to the instance id for this index */
static SDL_JoystickID
BSD_JoystickGetDeviceInstanceID(int device_index)
@ -764,6 +769,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickDetect,
BSD_JoystickGetDeviceName,
BSD_JoystickGetDevicePlayerIndex,
BSD_JoystickSetDevicePlayerIndex,
BSD_JoystickGetDeviceGUID,
BSD_JoystickGetDeviceInstanceID,
BSD_JoystickOpen,

View file

@ -734,6 +734,11 @@ DARWIN_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
DARWIN_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickGUID
DARWIN_JoystickGetDeviceGUID( int device_index )
{
@ -1033,6 +1038,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickDetect,
DARWIN_JoystickGetDeviceName,
DARWIN_JoystickGetDevicePlayerIndex,
DARWIN_JoystickSetDevicePlayerIndex,
DARWIN_JoystickGetDeviceGUID,
DARWIN_JoystickGetDeviceInstanceID,
DARWIN_JoystickOpen,

View file

@ -58,6 +58,11 @@ DUMMY_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
DUMMY_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickGUID
DUMMY_JoystickGetDeviceGUID(int device_index)
{
@ -106,6 +111,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickDetect,
DUMMY_JoystickGetDeviceName,
DUMMY_JoystickGetDevicePlayerIndex,
DUMMY_JoystickSetDevicePlayerIndex,
DUMMY_JoystickGetDeviceGUID,
DUMMY_JoystickGetDeviceInstanceID,
DUMMY_JoystickOpen,

View file

@ -288,6 +288,11 @@ EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
EMSCRIPTEN_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickID
EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index)
{
@ -406,6 +411,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
EMSCRIPTEN_JoystickDetect,
EMSCRIPTEN_JoystickGetDeviceName,
EMSCRIPTEN_JoystickGetDevicePlayerIndex,
EMSCRIPTEN_JoystickSetDevicePlayerIndex,
EMSCRIPTEN_JoystickGetDeviceGUID,
EMSCRIPTEN_JoystickGetDeviceInstanceID,
EMSCRIPTEN_JoystickOpen,

View file

@ -104,6 +104,10 @@ extern "C"
return -1;
}
static void HAIKU_JoystickGetDevicePlayerIndex(int device_index, int player_index)
{
}
/* Function to perform the mapping from device index to the instance id for this index */
static SDL_JoystickID HAIKU_JoystickGetDeviceInstanceID(int device_index)
{
@ -262,6 +266,7 @@ extern "C"
HAIKU_JoystickDetect,
HAIKU_JoystickGetDeviceName,
HAIKU_JoystickGetDevicePlayerIndex,
HAIKU_JoystickSetDevicePlayerIndex,
HAIKU_JoystickGetDeviceGUID,
HAIKU_JoystickGetDeviceInstanceID,
HAIKU_JoystickOpen,

View file

@ -140,6 +140,25 @@ error:
return SDL_FALSE;
}
static int
HIDAPI_DriverGameCube_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
Uint8 i;
for (i = 0; i < 4; ++i) {
if (instance_id == ctx->joysticks[i]) {
return i;
}
}
return -1;
}
static void
HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
static SDL_bool
HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
{
@ -253,7 +272,6 @@ HIDAPI_DriverGameCube_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
joystick->nbuttons = 12;
joystick->naxes = 6;
joystick->epowerlevel = ctx->wireless[i] ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED;
joystick->player_index = i;
return SDL_TRUE;
}
}
@ -331,6 +349,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_IsSupportedDevice,
HIDAPI_DriverGameCube_GetDeviceName,
HIDAPI_DriverGameCube_InitDevice,
HIDAPI_DriverGameCube_GetDevicePlayerIndex,
HIDAPI_DriverGameCube_SetDevicePlayerIndex,
HIDAPI_DriverGameCube_UpdateDevice,
HIDAPI_DriverGameCube_OpenJoystick,
HIDAPI_DriverGameCube_RumbleJoystick,

View file

@ -199,6 +199,17 @@ HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
return HIDAPI_JoystickConnected(device, NULL);
}
static int
HIDAPI_DriverPS4_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
static SDL_bool
@ -499,6 +510,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
HIDAPI_DriverPS4_IsSupportedDevice,
HIDAPI_DriverPS4_GetDeviceName,
HIDAPI_DriverPS4_InitDevice,
HIDAPI_DriverPS4_GetDevicePlayerIndex,
HIDAPI_DriverPS4_SetDevicePlayerIndex,
HIDAPI_DriverPS4_UpdateDevice,
HIDAPI_DriverPS4_OpenJoystick,
HIDAPI_DriverPS4_RumbleJoystick,

View file

@ -628,6 +628,17 @@ HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
return HIDAPI_JoystickConnected(device, NULL);
}
static int
HIDAPI_DriverSwitch_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverSwitch_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
static SDL_bool
HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
@ -1109,6 +1120,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
HIDAPI_DriverSwitch_IsSupportedDevice,
HIDAPI_DriverSwitch_GetDeviceName,
HIDAPI_DriverSwitch_InitDevice,
HIDAPI_DriverSwitch_GetDevicePlayerIndex,
HIDAPI_DriverSwitch_SetDevicePlayerIndex,
HIDAPI_DriverSwitch_UpdateDevice,
HIDAPI_DriverSwitch_OpenJoystick,
HIDAPI_DriverSwitch_RumbleJoystick,

View file

@ -305,10 +305,25 @@ HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device)
return HIDAPI_JoystickConnected(device, NULL);
}
static int
HIDAPI_DriverXbox360_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverXbox360_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
if (device->dev) {
SetSlotLED(device->dev, (player_index % 4));
}
}
static SDL_bool
HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
SDL_DriverXbox360_Context *ctx;
int player_index;
ctx = (SDL_DriverXbox360_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
@ -336,7 +351,10 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
#endif
/* Set the controller LED */
SetSlotLED(device->dev, (joystick->instance_id % 4));
player_index = SDL_JoystickGetPlayerIndex(joystick);
if (player_index >= 0) {
SetSlotLED(device->dev, (player_index % 4));
}
/* Initialize the joystick capabilities */
joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
@ -837,6 +855,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
HIDAPI_DriverXbox360_IsSupportedDevice,
HIDAPI_DriverXbox360_GetDeviceName,
HIDAPI_DriverXbox360_InitDevice,
HIDAPI_DriverXbox360_GetDevicePlayerIndex,
HIDAPI_DriverXbox360_SetDevicePlayerIndex,
HIDAPI_DriverXbox360_UpdateDevice,
HIDAPI_DriverXbox360_OpenJoystick,
HIDAPI_DriverXbox360_RumbleJoystick,

View file

@ -94,7 +94,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
SDL_DriverXbox360W_Context *ctx;
/* Requests controller presence information from the wireless dongle */
const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ctx = (SDL_DriverXbox360W_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
@ -118,6 +118,18 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
return SDL_TRUE;
}
static int
HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
SetSlotLED(device->dev, (player_index % 4));
}
static SDL_bool
HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
@ -300,6 +312,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
HIDAPI_DriverXbox360W_IsSupportedDevice,
HIDAPI_DriverXbox360W_GetDeviceName,
HIDAPI_DriverXbox360W_InitDevice,
HIDAPI_DriverXbox360W_GetDevicePlayerIndex,
HIDAPI_DriverXbox360W_SetDevicePlayerIndex,
HIDAPI_DriverXbox360W_UpdateDevice,
HIDAPI_DriverXbox360W_OpenJoystick,
HIDAPI_DriverXbox360W_RumbleJoystick,

View file

@ -260,6 +260,17 @@ HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device)
return HIDAPI_JoystickConnected(device, NULL);
}
static int
HIDAPI_DriverXboxOne_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverXboxOne_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
static SDL_bool
HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
@ -468,6 +479,8 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
HIDAPI_DriverXboxOne_IsSupportedDevice,
HIDAPI_DriverXboxOne_GetDeviceName,
HIDAPI_DriverXboxOne_InitDevice,
HIDAPI_DriverXboxOne_GetDevicePlayerIndex,
HIDAPI_DriverXboxOne_SetDevicePlayerIndex,
HIDAPI_DriverXboxOne_UpdateDevice,
HIDAPI_DriverXboxOne_OpenJoystick,
HIDAPI_DriverXboxOne_RumbleJoystick,

View file

@ -894,7 +894,32 @@ HIDAPI_JoystickGetDeviceName(int device_index)
static int
HIDAPI_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
SDL_HIDAPI_Device *device;
SDL_JoystickID instance_id;
int player_index = -1;
SDL_LockMutex(SDL_HIDAPI_mutex);
device = HIDAPI_GetDeviceByIndex(device_index, &instance_id);
if (device) {
player_index = device->driver->GetDevicePlayerIndex(device, instance_id);
}
SDL_UnlockMutex(SDL_HIDAPI_mutex);
return player_index;
}
static void
HIDAPI_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
SDL_HIDAPI_Device *device;
SDL_JoystickID instance_id;
SDL_LockMutex(SDL_HIDAPI_mutex);
device = HIDAPI_GetDeviceByIndex(device_index, &instance_id);
if (device) {
device->driver->SetDevicePlayerIndex(device, instance_id, player_index);
}
SDL_UnlockMutex(SDL_HIDAPI_mutex);
}
static SDL_JoystickGUID
@ -1023,6 +1048,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickDetect,
HIDAPI_JoystickGetDeviceName,
HIDAPI_JoystickGetDevicePlayerIndex,
HIDAPI_JoystickSetDevicePlayerIndex,
HIDAPI_JoystickGetDeviceGUID,
HIDAPI_JoystickGetDeviceInstanceID,
HIDAPI_JoystickOpen,

View file

@ -81,6 +81,8 @@ typedef struct _SDL_HIDAPI_DeviceDriver
SDL_bool (*IsSupportedDevice)(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name);
const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device);
int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id);
void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);
SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device);
SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);

View file

@ -469,6 +469,15 @@ IOS_JoystickGetDevicePlayerIndex(int device_index)
return device ? (int)device->controller.playerIndex : -1;
}
static void
IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
if (device) {
device->controller.playerIndex = player_index;
}
}
static SDL_JoystickGUID
IOS_JoystickGetDeviceGUID( int device_index )
{
@ -616,7 +625,6 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
GCController *controller = joystick->hwdata->controller;
Uint8 hatstate = SDL_HAT_CENTERED;
int i;
int updateplayerindex = 0;
int pause_button_index = 0;
if (controller.extendedGamepad) {
@ -670,17 +678,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
for (i = 0; i < SDL_arraysize(axes); i++) {
/* The triggers (axes 2 and 5) are resting at -32768 but SDL
* initializes its values to 0. We only want to make sure the
* player index is up to date if the user actually moves an axis. */
if ((i != 2 && i != 5) || axes[i] != -32768) {
updateplayerindex |= (joystick->axes[i].value != axes[i]);
}
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
}
for (i = 0; i < button_count; i++) {
updateplayerindex |= (joystick->buttons[i] != buttons[i]);
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
} else if (controller.gamepad) {
@ -701,7 +702,6 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
for (i = 0; i < button_count; i++) {
updateplayerindex |= (joystick->buttons[i] != buttons[i]);
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
}
@ -715,7 +715,6 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
};
for (i = 0; i < SDL_arraysize(axes); i++) {
updateplayerindex |= (joystick->axes[i].value != axes[i]);
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
}
@ -737,14 +736,12 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
#pragma clang diagnostic pop
for (i = 0; i < button_count; i++) {
updateplayerindex |= (joystick->buttons[i] != buttons[i]);
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
}
#endif /* TARGET_OS_TV */
if (joystick->nhats > 0) {
updateplayerindex |= (joystick->hats[0] != hatstate);
SDL_PrivateJoystickHat(joystick, 0, hatstate);
}
@ -752,31 +749,9 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_PRESSED);
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_RELEASED);
updateplayerindex = YES;
}
joystick->hwdata->num_pause_presses = 0;
}
if (updateplayerindex && controller.playerIndex == -1) {
BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};
/* Find the player index of all other connected controllers. */
for (GCController *c in [GCController controllers]) {
if (c != controller && c.playerIndex >= 0) {
usedPlayerIndexSlots[c.playerIndex] = YES;
}
}
/* Set this controller's player index to the first unused index.
* FIXME: This logic isn't great... but SDL doesn't expose this
* concept in its external API, so we don't have much to go on. */
for (i = 0; i < SDL_arraysize(usedPlayerIndexSlots); i++) {
if (!usedPlayerIndexSlots[i]) {
controller.playerIndex = i;
break;
}
}
}
}
#endif /* SDL_JOYSTICK_MFI */
}
@ -874,6 +849,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
IOS_JoystickDetect,
IOS_JoystickGetDeviceName,
IOS_JoystickGetDevicePlayerIndex,
IOS_JoystickSetDevicePlayerIndex,
IOS_JoystickGetDeviceGUID,
IOS_JoystickGetDeviceInstanceID,
IOS_JoystickOpen,

View file

@ -569,6 +569,11 @@ LINUX_JoystickGetDevicePlayerIndex(int device_index)
return -1;
}
static void
LINUX_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickGUID
LINUX_JoystickGetDeviceGUID( int device_index )
{
@ -1086,6 +1091,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickDetect,
LINUX_JoystickGetDeviceName,
LINUX_JoystickGetDevicePlayerIndex,
LINUX_JoystickSetDevicePlayerIndex,
LINUX_JoystickGetDeviceGUID,
LINUX_JoystickGetDeviceInstanceID,
LINUX_JoystickOpen,

View file

@ -419,6 +419,11 @@ WINDOWS_JoystickGetDevicePlayerIndex(int device_index)
return device->bXInputDevice ? (int)device->XInputUserId : -1;
}
static void
WINDOWS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
/* return the stable device guid for this device index */
static SDL_JoystickGUID
WINDOWS_JoystickGetDeviceGUID(int device_index)
@ -557,6 +562,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickDetect,
WINDOWS_JoystickGetDeviceName,
WINDOWS_JoystickGetDevicePlayerIndex,
WINDOWS_JoystickSetDevicePlayerIndex,
WINDOWS_JoystickGetDeviceGUID,
WINDOWS_JoystickGetDeviceInstanceID,
WINDOWS_JoystickOpen,

View file

@ -316,9 +316,9 @@ main(int argc, char *argv[])
name = SDL_JoystickNameForIndex(i);
description = "Joystick";
}
SDL_Log("%s %d: %s (guid %s, VID 0x%.4x, PID 0x%.4x)\n",
SDL_Log("%s %d: %s (guid %s, VID 0x%.4x, PID 0x%.4x, player index = %d)\n",
description, i, name ? name : "Unknown", guid,
SDL_JoystickGetDeviceVendor(i), SDL_JoystickGetDeviceProduct(i));
SDL_JoystickGetDeviceVendor(i), SDL_JoystickGetDeviceProduct(i), SDL_JoystickGetDevicePlayerIndex(i));
}
SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", nController, SDL_NumJoysticks());