From 3be9030dd4be5d016a9d917c33e7807ba13a373e Mon Sep 17 00:00:00 2001 From: PARTY MAN X <4970541+PARTYMANX@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:39:50 -0600 Subject: [PATCH 1/3] Add player index functions for game controller and joystick --- src/sdl2/controller.rs | 50 ++++++++++++++++++++++++++++++++++ src/sdl2/joystick.rs | 62 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/src/sdl2/controller.rs b/src/sdl2/controller.rs index 33c60ca94f..022619fd05 100644 --- a/src/sdl2/controller.rs +++ b/src/sdl2/controller.rs @@ -112,6 +112,30 @@ impl GameControllerSubsystem { } } + /// Return the instance ID of the controller with player index `player_index`. + #[doc(alias = "SDL_GameControllerFromPlayerIndex")] + pub fn instance_id_for_player_index(&self, player_index: u32) -> Result, IntegerOrSdlError> { + let player_index = validate_int(player_index, "player_index")?; + + let controller = unsafe { sys::SDL_GameControllerFromPlayerIndex(player_index) }; + + if controller.is_null() { + Ok(None) + } else { + let result = unsafe { + let joystick = sys::SDL_GameControllerGetJoystick(controller); + sys::SDL_JoystickInstanceID(joystick) + }; + + if result < 0 { + // Should only fail if the joystick is NULL. + panic!("{}", get_error()) + } else { + Ok(Some(result as u32)) + } + } + } + /// If state is `true` controller events are processed, otherwise /// they're ignored. #[doc(alias = "SDL_GameControllerEventState")] @@ -545,6 +569,32 @@ impl GameController { } } + /// Set player index for game controller or `None` to clear the player index and turn off player LEDs. + #[doc(alias = "SDL_GameControllerSetPlayerIndex")] + pub fn set_player_index(&mut self, player_index: Option) -> Result<(), IntegerOrSdlError> { + let player_index = match player_index { + None => -1, + Some(player_index) => validate_int(player_index, "player_index")?, + }; + + unsafe { sys::SDL_GameControllerSetPlayerIndex(self.raw, player_index) }; + + Ok(()) + } + + /// Get player index for game controller or `None` if it's not available. + #[doc(alias = "SDL_GameControllerGetPlayerIndex")] + pub fn get_player_index(&self) -> Option { + let player_index = unsafe { sys::SDL_GameControllerGetPlayerIndex(self.raw) }; + + // if index is -1, controller has no player + if player_index == -1 { + None + } else { + Some(player_index as u32) + } + } + /// Query whether a game controller has an LED. #[doc(alias = "SDL_GameControllerHasLED")] pub fn has_led(&self) -> bool { diff --git a/src/sdl2/joystick.rs b/src/sdl2/joystick.rs index 82e20b449a..6c50189200 100644 --- a/src/sdl2/joystick.rs +++ b/src/sdl2/joystick.rs @@ -60,6 +60,42 @@ impl JoystickSubsystem { } } + /// Return the player index of the joystick with index `device_index`. + #[doc(alias = "SDL_JoystickGetDevicePlayerIndex")] + pub fn player_index_for_device_id(&self, device_index: u32) -> Result, IntegerOrSdlError> { + let device_index = validate_int(device_index, "device_index")?; + + let player_index = unsafe { sys::SDL_JoystickGetDevicePlayerIndex(device_index) }; + + // if index is -1, joystick has no player + if player_index == -1 { + Ok(None) + } else { + Ok(Some(player_index as u32)) + } + } + + /// Return the instance ID of the joystick with player index `player_index`. + #[doc(alias = "SDL_JoystickFromPlayerIndex")] + pub fn instance_id_for_player_index(&self, player_index: u32) -> Result, IntegerOrSdlError> { + let player_index = validate_int(player_index, "player_index")?; + + let joystick = unsafe { sys::SDL_JoystickFromPlayerIndex(player_index) }; + + if joystick.is_null() { + Ok(None) + } else { + let result = unsafe { sys::SDL_JoystickInstanceID(joystick) }; + + if result < 0 { + // Should only fail if the joystick is NULL. + panic!("{}", get_error()) + } else { + Ok(Some(result as u32)) + } + } + } + /// Get the GUID for the joystick at index `joystick_index` #[doc(alias = "SDL_JoystickGetDeviceGUID")] pub fn device_guid(&self, joystick_index: u32) -> Result { @@ -482,6 +518,32 @@ impl Joystick { Ok(()) } } + + /// Set player index for joystick or `None` to clear the player index and turn off player LEDs. + #[doc(alias = "SDL_JoystickSetPlayerIndex")] + pub fn set_player_index(&mut self, player_index: Option) -> Result<(), IntegerOrSdlError> { + let player_index = match player_index { + None => -1, + Some(player_index) => validate_int(player_index, "player_index")?, + }; + + unsafe { sys::SDL_JoystickSetPlayerIndex(self.raw, player_index) }; + + Ok(()) + } + + /// Get player index for joystick or `None` if it's not available. + #[doc(alias = "SDL_JoystickGetPlayerIndex")] + pub fn get_player_index(&self) -> Option { + let player_index = unsafe { sys::SDL_JoystickGetPlayerIndex(self.raw) }; + + // if index is -1, joystick has no player + if player_index == -1 { + None + } else { + Some(player_index as u32) + } + } } impl Drop for Joystick { From 4e4a5d1390a1bbc4b1f947c7915606ade4187f11 Mon Sep 17 00:00:00 2001 From: PARTY MAN X <4970541+PARTYMANX@users.noreply.github.com> Date: Tue, 18 Feb 2025 19:15:01 -0600 Subject: [PATCH 2/3] handle other negative numbers returned from SDL_JoystickGetDevicePlayerIndex --- src/sdl2/joystick.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl2/joystick.rs b/src/sdl2/joystick.rs index 6c50189200..1c3185da41 100644 --- a/src/sdl2/joystick.rs +++ b/src/sdl2/joystick.rs @@ -67,8 +67,8 @@ impl JoystickSubsystem { let player_index = unsafe { sys::SDL_JoystickGetDevicePlayerIndex(device_index) }; - // if index is -1, joystick has no player - if player_index == -1 { + // if index is -1, joystick has no player (treat other negative numbers as no player, just in case) + if player_index < 0 { Ok(None) } else { Ok(Some(player_index as u32)) From bbd1f6a7a3697bb0cadba786d12583748e911689 Mon Sep 17 00:00:00 2001 From: PARTY MAN X <4970541+PARTYMANX@users.noreply.github.com> Date: Tue, 18 Feb 2025 19:20:51 -0600 Subject: [PATCH 3/3] fix other negative numbers for SDL_GameControllerGetPlayerIndex and SDL_JoystickGetPlayerIndex --- src/sdl2/controller.rs | 4 ++-- src/sdl2/joystick.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sdl2/controller.rs b/src/sdl2/controller.rs index 022619fd05..6537b8fc73 100644 --- a/src/sdl2/controller.rs +++ b/src/sdl2/controller.rs @@ -587,8 +587,8 @@ impl GameController { pub fn get_player_index(&self) -> Option { let player_index = unsafe { sys::SDL_GameControllerGetPlayerIndex(self.raw) }; - // if index is -1, controller has no player - if player_index == -1 { + // if index is -1 (or less than 0), controller has no player + if player_index < 0 { None } else { Some(player_index as u32) diff --git a/src/sdl2/joystick.rs b/src/sdl2/joystick.rs index 1c3185da41..0d0be8337b 100644 --- a/src/sdl2/joystick.rs +++ b/src/sdl2/joystick.rs @@ -67,7 +67,7 @@ impl JoystickSubsystem { let player_index = unsafe { sys::SDL_JoystickGetDevicePlayerIndex(device_index) }; - // if index is -1, joystick has no player (treat other negative numbers as no player, just in case) + // if index is -1 (or less than 0), joystick has no player if player_index < 0 { Ok(None) } else { @@ -537,8 +537,8 @@ impl Joystick { pub fn get_player_index(&self) -> Option { let player_index = unsafe { sys::SDL_JoystickGetPlayerIndex(self.raw) }; - // if index is -1, joystick has no player - if player_index == -1 { + // if index is -1 (or less than 0), joystick has no player + if player_index < 0 { None } else { Some(player_index as u32)