diff --git a/src/device/cart.rs b/src/device/cart.rs index 55d1e32..2734638 100644 --- a/src/device/cart.rs +++ b/src/device/cart.rs @@ -126,8 +126,8 @@ pub fn process(device: &mut device::Device, channel: usize) { } fn format_eeprom(device: &mut device::Device) { - if device.ui.saves.eeprom.0.len() < EEPROM_MAX_SIZE { - device.ui.saves.eeprom.0.resize(EEPROM_MAX_SIZE, 0xFF) + if device.ui.saves.eeprom.data.len() < EEPROM_MAX_SIZE { + device.ui.saves.eeprom.data.resize(EEPROM_MAX_SIZE, 0xFF) } } @@ -137,7 +137,7 @@ fn eeprom_read_block(device: &mut device::Device, block: usize, offset: usize) { format_eeprom(device); device.pif.ram[offset..offset + EEPROM_BLOCK_SIZE] - .copy_from_slice(&device.ui.saves.eeprom.0[address..address + EEPROM_BLOCK_SIZE]); + .copy_from_slice(&device.ui.saves.eeprom.data[address..address + EEPROM_BLOCK_SIZE]); } fn eeprom_write_block(device: &mut device::Device, block: usize, offset: usize, status: usize) { @@ -145,12 +145,12 @@ fn eeprom_write_block(device: &mut device::Device, block: usize, offset: usize, format_eeprom(device); - device.ui.saves.eeprom.0[address..address + EEPROM_BLOCK_SIZE] + device.ui.saves.eeprom.data[address..address + EEPROM_BLOCK_SIZE] .copy_from_slice(&device.pif.ram[offset..offset + EEPROM_BLOCK_SIZE]); device.pif.ram[status] = 0x00; - device.ui.saves.eeprom.1 = true + device.ui.saves.eeprom.written = true } fn time2data(device: &mut device::Device, offset: usize) { diff --git a/src/device/cart/rom.rs b/src/device/cart/rom.rs index 888427b..f33fb1d 100644 --- a/src/device/cart/rom.rs +++ b/src/device/cart/rom.rs @@ -10,10 +10,10 @@ fn read_cart_word(device: &mut device::Device, address: usize) -> u32 { .ui .saves .romsave - .0 + .data .contains_key(&(address as u32 + i)) { - data[i as usize] = device.ui.saves.romsave.0[&(address as u32 + i)]; + data[i as usize] = device.ui.saves.romsave.data[&(address as u32 + i)]; } } u32::from_be_bytes(data) @@ -55,10 +55,10 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, mask: u3 .ui .saves .romsave - .0 + .data .insert((masked_address + i) as u32, *item); } - device.ui.saves.romsave.1 = true; + device.ui.saves.romsave.written = true; } device.cart.latch = value & mask; @@ -85,12 +85,12 @@ pub fn dma_read( for i in 0..length { if cart_addr + i < device.cart.rom.len() as u32 { - device.ui.saves.romsave.0.insert( + device.ui.saves.romsave.data.insert( cart_addr + i, device.rdram.mem[(dram_addr + i) as usize ^ device.byte_swap], ); - device.ui.saves.romsave.1 = true; + device.ui.saves.romsave.written = true; } } } @@ -110,8 +110,8 @@ pub fn dma_write( let mut i = dram_addr; let mut j = cart_addr; while i < dram_addr + length && j < device.cart.rom.len() as u32 { - if device.ui.saves.romsave.0.contains_key(&j) { - device.rdram.mem[i as usize ^ device.byte_swap] = device.ui.saves.romsave.0[&j]; + if device.ui.saves.romsave.data.contains_key(&j) { + device.rdram.mem[i as usize ^ device.byte_swap] = device.ui.saves.romsave.data[&j]; } else { device.rdram.mem[i as usize ^ device.byte_swap] = device.cart.rom[j as usize]; } diff --git a/src/device/cart/sc64.rs b/src/device/cart/sc64.rs index b035750..b4e5728 100644 --- a/src/device/cart/sc64.rs +++ b/src/device/cart/sc64.rs @@ -27,9 +27,9 @@ pub struct Sc64 { } fn format_sdcard(device: &mut device::Device) { - if device.ui.saves.sdcard.0.is_empty() { - device.ui.saves.sdcard.0.resize(SDCARD_SIZE, 0); - let buf = std::io::Cursor::new(&mut device.ui.saves.sdcard.0); + if device.ui.saves.sdcard.data.is_empty() { + device.ui.saves.sdcard.data.resize(SDCARD_SIZE, 0); + let buf = std::io::Cursor::new(&mut device.ui.saves.sdcard.data); fatfs::format_volume(buf, fatfs::FormatVolumeOptions::new()).unwrap(); } } @@ -117,9 +117,9 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u let mut i = 0; while i < length { - if offset + i < device.ui.saves.sdcard.0.len() { + if offset + i < device.ui.saves.sdcard.data.len() { let data = u32::from_be_bytes( - device.ui.saves.sdcard.0[(offset + i)..(offset + i + 4)] + device.ui.saves.sdcard.data[(offset + i)..(offset + i + 4)] .try_into() .unwrap(), ); @@ -148,7 +148,7 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u let mut i = 0; while i < length { - if offset + i < device.ui.saves.sdcard.0.len() { + if offset + i < device.ui.saves.sdcard.data.len() { let data = device::memory::data_read( device, address + i as u64, @@ -156,14 +156,14 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u false, ) .to_be_bytes(); - device.ui.saves.sdcard.0[(offset + i)..(offset + i + 4)] + device.ui.saves.sdcard.data[(offset + i)..(offset + i + 4)] .copy_from_slice(&data); } else { panic!("sd card write out of bounds") } i += 4; } - device.ui.saves.sdcard.1 = true; + device.ui.saves.sdcard.written = true; } 'U' => {} // USB_WRITE_STATUS, ignored 'M' => {} // USB_WRITE, ignored diff --git a/src/device/cart/sram.rs b/src/device/cart/sram.rs index 67d7146..8fae390 100644 --- a/src/device/cart/sram.rs +++ b/src/device/cart/sram.rs @@ -29,14 +29,14 @@ pub struct Flashram { } fn format_sram(device: &mut device::Device) { - if device.ui.saves.sram.0.len() < SRAM_SIZE { - device.ui.saves.sram.0.resize(SRAM_SIZE, 0xFF) + if device.ui.saves.sram.data.len() < SRAM_SIZE { + device.ui.saves.sram.data.resize(SRAM_SIZE, 0xFF) } } fn format_flash(device: &mut device::Device) { - if device.ui.saves.flash.0.len() < FLASHRAM_SIZE { - device.ui.saves.flash.0.resize(FLASHRAM_SIZE, 0xFF) + if device.ui.saves.flash.data.len() < FLASHRAM_SIZE { + device.ui.saves.flash.data.resize(FLASHRAM_SIZE, 0xFF) } } @@ -46,7 +46,7 @@ fn read_mem_sram(device: &mut device::Device, address: u64) -> u32 { format_sram(device); u32::from_be_bytes( - device.ui.saves.sram.0[masked_address..masked_address + 4] + device.ui.saves.sram.data[masked_address..masked_address + 4] .try_into() .unwrap(), ) @@ -88,14 +88,15 @@ fn write_mem_sram(device: &mut device::Device, address: u64, value: u32, mask: u format_sram(device); let mut data = u32::from_be_bytes( - device.ui.saves.sram.0[masked_address..masked_address + 4] + device.ui.saves.sram.data[masked_address..masked_address + 4] .try_into() .unwrap(), ); device::memory::masked_write_32(&mut data, value, mask); - device.ui.saves.sram.0[masked_address..masked_address + 4].copy_from_slice(&data.to_be_bytes()); + device.ui.saves.sram.data[masked_address..masked_address + 4] + .copy_from_slice(&data.to_be_bytes()); - device.ui.saves.sram.1 = true + device.ui.saves.sram.written = true } fn write_mem_flash(device: &mut device::Device, address: u64, value: u32, mask: u32) { @@ -138,12 +139,12 @@ fn dma_read_sram(device: &mut device::Device, mut cart_addr: u32, mut dram_addr: format_sram(device); while i < dram_addr + length && i < device.rdram.size { - device.ui.saves.sram.0[j as usize] = device.rdram.mem[i as usize ^ device.byte_swap]; + device.ui.saves.sram.data[j as usize] = device.rdram.mem[i as usize ^ device.byte_swap]; i += 1; j += 1; } - device.ui.saves.sram.1 = true + device.ui.saves.sram.written = true } fn dma_read_flash(device: &mut device::Device, cart_addr: u32, dram_addr: u32, length: u32) { @@ -188,7 +189,7 @@ fn dma_write_sram( format_sram(device); while i < dram_addr + length && i < device.rdram.size { - device.rdram.mem[i as usize ^ device.byte_swap] = device.ui.saves.sram.0[j as usize]; + device.rdram.mem[i as usize ^ device.byte_swap] = device.ui.saves.sram.data[j as usize]; i += 1; j += 1; } @@ -231,7 +232,7 @@ fn dma_write_flash( /* do actual DMA */ for i in 0..length { device.rdram.mem[(dram_addr + i) as usize ^ device.byte_swap] = - device.ui.saves.flash.0[(cart_addr + i) as usize]; + device.ui.saves.flash.data[(cart_addr + i) as usize]; } } else { /* other accesses are not implemented */ @@ -270,14 +271,14 @@ fn flashram_command(device: &mut device::Device, command: u32) { if device.cart.flashram.mode == FlashramMode::SectorErase { let offset: usize = (device.cart.flashram.erase_page & 0xff80) as usize * 128; for i in 0..128 * 128 { - device.ui.saves.flash.0[offset + i] = 0xFF; + device.ui.saves.flash.data[offset + i] = 0xFF; } - device.ui.saves.flash.1 = true + device.ui.saves.flash.written = true } else if device.cart.flashram.mode == FlashramMode::ChipErase { for i in 0..FLASHRAM_SIZE { - device.ui.saves.flash.0[i] = 0xFF; + device.ui.saves.flash.data[i] = 0xFF; } - device.ui.saves.flash.1 = true + device.ui.saves.flash.written = true } else { panic!("Unexpected flash erase command") } @@ -295,9 +296,9 @@ fn flashram_command(device: &mut device::Device, command: u32) { /* program selected page */ let offset: usize = (command & 0xffff) as usize * 128; for i in 0..128 { - device.ui.saves.flash.0[offset + i] = device.cart.flashram.page_buf[i]; + device.ui.saves.flash.data[offset + i] = device.cart.flashram.page_buf[i]; } - device.ui.saves.flash.1 = true; + device.ui.saves.flash.written = true; /* clear program busy flag, set program success flag, transition to status mode */ device.cart.flashram.status &= !0x01; diff --git a/src/device/controller.rs b/src/device/controller.rs index 59c15d8..e7f3b41 100644 --- a/src/device/controller.rs +++ b/src/device/controller.rs @@ -66,8 +66,8 @@ pub fn process(device: &mut device::Device, channel: usize) { netplay::get_input(device, channel) }; - device.pif.ram[offset..offset + 4].copy_from_slice(&input.0.to_ne_bytes()); - if input.1 { + device.pif.ram[offset..offset + 4].copy_from_slice(&input.data.to_ne_bytes()); + if input.pak_change_pressed { // pak change button pressed if device::events::get_event(device, device::events::EVENT_TYPE_PAK).is_none() { device.pif.channels[channel].change_pak = diff --git a/src/device/controller/mempak.rs b/src/device/controller/mempak.rs index 0361678..aca986e 100644 --- a/src/device/controller/mempak.rs +++ b/src/device/controller/mempak.rs @@ -4,8 +4,8 @@ pub const MEMPAK_SIZE: usize = 0x8000; const MPK_PAGE_SIZE: usize = 256; fn format_mempak(device: &mut device::Device) { - if device.ui.saves.mempak.0.len() < MEMPAK_SIZE * 4 { - device.ui.saves.mempak.0.resize(MEMPAK_SIZE * 4, 0); + if device.ui.saves.mempak.data.len() < MEMPAK_SIZE * 4 { + device.ui.saves.mempak.data.resize(MEMPAK_SIZE * 4, 0); let page_0: [u8; MPK_PAGE_SIZE] = [ /* Label area */ @@ -38,28 +38,28 @@ fn format_mempak(device: &mut device::Device) { let offset = i * MEMPAK_SIZE; /* Fill Page 0 with pre-initialized content */ - device.ui.saves.mempak.0[offset..offset + MPK_PAGE_SIZE].copy_from_slice(&page_0); + device.ui.saves.mempak.data[offset..offset + MPK_PAGE_SIZE].copy_from_slice(&page_0); /* Fill INODE page 1 and update it's checkum */ let start_page = 5; for i in MPK_PAGE_SIZE..2 * start_page { - device.ui.saves.mempak.0[offset + i] = 0; + device.ui.saves.mempak.data[offset + i] = 0; } for i in (MPK_PAGE_SIZE + 2 * start_page..2 * MPK_PAGE_SIZE).step_by(2) { - device.ui.saves.mempak.0[offset + i] = 0x00; - device.ui.saves.mempak.0[offset + i + 1] = 0x03; + device.ui.saves.mempak.data[offset + i] = 0x00; + device.ui.saves.mempak.data[offset + i + 1] = 0x03; } - device.ui.saves.mempak.0[offset + (MPK_PAGE_SIZE + 1)] = 0x71; + device.ui.saves.mempak.data[offset + (MPK_PAGE_SIZE + 1)] = 0x71; /* Page 2 is identical to page 1 */ let page1 = offset + MPK_PAGE_SIZE; let page2 = offset + 2 * MPK_PAGE_SIZE; - let page1data = device.ui.saves.mempak.0[page1..page1 + MPK_PAGE_SIZE].to_vec(); - device.ui.saves.mempak.0[page2..page2 + MPK_PAGE_SIZE].copy_from_slice(&page1data); + let page1data = device.ui.saves.mempak.data[page1..page1 + MPK_PAGE_SIZE].to_vec(); + device.ui.saves.mempak.data[page2..page2 + MPK_PAGE_SIZE].copy_from_slice(&page1data); /* Remaining pages DIR+DATA (3...) are initialized with 0x00 */ for i in 3 * MPK_PAGE_SIZE..MEMPAK_SIZE - 3 * MPK_PAGE_SIZE { - device.ui.saves.mempak.0[offset + i] = 0; + device.ui.saves.mempak.data[offset + i] = 0; } } } @@ -71,7 +71,7 @@ pub fn read(device: &mut device::Device, channel: usize, address: u16, data: usi let offset = (channel * MEMPAK_SIZE) + address as usize; device.pif.ram[data..data + size] - .copy_from_slice(&device.ui.saves.mempak.0[offset..offset + size]) + .copy_from_slice(&device.ui.saves.mempak.data[offset..offset + size]) } else { for i in 0..size { device.pif.ram[data + i] = 0; @@ -84,9 +84,9 @@ pub fn write(device: &mut device::Device, channel: usize, address: u16, data: us format_mempak(device); let offset = (channel * MEMPAK_SIZE) + address as usize; - device.ui.saves.mempak.0[offset..offset + size] + device.ui.saves.mempak.data[offset..offset + size] .copy_from_slice(&device.pif.ram[data..data + size]); - device.ui.saves.mempak.1 = true + device.ui.saves.mempak.written = true } } diff --git a/src/netplay.rs b/src/netplay.rs index c40514a..0102271 100644 --- a/src/netplay.rs +++ b/src/netplay.rs @@ -90,18 +90,18 @@ pub fn send_sync_check(device: &mut device::Device) { netplay.vi_counter = netplay.vi_counter.wrapping_add(1); } -pub fn send_input(netplay: &Netplay, input: (u32, bool)) { +pub fn send_input(netplay: &Netplay, input: ui::input::InputData) { let mut request: Vec = [UDP_SEND_KEY_INFO].to_vec(); request.push(netplay.player_number); request.extend_from_slice( &(netplay.player_data[netplay.player_number as usize].count).to_be_bytes(), ); - request.extend_from_slice(&(input.0).to_be_bytes()); - request.push(input.1 as u8); + request.extend_from_slice(&(input.data).to_be_bytes()); + request.push(input.pak_change_pressed as u8); netplay.udp_socket.send(&request).unwrap(); } -pub fn get_input(device: &mut device::Device, channel: usize) -> (u32, bool) { +pub fn get_input(device: &mut device::Device, channel: usize) -> ui::input::InputData { let netplay = device.netplay.as_mut().unwrap(); let mut input = None; @@ -132,10 +132,10 @@ pub fn get_input(device: &mut device::Device, channel: usize) -> (u32, bool) { && netplay.player_data[channel].input_events.len() as u8 > netplay.buffer_target; netplay.player_data[channel].count = netplay.player_data[channel].count.wrapping_add(1); - ( - input.as_ref().unwrap().input, - input.as_ref().unwrap().plugin != 0, - ) + ui::input::InputData { + data: input.as_ref().unwrap().input, + pak_change_pressed: input.as_ref().unwrap().plugin != 0, + } } fn request_input(netplay: &Netplay, channel: usize) { diff --git a/src/ui.rs b/src/ui.rs index 74c52f5..29ffad8 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -122,12 +122,30 @@ impl Ui { savestate_file_path: std::path::PathBuf::new(), }, saves: storage::Saves { - eeprom: (Vec::new(), false), - sram: (Vec::new(), false), - flash: (Vec::new(), false), - mempak: (Vec::new(), false), - sdcard: (Vec::new(), false), - romsave: (std::collections::HashMap::new(), false), + eeprom: storage::Save { + data: Vec::new(), + written: false, + }, + sram: storage::Save { + data: Vec::new(), + written: false, + }, + flash: storage::Save { + data: Vec::new(), + written: false, + }, + mempak: storage::Save { + data: Vec::new(), + written: false, + }, + sdcard: storage::Save { + data: Vec::new(), + written: false, + }, + romsave: storage::RomSave { + data: std::collections::HashMap::new(), + written: false, + }, }, event_audio: audio::EventAudio { mempak: include_bytes!("../data/mempak.wav").to_vec(), diff --git a/src/ui/config.rs b/src/ui/config.rs index ad8b4cc..0c1844d 100644 --- a/src/ui/config.rs +++ b/src/ui/config.rs @@ -1,13 +1,33 @@ use crate::ui; +#[derive(Copy, Clone, serde::Serialize, serde::Deserialize)] +pub struct InputKeyButton { + pub enabled: bool, + pub id: i32, +} + +#[derive(PartialEq, Copy, Clone, serde::Serialize, serde::Deserialize)] +pub struct InputControllerAxis { + pub enabled: bool, + pub id: i32, + pub axis: i16, +} + +#[derive(Copy, Clone, serde::Serialize, serde::Deserialize)] +pub struct InputJoystickHat { + pub enabled: bool, + pub id: i32, + pub direction: u8, +} + #[derive(serde::Serialize, serde::Deserialize)] pub struct InputProfile { - pub keys: [(bool, i32); ui::input::PROFILE_SIZE], - pub controller_buttons: [(bool, i32); ui::input::PROFILE_SIZE], - pub controller_axis: [(bool, i32, i16); ui::input::PROFILE_SIZE], - pub joystick_buttons: [(bool, i32); ui::input::PROFILE_SIZE], - pub joystick_hat: [(bool, i32, u8); ui::input::PROFILE_SIZE], - pub joystick_axis: [(bool, i32, i16); ui::input::PROFILE_SIZE], + pub keys: [InputKeyButton; ui::input::PROFILE_SIZE], + pub controller_buttons: [InputKeyButton; ui::input::PROFILE_SIZE], + pub controller_axis: [InputControllerAxis; ui::input::PROFILE_SIZE], + pub joystick_buttons: [InputKeyButton; ui::input::PROFILE_SIZE], + pub joystick_hat: [InputJoystickHat; ui::input::PROFILE_SIZE], + pub joystick_axis: [InputControllerAxis; ui::input::PROFILE_SIZE], pub dinput: bool, } diff --git a/src/ui/input.rs b/src/ui/input.rs index 0663864..b4a1fc5 100644 --- a/src/ui/input.rs +++ b/src/ui/input.rs @@ -34,6 +34,11 @@ pub struct Controllers { pub joystick: *mut sdl3_sys::joystick::SDL_Joystick, } +pub struct InputData { + pub data: u32, + pub pak_change_pressed: bool, +} + fn bound_axis(x: &mut f64, y: &mut f64) { let radius = 95.0; // this is roughly the maxium diagonal distance of the controller @@ -54,35 +59,35 @@ fn set_axis_from_joystick( ) -> (f64, f64) { let mut x = 0.0; let mut y = 0.0; - if profile.joystick_axis[AXIS_LEFT].0 { + if profile.joystick_axis[AXIS_LEFT].enabled { let axis_position = unsafe { - sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_LEFT].1) + sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_LEFT].id) }; - if axis_position as isize * profile.joystick_axis[AXIS_LEFT].2 as isize > 0 { + if axis_position as isize * profile.joystick_axis[AXIS_LEFT].axis as isize > 0 { x = axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64; } } - if profile.joystick_axis[AXIS_RIGHT].0 { + if profile.joystick_axis[AXIS_RIGHT].enabled { let axis_position = unsafe { - sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_RIGHT].1) + sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_RIGHT].id) }; - if axis_position as isize * profile.joystick_axis[AXIS_RIGHT].2 as isize > 0 { + if axis_position as isize * profile.joystick_axis[AXIS_RIGHT].axis as isize > 0 { x = axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64; } } - if profile.joystick_axis[AXIS_DOWN].0 { + if profile.joystick_axis[AXIS_DOWN].enabled { let axis_position = unsafe { - sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_DOWN].1) + sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_DOWN].id) }; - if axis_position as isize * profile.joystick_axis[AXIS_DOWN].2 as isize > 0 { + if axis_position as isize * profile.joystick_axis[AXIS_DOWN].axis as isize > 0 { y = (axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64).neg(); } } - if profile.joystick_axis[AXIS_UP].0 { + if profile.joystick_axis[AXIS_UP].enabled { let axis_position = unsafe { - sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_UP].1) + sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile.joystick_axis[AXIS_UP].id) }; - if axis_position as isize * profile.joystick_axis[AXIS_UP].2 as isize > 0 { + if axis_position as isize * profile.joystick_axis[AXIS_UP].axis as isize > 0 { y = (axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64).neg(); } } @@ -128,47 +133,47 @@ fn set_axis_from_controller( ) -> (f64, f64) { let mut x = 0.0; let mut y = 0.0; - if profile.controller_axis[AXIS_LEFT].0 { + if profile.controller_axis[AXIS_LEFT].enabled { let axis_position = unsafe { sdl3_sys::gamepad::SDL_GetGamepadAxis( controller, - get_axis_from_i32(profile.controller_axis[AXIS_LEFT].1), + get_axis_from_i32(profile.controller_axis[AXIS_LEFT].id), ) }; - if axis_position as isize * profile.controller_axis[AXIS_LEFT].2 as isize > 0 { + if axis_position as isize * profile.controller_axis[AXIS_LEFT].axis as isize > 0 { x = axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64; } } - if profile.controller_axis[AXIS_RIGHT].0 { + if profile.controller_axis[AXIS_RIGHT].enabled { let axis_position = unsafe { sdl3_sys::gamepad::SDL_GetGamepadAxis( controller, - get_axis_from_i32(profile.controller_axis[AXIS_RIGHT].1), + get_axis_from_i32(profile.controller_axis[AXIS_RIGHT].id), ) }; - if axis_position as isize * profile.controller_axis[AXIS_RIGHT].2 as isize > 0 { + if axis_position as isize * profile.controller_axis[AXIS_RIGHT].axis as isize > 0 { x = axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64; } } - if profile.controller_axis[AXIS_DOWN].0 { + if profile.controller_axis[AXIS_DOWN].enabled { let axis_position = unsafe { sdl3_sys::gamepad::SDL_GetGamepadAxis( controller, - get_axis_from_i32(profile.controller_axis[AXIS_DOWN].1), + get_axis_from_i32(profile.controller_axis[AXIS_DOWN].id), ) }; - if axis_position as isize * profile.controller_axis[AXIS_DOWN].2 as isize > 0 { + if axis_position as isize * profile.controller_axis[AXIS_DOWN].axis as isize > 0 { y = (axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64).neg(); } } - if profile.controller_axis[AXIS_UP].0 { + if profile.controller_axis[AXIS_UP].enabled { let axis_position = unsafe { sdl3_sys::gamepad::SDL_GetGamepadAxis( controller, - get_axis_from_i32(profile.controller_axis[AXIS_UP].1), + get_axis_from_i32(profile.controller_axis[AXIS_UP].id), ) }; - if axis_position as isize * profile.controller_axis[AXIS_UP].2 as isize > 0 { + if axis_position as isize * profile.controller_axis[AXIS_UP].axis as isize > 0 { y = (axis_position as f64 * MAX_AXIS_VALUE / i16::MAX as f64).neg(); } } @@ -181,23 +186,23 @@ fn set_axis_from_keys( ) -> (f64, f64) { let mut x = 0.0; let mut y = 0.0; - if profile.keys[AXIS_LEFT].0 - && unsafe { *keyboard_state.offset(profile.keys[AXIS_LEFT].1 as isize) } + if profile.keys[AXIS_LEFT].enabled + && unsafe { *keyboard_state.offset(profile.keys[AXIS_LEFT].id as isize) } { x = -MAX_AXIS_VALUE } - if profile.keys[AXIS_RIGHT].0 - && unsafe { *keyboard_state.offset(profile.keys[AXIS_RIGHT].1 as isize) } + if profile.keys[AXIS_RIGHT].enabled + && unsafe { *keyboard_state.offset(profile.keys[AXIS_RIGHT].id as isize) } { x = MAX_AXIS_VALUE } - if profile.keys[AXIS_DOWN].0 - && unsafe { *keyboard_state.offset(profile.keys[AXIS_DOWN].1 as isize) } + if profile.keys[AXIS_DOWN].enabled + && unsafe { *keyboard_state.offset(profile.keys[AXIS_DOWN].id as isize) } { y = -MAX_AXIS_VALUE } - if profile.keys[AXIS_UP].0 - && unsafe { *keyboard_state.offset(profile.keys[AXIS_UP].1 as isize) } + if profile.keys[AXIS_UP].enabled + && unsafe { *keyboard_state.offset(profile.keys[AXIS_UP].id as isize) } { y = MAX_AXIS_VALUE } @@ -211,26 +216,26 @@ fn set_buttons_from_joystick( keys: &mut u32, ) { let profile_joystick_button = profile.joystick_buttons[i]; - if profile_joystick_button.0 { + if profile_joystick_button.enabled { *keys |= (unsafe { - sdl3_sys::joystick::SDL_GetJoystickButton(joystick, profile_joystick_button.1) + sdl3_sys::joystick::SDL_GetJoystickButton(joystick, profile_joystick_button.id) } as u32) << i; } let profile_joystick_hat = profile.joystick_hat[i]; - if profile_joystick_hat.0 - && unsafe { sdl3_sys::joystick::SDL_GetJoystickHat(joystick, profile_joystick_hat.1) } - == profile_joystick_hat.2 + if profile_joystick_hat.enabled + && unsafe { sdl3_sys::joystick::SDL_GetJoystickHat(joystick, profile_joystick_hat.id) } + == profile_joystick_hat.direction { *keys |= 1 << i; } let profile_joystick_axis = profile.joystick_axis[i]; - if profile_joystick_axis.0 { + if profile_joystick_axis.enabled { let axis_position = - unsafe { sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile_joystick_axis.1) }; - if axis_position as isize * profile_joystick_axis.2 as isize > 0 + unsafe { sdl3_sys::joystick::SDL_GetJoystickAxis(joystick, profile_joystick_axis.id) }; + if axis_position as isize * profile_joystick_axis.axis as isize > 0 && axis_position.saturating_abs() > i16::MAX / 2 { *keys |= 1 << i; @@ -245,25 +250,25 @@ fn set_buttons_from_controller( keys: &mut u32, ) { let profile_controller_button = profile.controller_buttons[i]; - if profile_controller_button.0 { + if profile_controller_button.enabled { *keys |= (unsafe { sdl3_sys::gamepad::SDL_GetGamepadButton( controller, - get_button_from_i32(profile_controller_button.1), + get_button_from_i32(profile_controller_button.id), ) } as u32) << i; } let profile_controller_axis = profile.controller_axis[i]; - if profile_controller_axis.0 { + if profile_controller_axis.enabled { let axis_position = unsafe { sdl3_sys::gamepad::SDL_GetGamepadAxis( controller, - get_axis_from_i32(profile_controller_axis.1), + get_axis_from_i32(profile_controller_axis.id), ) }; - if axis_position as isize * profile_controller_axis.2 as isize > 0 + if axis_position as isize * profile_controller_axis.axis as isize > 0 && axis_position.saturating_abs() > i16::MAX / 2 { *keys |= 1 << i; @@ -310,25 +315,26 @@ fn change_paks( let key = profile.keys[CHANGE_PAK]; let mut pressed = false; - if controller_button.0 && !controller.is_null() { + if controller_button.enabled && !controller.is_null() { pressed = unsafe { sdl3_sys::gamepad::SDL_GetGamepadButton( controller, - get_button_from_i32(controller_button.1), + get_button_from_i32(controller_button.id), ) }; - } else if joystick_button.0 && !joystick.is_null() { - pressed = unsafe { sdl3_sys::joystick::SDL_GetJoystickButton(joystick, joystick_button.1) }; - } else if joystick_hat.0 && !joystick.is_null() { - pressed = unsafe { sdl3_sys::joystick::SDL_GetJoystickHat(joystick, joystick_hat.1) } - == joystick_hat.2; - } else if key.0 { - pressed = unsafe { *keyboard_state.offset(key.1 as isize) }; + } else if joystick_button.enabled && !joystick.is_null() { + pressed = + unsafe { sdl3_sys::joystick::SDL_GetJoystickButton(joystick, joystick_button.id) }; + } else if joystick_hat.enabled && !joystick.is_null() { + pressed = unsafe { sdl3_sys::joystick::SDL_GetJoystickHat(joystick, joystick_hat.id) } + == joystick_hat.direction; + } else if key.enabled { + pressed = unsafe { *keyboard_state.offset(key.id as isize) }; } pressed } -pub fn get(ui: &mut ui::Ui, channel: usize) -> (u32, bool) { +pub fn get(ui: &mut ui::Ui, channel: usize) -> InputData { let profile_name = ui.config.input.input_profile_binding[channel].clone(); let profile = ui.config.input.input_profiles.get(&profile_name).unwrap(); let mut keys = 0; @@ -347,8 +353,8 @@ pub fn get(ui: &mut ui::Ui, channel: usize) -> (u32, bool) { for i in 0..14 { if profile_name != "default" || channel == 0 { let profile_key = profile.keys[i]; - if profile_key.0 && !alt_pressed { - keys |= (unsafe { *ui.keyboard_state.offset(profile_key.1 as isize) } as u32) << i; + if profile_key.enabled && !alt_pressed { + keys |= (unsafe { *ui.keyboard_state.offset(profile_key.id as isize) } as u32) << i; } } @@ -376,10 +382,10 @@ pub fn get(ui: &mut ui::Ui, channel: usize) -> (u32, bool) { keys |= (x.round() as i8 as u8 as u32) << X_AXIS_SHIFT; keys |= (y.round() as i8 as u8 as u32) << Y_AXIS_SHIFT; - ( - keys, - change_paks(profile, joystick, controller, ui.keyboard_state), - ) + InputData { + data: keys, + pak_change_pressed: change_paks(profile, joystick, controller, ui.keyboard_state), + } } pub fn assign_controller(ui: &mut ui::Ui, controller: i32, port: usize) { @@ -497,14 +503,39 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) { ("Change Pak", CHANGE_PAK), ]; - let mut new_keys = [(false, 0); PROFILE_SIZE]; - let mut new_joystick_buttons = [(false, 0i32); PROFILE_SIZE]; - let mut new_joystick_hat = [(false, 0i32, 0); PROFILE_SIZE]; - let mut new_joystick_axis = [(false, 0i32, 0); PROFILE_SIZE]; - let mut new_controller_buttons = [(false, 0i32); PROFILE_SIZE]; - let mut new_controller_axis = [(false, 0i32, 0); PROFILE_SIZE]; + let mut new_keys = [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE]; + let mut new_joystick_buttons = [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE]; + let mut new_joystick_hat = [ui::config::InputJoystickHat { + enabled: false, + id: 0, + direction: 0, + }; PROFILE_SIZE]; + let mut new_joystick_axis = [ui::config::InputControllerAxis { + enabled: false, + id: 0, + axis: 0, + }; PROFILE_SIZE]; + let mut new_controller_buttons = [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE]; + let mut new_controller_axis = [ui::config::InputControllerAxis { + enabled: false, + id: 0, + axis: 0, + }; PROFILE_SIZE]; - let mut last_joystick_axis_result = (false, 0, 0); + let mut last_joystick_axis_result = ui::config::InputControllerAxis { + enabled: false, + id: 0, + axis: 0, + }; for (key, value) in key_labels.iter() { let mut event: sdl3_sys::events::SDL_Event = Default::default(); while unsafe { sdl3_sys::events::SDL_PollEvent(&mut event) } {} // clear events @@ -528,20 +559,29 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) { event.key.scancode != sdl3_sys::scancode::SDL_SCANCODE_LALT && event.key.scancode != sdl3_sys::scancode::SDL_SCANCODE_RALT } { - new_keys[*value] = (true, i32::from(unsafe { event.key.scancode })); + new_keys[*value] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(unsafe { event.key.scancode }), + }; key_set = true } } else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_GAMEPAD_BUTTON_DOWN) { if !open_controllers.is_empty() { - new_controller_buttons[*value] = - (true, i32::from(unsafe { event.gbutton.button })); + new_controller_buttons[*value] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(unsafe { event.gbutton.button }), + }; key_set = true } } else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_GAMEPAD_AXIS_MOTION) { let axis_value = unsafe { event.gaxis.value }; let axis = unsafe { event.gaxis.axis }; if !open_controllers.is_empty() && axis_value.saturating_abs() > i16::MAX / 2 { - let result = (true, axis as i32, axis_value / axis_value.saturating_abs()); + let result = ui::config::InputControllerAxis { + enabled: true, + id: axis as i32, + axis: axis_value / axis_value.saturating_abs(), + }; if result != last_joystick_axis_result { new_controller_axis[*value] = result; last_joystick_axis_result = result; @@ -551,15 +591,21 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) { } else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_JOYSTICK_BUTTON_DOWN) { if !open_joysticks.is_empty() { - new_joystick_buttons[*value] = - (true, i32::from(unsafe { event.jbutton.button })); + new_joystick_buttons[*value] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(unsafe { event.jbutton.button }), + }; key_set = true } } else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_JOYSTICK_HAT_MOTION) { let state = unsafe { event.jhat.value }; let hat = unsafe { event.jhat.hat }; if !open_joysticks.is_empty() && state != sdl3_sys::joystick::SDL_HAT_CENTERED { - new_joystick_hat[*value] = (true, hat as i32, state); + new_joystick_hat[*value] = ui::config::InputJoystickHat { + enabled: true, + id: hat as i32, + direction: state, + }; key_set = true } } else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_JOYSTICK_AXIS_MOTION) @@ -567,7 +613,11 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) { let axis_value = unsafe { event.jaxis.value }; let axis = unsafe { event.jaxis.axis }; if !open_joysticks.is_empty() && axis_value.saturating_abs() > i16::MAX / 2 { - let result = (true, axis as i32, axis_value / axis_value.saturating_abs()); + let result = ui::config::InputControllerAxis { + enabled: true, + id: axis as i32, + axis: axis_value / axis_value.saturating_abs(), + }; if result != last_joystick_axis_result { new_joystick_axis[*value] = result; last_joystick_axis_result = result; @@ -599,114 +649,200 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) { } pub fn get_default_profile() -> ui::config::InputProfile { - let mut default_controller_buttons = [(false, 0); PROFILE_SIZE]; - let mut default_controller_axis = [(false, 0, 0); PROFILE_SIZE]; - let mut default_keys = [(false, 0); PROFILE_SIZE]; - default_keys[R_DPAD] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_D)); - default_keys[L_DPAD] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_A)); - default_keys[D_DPAD] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_S)); - default_keys[U_DPAD] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_W)); - default_keys[START_BUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_RETURN)); - default_keys[Z_TRIG] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_Z)); - default_keys[B_BUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_LCTRL)); - default_keys[A_BUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_LSHIFT)); - default_keys[R_CBUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_L)); - default_keys[L_CBUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_J)); - default_keys[D_CBUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_K)); - default_keys[U_CBUTTON] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_I)); - default_keys[R_TRIG] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_C)); - default_keys[L_TRIG] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_X)); - default_keys[AXIS_LEFT] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_LEFT)); - default_keys[AXIS_RIGHT] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_RIGHT)); - default_keys[AXIS_UP] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_UP)); - default_keys[AXIS_DOWN] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_DOWN)); - default_keys[CHANGE_PAK] = (true, i32::from(sdl3_sys::scancode::SDL_SCANCODE_COMMA)); + let mut default_controller_buttons = [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE]; + let mut default_controller_axis = [ui::config::InputControllerAxis { + enabled: false, + id: 0, + axis: 0, + }; PROFILE_SIZE]; + let mut default_keys = [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE]; + default_keys[R_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_D), + }; + default_keys[L_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_A), + }; + default_keys[D_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_S), + }; + default_keys[U_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_W), + }; + default_keys[START_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_RETURN), + }; + default_keys[Z_TRIG] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_Z), + }; + default_keys[B_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_LCTRL), + }; + default_keys[A_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_LSHIFT), + }; + default_keys[R_CBUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_L), + }; + default_keys[L_CBUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_J), + }; + default_keys[D_CBUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_K), + }; + default_keys[U_CBUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_I), + }; + default_keys[R_TRIG] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_C), + }; + default_keys[L_TRIG] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_X), + }; + default_keys[AXIS_LEFT] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_LEFT), + }; + default_keys[AXIS_RIGHT] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_RIGHT), + }; + default_keys[AXIS_UP] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_UP), + }; + default_keys[AXIS_DOWN] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_DOWN), + }; + default_keys[CHANGE_PAK] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::scancode::SDL_SCANCODE_COMMA), + }; - default_controller_buttons[R_DPAD] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_RIGHT), - ); - default_controller_buttons[L_DPAD] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_LEFT), - ); - default_controller_buttons[D_DPAD] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_DOWN), - ); - default_controller_buttons[U_DPAD] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_UP), - ); - default_controller_buttons[START_BUTTON] = - (true, i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_START)); - default_controller_axis[Z_TRIG] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFT_TRIGGER), - 1, - ); - default_controller_buttons[B_BUTTON] = - (true, i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_WEST)); - default_controller_buttons[A_BUTTON] = - (true, i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_SOUTH)); - default_controller_axis[R_CBUTTON] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTX), - 1, - ); - default_controller_axis[L_CBUTTON] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTX), - -1, - ); - default_controller_axis[D_CBUTTON] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTY), - 1, - ); - default_controller_axis[U_CBUTTON] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTY), - -1, - ); - default_controller_buttons[R_TRIG] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER), - ); - default_controller_buttons[L_TRIG] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER), - ); - default_controller_axis[AXIS_LEFT] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTX), - -1, - ); - default_controller_axis[AXIS_RIGHT] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTX), - 1, - ); - default_controller_axis[AXIS_UP] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTY), - -1, - ); - default_controller_axis[AXIS_DOWN] = ( - true, - i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTY), - 1, - ); - default_controller_buttons[CHANGE_PAK] = - (true, i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_BACK)); + default_controller_buttons[R_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_RIGHT), + }; + default_controller_buttons[L_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_LEFT), + }; + default_controller_buttons[D_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_DOWN), + }; + default_controller_buttons[U_DPAD] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_DPAD_UP), + }; + default_controller_buttons[START_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_START), + }; + default_controller_axis[Z_TRIG] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFT_TRIGGER), + axis: 1, + }; + default_controller_buttons[B_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_WEST), + }; + default_controller_buttons[A_BUTTON] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_SOUTH), + }; + default_controller_axis[R_CBUTTON] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTX), + axis: 1, + }; + default_controller_axis[L_CBUTTON] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTX), + axis: -1, + }; + default_controller_axis[D_CBUTTON] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTY), + axis: 1, + }; + default_controller_axis[U_CBUTTON] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_RIGHTY), + axis: -1, + }; + default_controller_buttons[R_TRIG] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER), + }; + default_controller_buttons[L_TRIG] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_LEFT_SHOULDER), + }; + default_controller_axis[AXIS_LEFT] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTX), + axis: -1, + }; + default_controller_axis[AXIS_RIGHT] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTX), + axis: 1, + }; + default_controller_axis[AXIS_UP] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTY), + axis: -1, + }; + default_controller_axis[AXIS_DOWN] = ui::config::InputControllerAxis { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_AXIS_LEFTY), + axis: 1, + }; + default_controller_buttons[CHANGE_PAK] = ui::config::InputKeyButton { + enabled: true, + id: i32::from(sdl3_sys::gamepad::SDL_GAMEPAD_BUTTON_BACK), + }; ui::config::InputProfile { keys: default_keys, controller_buttons: default_controller_buttons, controller_axis: default_controller_axis, - joystick_buttons: Default::default(), - joystick_hat: Default::default(), - joystick_axis: Default::default(), + joystick_buttons: [ui::config::InputKeyButton { + enabled: false, + id: 0, + }; PROFILE_SIZE], + joystick_hat: [ui::config::InputJoystickHat { + enabled: false, + id: 0, + direction: 0, + }; PROFILE_SIZE], + joystick_axis: [ui::config::InputControllerAxis { + enabled: false, + id: 0, + axis: 0, + }; PROFILE_SIZE], dinput: false, } } diff --git a/src/ui/storage.rs b/src/ui/storage.rs index f9f9d69..b5bc764 100644 --- a/src/ui/storage.rs +++ b/src/ui/storage.rs @@ -25,14 +25,26 @@ pub struct Paths { // the bool indicates whether the save has been written to // if that is the case, it will be flushed to the disk when the program closes +#[derive(serde::Serialize, serde::Deserialize)] +pub struct Save { + pub data: Vec, + pub written: bool, +} + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct RomSave { + pub data: std::collections::HashMap, + pub written: bool, +} + #[derive(serde::Serialize, serde::Deserialize)] pub struct Saves { - pub eeprom: (Vec, bool), - pub sram: (Vec, bool), - pub flash: (Vec, bool), - pub mempak: (Vec, bool), - pub sdcard: (Vec, bool), - pub romsave: (std::collections::HashMap, bool), + pub eeprom: Save, + pub sram: Save, + pub flash: Save, + pub mempak: Save, + pub sdcard: Save, + pub romsave: RomSave, } fn get_save_type(rom: &[u8], game_id: &str) -> Vec { @@ -175,27 +187,27 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option) { if netplay.is_none() || netplay.as_ref().unwrap().player_number == 0 { let eep = std::fs::read(&mut ui.paths.eep_file_path); if eep.is_ok() { - ui.saves.eeprom.0 = eep.unwrap(); + ui.saves.eeprom.data = eep.unwrap(); } let sra = std::fs::read(&mut ui.paths.sra_file_path); if sra.is_ok() { - ui.saves.sram.0 = sra.unwrap(); + ui.saves.sram.data = sra.unwrap(); } let fla = std::fs::read(&mut ui.paths.fla_file_path); if fla.is_ok() { - ui.saves.flash.0 = fla.unwrap(); + ui.saves.flash.data = fla.unwrap(); } let mempak = std::fs::read(&mut ui.paths.pak_file_path); if mempak.is_ok() { - ui.saves.mempak.0 = mempak.unwrap(); + ui.saves.mempak.data = mempak.unwrap(); } let sdcard = std::fs::read(&mut ui.paths.sdcard_file_path); if sdcard.is_ok() { - ui.saves.sdcard.0 = sdcard.unwrap(); + ui.saves.sdcard.data = sdcard.unwrap(); } let romsave = std::fs::read(&mut ui.paths.romsave_file_path); if romsave.is_ok() { - ui.saves.romsave.0 = postcard::from_bytes(romsave.unwrap().as_ref()).unwrap(); + ui.saves.romsave.data = postcard::from_bytes(romsave.unwrap().as_ref()).unwrap(); } } @@ -204,31 +216,31 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option) { netplay::send_save( netplay.as_mut().unwrap(), "eep", - &ui.saves.eeprom.0, - ui.saves.eeprom.0.len(), + &ui.saves.eeprom.data, + ui.saves.eeprom.data.len(), ); netplay::send_save( netplay.as_mut().unwrap(), "sra", - &ui.saves.sram.0, - ui.saves.sram.0.len(), + &ui.saves.sram.data, + ui.saves.sram.data.len(), ); netplay::send_save( netplay.as_mut().unwrap(), "fla", - &ui.saves.flash.0, - ui.saves.flash.0.len(), + &ui.saves.flash.data, + ui.saves.flash.data.len(), ); netplay::send_save( netplay.as_mut().unwrap(), "mpk", - &ui.saves.mempak.0, - ui.saves.mempak.0.len(), + &ui.saves.mempak.data, + ui.saves.mempak.data.len(), ); let mut compressed_sd = Vec::new(); - if !ui.saves.sdcard.0.is_empty() { - compressed_sd = compress_file(&[(&ui.saves.sdcard.0, "save")]); + if !ui.saves.sdcard.data.is_empty() { + compressed_sd = compress_file(&[(&ui.saves.sdcard.data, "save")]); } netplay::send_save( netplay.as_mut().unwrap(), @@ -238,9 +250,11 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option) { ); let mut compressed_romsave = Vec::new(); - if !ui.saves.romsave.0.is_empty() { - compressed_romsave = - compress_file(&[(&postcard::to_stdvec(&ui.saves.romsave.0).unwrap(), "save")]); + if !ui.saves.romsave.data.is_empty() { + compressed_romsave = compress_file(&[( + &postcard::to_stdvec(&ui.saves.romsave.data).unwrap(), + "save", + )]); } netplay::send_save( netplay.as_mut().unwrap(), @@ -249,22 +263,22 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option) { compressed_romsave.len(), ); } else { - netplay::receive_save(netplay.as_mut().unwrap(), "eep", &mut ui.saves.eeprom.0); - netplay::receive_save(netplay.as_mut().unwrap(), "sra", &mut ui.saves.sram.0); - netplay::receive_save(netplay.as_mut().unwrap(), "fla", &mut ui.saves.flash.0); - netplay::receive_save(netplay.as_mut().unwrap(), "mpk", &mut ui.saves.mempak.0); + netplay::receive_save(netplay.as_mut().unwrap(), "eep", &mut ui.saves.eeprom.data); + netplay::receive_save(netplay.as_mut().unwrap(), "sra", &mut ui.saves.sram.data); + netplay::receive_save(netplay.as_mut().unwrap(), "fla", &mut ui.saves.flash.data); + netplay::receive_save(netplay.as_mut().unwrap(), "mpk", &mut ui.saves.mempak.data); let mut compressed_sd = Vec::new(); netplay::receive_save(netplay.as_mut().unwrap(), "img", &mut compressed_sd); if !compressed_sd.is_empty() { - ui.saves.sdcard.0 = decompress_file(&compressed_sd, "save"); + ui.saves.sdcard.data = decompress_file(&compressed_sd, "save"); } let mut compressed_romsave = Vec::new(); netplay::receive_save(netplay.as_mut().unwrap(), "rom", &mut compressed_romsave); if !compressed_romsave.is_empty() { let romsave_bytes = decompress_file(&compressed_romsave, "save"); - ui.saves.romsave.0 = postcard::from_bytes(&romsave_bytes).unwrap(); + ui.saves.romsave.data = postcard::from_bytes(&romsave_bytes).unwrap(); } } } @@ -299,28 +313,28 @@ pub fn compress_file(data: &[(&[u8], &str)]) -> Vec { } fn write_rom_save(ui: &ui::Ui) { - let data = postcard::to_stdvec(&ui.saves.romsave.0).unwrap(); + let data = postcard::to_stdvec(&ui.saves.romsave.data).unwrap(); std::fs::write(ui.paths.romsave_file_path.clone(), data).unwrap(); } pub fn write_saves(ui: &ui::Ui, netplay: &Option) { if netplay.is_none() || netplay.as_ref().unwrap().player_number == 0 { - if ui.saves.eeprom.1 { + if ui.saves.eeprom.written { write_save(ui, SaveTypes::Eeprom16k) } - if ui.saves.sram.1 { + if ui.saves.sram.written { write_save(ui, SaveTypes::Sram) } - if ui.saves.flash.1 { + if ui.saves.flash.written { write_save(ui, SaveTypes::Flash) } - if ui.saves.mempak.1 { + if ui.saves.mempak.written { write_save(ui, SaveTypes::Mempak) } - if ui.saves.sdcard.1 { + if ui.saves.sdcard.written { write_save(ui, SaveTypes::Sdcard) } - if ui.saves.romsave.1 { + if ui.saves.romsave.written { write_save(ui, SaveTypes::Romsave) } } @@ -332,23 +346,23 @@ fn write_save(ui: &ui::Ui, save_type: SaveTypes) { match save_type { SaveTypes::Eeprom4k | SaveTypes::Eeprom16k => { path = ui.paths.eep_file_path.as_ref(); - data = ui.saves.eeprom.0.as_ref(); + data = ui.saves.eeprom.data.as_ref(); } SaveTypes::Sram => { path = ui.paths.sra_file_path.as_ref(); - data = ui.saves.sram.0.as_ref(); + data = ui.saves.sram.data.as_ref(); } SaveTypes::Flash => { path = ui.paths.fla_file_path.as_ref(); - data = ui.saves.flash.0.as_ref(); + data = ui.saves.flash.data.as_ref(); } SaveTypes::Mempak => { path = ui.paths.pak_file_path.as_ref(); - data = ui.saves.mempak.0.as_ref(); + data = ui.saves.mempak.data.as_ref(); } SaveTypes::Sdcard => { path = ui.paths.sdcard_file_path.as_ref(); - data = ui.saves.sdcard.0.as_ref(); + data = ui.saves.sdcard.data.as_ref(); } SaveTypes::Romsave => { write_rom_save(ui);