Use struct instead of tuple (#258)

* Use struct instead of tuple

* more
This commit is contained in:
Logan McNaughton 2025-02-17 09:19:25 +01:00 committed by GitHub
parent aac68a4a1b
commit 671a961789
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 484 additions and 295 deletions

View File

@ -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) {

View File

@ -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];
}

View File

@ -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

View File

@ -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;

View File

@ -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 =

View File

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

View File

@ -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<u8> = [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) {

View File

@ -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(),

View File

@ -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,
}

View File

@ -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,
}
}

View File

@ -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<u8>,
pub written: bool,
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct RomSave {
pub data: std::collections::HashMap<u32, u8>,
pub written: bool,
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Saves {
pub eeprom: (Vec<u8>, bool),
pub sram: (Vec<u8>, bool),
pub flash: (Vec<u8>, bool),
pub mempak: (Vec<u8>, bool),
pub sdcard: (Vec<u8>, bool),
pub romsave: (std::collections::HashMap<u32, u8>, 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<SaveTypes> {
@ -175,27 +187,27 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option<netplay::Netplay>) {
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::Netplay>) {
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<netplay::Netplay>) {
);
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<netplay::Netplay>) {
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<u8> {
}
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<netplay::Netplay>) {
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);