Cleanup some controller code (#378)

* controller hotplugging

* more

* more
This commit is contained in:
Logan McNaughton 2025-04-13 21:07:54 +02:00 committed by GitHub
parent 33f74e5062
commit 27bb66df4c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 30 deletions

View File

@ -21,8 +21,7 @@ pub struct Audio {
}
pub struct Input {
pub num_joysticks: i32,
pub joysticks: *mut sdl3_sys::joystick::SDL_JoystickID,
pub joysticks: Vec<sdl3_sys::joystick::SDL_JoystickID>,
pub keyboard_state: *const bool,
pub controllers: [input::Controllers; 4],
}
@ -54,7 +53,6 @@ impl Drop for Ui {
fn drop(&mut self) {
if self.with_sdl {
unsafe {
sdl3_sys::stdinc::SDL_free(self.input.joysticks as *mut std::ffi::c_void);
sdl3_sys::init::SDL_Quit();
}
}
@ -98,7 +96,7 @@ pub fn get_dirs() -> Dirs {
}
impl Ui {
fn construct_ui(num_joysticks: i32, joysticks: *mut u32, with_sdl: bool) -> Ui {
fn construct_ui(joysticks: Vec<u32>, with_sdl: bool) -> Ui {
let dirs = get_dirs();
Ui {
@ -126,7 +124,6 @@ impl Ui {
},
],
keyboard_state: std::ptr::null_mut(),
num_joysticks,
joysticks,
},
storage: Storage {
@ -201,7 +198,7 @@ impl Ui {
}
pub fn default() -> Ui {
Self::construct_ui(0, std::ptr::null_mut(), false)
Self::construct_ui(vec![], false)
}
pub fn new() -> Ui {
@ -211,6 +208,11 @@ impl Ui {
if joysticks.is_null() {
panic!("Could not get joystick list");
}
Self::construct_ui(num_joysticks, joysticks, true)
let mut joystick_vec = vec![];
for i in 0..num_joysticks {
joystick_vec.push(unsafe { *joysticks.add(i as usize) });
}
unsafe { sdl3_sys::stdinc::SDL_free(joysticks as *mut std::ffi::c_void) }
Self::construct_ui(joystick_vec, true)
}
}

View File

@ -61,11 +61,9 @@ fn get_input_profiles(config: &ui::config::Config) -> Vec<String> {
pub fn get_controller_names(game_ui: &ui::Ui) -> Vec<String> {
let mut controllers: Vec<String> = vec![];
for offset in 0..game_ui.input.num_joysticks as isize {
for joystick in game_ui.input.joysticks.iter() {
let name = unsafe {
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickNameForID(
*(game_ui.input.joysticks.offset(offset)),
))
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickNameForID(*joystick))
};
controllers.push(name.to_string_lossy().to_string());
}
@ -76,13 +74,11 @@ pub fn get_controller_names(game_ui: &ui::Ui) -> Vec<String> {
pub fn get_controller_paths(game_ui: &ui::Ui) -> Vec<String> {
let mut controller_paths: Vec<String> = vec![];
for offset in 0..game_ui.input.num_joysticks as isize {
for joystick in game_ui.input.joysticks.iter() {
let path = unsafe {
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickPathForID(
*(game_ui.input.joysticks.offset(offset)),
))
.to_string_lossy()
.to_string()
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickPathForID(*joystick))
.to_string_lossy()
.to_string()
};
controller_paths.push(path);
}

View File

@ -393,10 +393,10 @@ pub fn get(ui: &ui::Ui, channel: usize) -> InputData {
}
pub fn assign_controller(ui: &mut ui::Ui, controller: i32, port: usize) {
if controller < ui.input.num_joysticks {
if controller < ui.input.joysticks.len() as i32 {
let path = unsafe {
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickPathForID(
*(ui.input.joysticks.offset(controller as isize)),
ui.input.joysticks[controller as usize],
))
.to_string_lossy()
.to_string()
@ -448,16 +448,14 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) {
let mut open_joysticks: Vec<*mut sdl3_sys::joystick::SDL_Joystick> = Vec::new();
let mut open_controllers: Vec<*mut sdl3_sys::gamepad::SDL_Gamepad> = Vec::new();
for offset in 0..ui.input.num_joysticks as isize {
for joystick in ui.input.joysticks.iter() {
if !dinput {
let controller =
unsafe { sdl3_sys::gamepad::SDL_OpenGamepad(*ui.input.joysticks.offset(offset)) };
let controller = unsafe { sdl3_sys::gamepad::SDL_OpenGamepad(*joystick) };
if !controller.is_null() {
open_controllers.push(controller);
}
} else {
let joystick =
unsafe { sdl3_sys::joystick::SDL_OpenJoystick(*ui.input.joysticks.offset(offset)) };
let joystick = unsafe { sdl3_sys::joystick::SDL_OpenJoystick(*joystick) };
if !joystick.is_null() {
open_joysticks.push(joystick);
}
@ -861,24 +859,25 @@ pub fn init(ui: &mut ui::Ui) {
panic!("Could not get keyboard state");
}
let mut taken = [false; 4];
for i in 0..4 {
let controller_assignment = &ui.config.input.controller_assignment[i];
if controller_assignment.is_some() && ui.config.input.controller_enabled[i] {
let mut joystick_id = 0;
let assigned_path = controller_assignment.as_ref().unwrap();
for offset in 0..ui.input.num_joysticks as isize {
for joystick in ui.input.joysticks.iter() {
let path = unsafe {
std::ffi::CStr::from_ptr(sdl3_sys::joystick::SDL_GetJoystickPathForID(
*(ui.input.joysticks.offset(offset)),
*joystick,
))
.to_string_lossy()
.to_string()
};
if path == *assigned_path && !taken[offset as usize] {
joystick_id = unsafe { *(ui.input.joysticks.offset(offset)) };
taken[offset as usize] = true;
if path == *assigned_path
&& unsafe { sdl3_sys::joystick::SDL_GetJoystickFromID(*joystick) }.is_null()
&& unsafe { sdl3_sys::gamepad::SDL_GetGamepadFromID(*joystick) }.is_null()
{
joystick_id = *joystick;
break;
}
}