Compare commits

...

10 Commits

Author SHA1 Message Date
Logan McNaughton baee7ffb82 update cargo packages 2025-02-15 23:10:04 +01:00
Logan McNaughton c2780c78b3 Transferpak stub (#254)
* transferpak support

* more

* more
2025-02-15 18:32:36 +01:00
Logan McNaughton ba006ddd53 add transferpak wav 2025-02-15 15:54:25 +01:00
Logan McNaughton e04a151d49 set DPC_PIPEBUSY_REG (#253)
* set DPC_PIPEBUSY_REG

* revert hidden rdram change

* more
2025-02-15 08:29:37 +01:00
Logan McNaughton 8566eee906 fix possible crash in is viewer 2025-02-14 22:20:15 +01:00
Logan McNaughton a1c2ac21be fix hidden rdram size 2025-02-14 21:32:11 +01:00
Logan McNaughton b7d194e12d alt_return to toggle fullscreen (#252)
* alt_return to toggle fullscreen

* more
2025-02-14 12:29:49 +01:00
Logan McNaughton df9ad377d3 add cycles for rsp mfc0 (#251)
* add cycles for rsp mfc0

* more
2025-02-14 10:07:58 +01:00
Logan McNaughton 8f20abe813 update_screen after speed limiter (#250) 2025-02-13 22:09:17 +01:00
Logan McNaughton 3aca3c1664 bump to 1.0.7 (#249) 2025-02-13 21:28:47 +01:00
16 changed files with 111 additions and 42 deletions
Generated
+11 -12
View File
@@ -485,9 +485,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.13"
version = "1.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9"
dependencies = [
"jobserver",
"libc",
@@ -1107,9 +1107,9 @@ dependencies = [
[[package]]
name = "equivalent"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
@@ -1482,7 +1482,7 @@ dependencies = [
[[package]]
name = "gopher64"
version = "1.0.6"
version = "1.0.7"
dependencies = [
"bindgen",
"cc",
@@ -2922,9 +2922,9 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.9"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904"
checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944"
dependencies = [
"cfg_aliases",
"libc",
@@ -3123,15 +3123,14 @@ dependencies = [
[[package]]
name = "ring"
version = "0.17.8"
version = "0.17.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.15",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
@@ -3435,9 +3434,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.2"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "smithay-client-toolkit"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "gopher64"
version = "1.0.6"
version = "1.0.7"
edition = "2021"
rust-version = "1.82"
Binary file not shown.
+8 -1
View File
@@ -141,10 +141,17 @@ bool sdl_event_filter(void *userdata, SDL_Event *event)
{
wsi_platform->do_resize();
}
else if (event->type == SDL_EVENT_KEY_DOWN)
else if (event->type == SDL_EVENT_KEY_UP)
{
switch (event->key.scancode)
{
case SDL_SCANCODE_RETURN:
if (event->key.mod & SDL_KMOD_ALT)
{
fullscreen = !fullscreen;
SDL_SetWindowFullscreen(window, fullscreen);
}
break;
case SDL_SCANCODE_ESCAPE:
if (fullscreen)
callback.emu_running = false;
+1
View File
@@ -357,6 +357,7 @@ impl Device {
pc: 0,
},
broken: false,
running: false,
halted: false,
sync_point: false,
cycle_counter: 0,
+31 -17
View File
@@ -2,6 +2,7 @@ use crate::{device, netplay, savestates, ui};
pub mod mempak;
pub mod rumble;
pub mod transferpak;
pub mod vru;
pub const JCMD_STATUS: u8 = 0x00;
@@ -24,6 +25,7 @@ pub enum PakType {
None = 0,
MemPak = 1,
RumblePak = 2,
TransferPak = 3,
}
#[derive(Copy, Clone, serde::Serialize, serde::Deserialize)]
@@ -159,29 +161,41 @@ fn data_crc(device: &device::Device, data_offset: usize, size: usize) -> u8 {
pub fn pak_switch_event(device: &mut device::Device) {
for (i, channel) in device.pif.channels.iter_mut().enumerate() {
if channel.change_pak != PakType::None {
if channel.change_pak == PakType::RumblePak {
if device.netplay.is_none() {
device::ui::input::set_rumble(&mut device.ui, i, 0);
} else if device.netplay.as_ref().unwrap().player_number as usize == i {
device::ui::input::set_rumble(&mut device.ui, 0, 0);
}
//stop rumble if it is on
if device.netplay.is_none() {
device::ui::input::set_rumble(&mut device.ui, i, 0);
} else if device.netplay.as_ref().unwrap().player_number as usize == i {
device::ui::input::set_rumble(&mut device.ui, 0, 0);
}
let handler = device::controller::PakHandler {
let new_pak_type = match channel.change_pak {
PakType::MemPak => PakType::RumblePak,
PakType::RumblePak => PakType::MemPak,
_ => {
panic!("Invalid pak type");
}
};
if new_pak_type == PakType::MemPak {
channel.pak_handler = Some(device::controller::PakHandler {
read: device::controller::mempak::read,
write: device::controller::mempak::write,
pak_type: device::controller::PakType::MemPak,
};
channel.pak_handler = Some(handler);
ui::audio::play_pak_switch(&mut device.ui, PakType::MemPak);
} else if channel.change_pak == PakType::MemPak {
let handler = device::controller::PakHandler {
pak_type: new_pak_type,
});
} else if new_pak_type == PakType::RumblePak {
channel.pak_handler = Some(device::controller::PakHandler {
read: device::controller::rumble::read,
write: device::controller::rumble::write,
pak_type: device::controller::PakType::RumblePak,
};
channel.pak_handler = Some(handler);
ui::audio::play_pak_switch(&mut device.ui, PakType::RumblePak);
pak_type: new_pak_type,
});
} else if new_pak_type == PakType::TransferPak {
channel.pak_handler = Some(device::controller::PakHandler {
read: device::controller::transferpak::read,
write: device::controller::transferpak::write,
pak_type: new_pak_type,
});
}
ui::audio::play_pak_switch(&mut device.ui, new_pak_type);
channel.change_pak = PakType::None;
}
}
+19
View File
@@ -0,0 +1,19 @@
use crate::device;
pub fn read(
_device: &mut device::Device,
_channel: usize,
_address: u16,
_data: usize,
_size: usize,
) {
}
pub fn write(
_device: &mut device::Device,
_channel: usize,
_address: u16,
_data: usize,
_size: usize,
) {
}
+4 -3
View File
@@ -21,9 +21,10 @@ pub fn write_mem(device: &mut device::Device, address: u64, value: u32, mask: u3
let length = (value & mask) as u64;
let data = std::str::from_utf8(
&device.cart.is_viewer_buffer[0x20_usize..(0x20 + length) as usize],
)
.unwrap();
print!("{}", data);
);
if data.is_ok() {
print!("{}", data.unwrap());
}
} else {
let mut data = u32::from_be_bytes(
device.cart.is_viewer_buffer[masked_address..masked_address + 4]
+5 -1
View File
@@ -53,7 +53,9 @@ pub fn read_regs_dpc(
address: u64,
_access_size: device::memory::AccessSize,
) -> u32 {
device::cop0::add_cycles(device, 20);
if !device.rsp.cpu.running {
device::cop0::add_cycles(device, 20);
}
let reg = (address & 0xFFFF) >> 2;
match reg as u32 {
DPC_STATUS_REG => {
@@ -116,6 +118,7 @@ fn run_rdp(device: &mut device::Device) {
let timer = ui::video::process_rdp_list();
device.rdp.regs_dpc[DPC_STATUS_REG as usize] |=
DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY | DPC_STATUS_CMD_BUSY;
device.rdp.regs_dpc[DPC_PIPEBUSY_REG as usize] = 0xFFFFFF;
if timer != 0 {
if device.save_state {
@@ -203,6 +206,7 @@ fn update_dpc_status(device: &mut device::Device, w: u32) {
pub fn init(device: &mut device::Device) {
device.rdp.regs_dpc[DPC_STATUS_REG as usize] |=
DPC_STATUS_START_GCLK | DPC_STATUS_PIPE_BUSY | DPC_STATUS_CBUF_READY;
device.rdp.regs_dpc[DPC_PIPEBUSY_REG as usize] = 0xFFFFFF;
}
pub fn rdp_interrupt_event(device: &mut device::Device) {
+3
View File
@@ -34,6 +34,7 @@ pub struct Cpu {
pub pipeline_full: bool,
pub branch_state: BranchState,
pub broken: bool,
pub running: bool,
pub halted: bool,
pub sync_point: bool,
pub cycle_counter: u64,
@@ -125,6 +126,7 @@ pub fn in_delay_slot_taken(device: &device::Device) -> bool {
pub fn run(device: &mut device::Device) -> u64 {
device.rsp.cpu.broken = false;
device.rsp.cpu.cycle_counter = 0;
device.rsp.cpu.running = true;
while !device.rsp.cpu.sync_point {
device.rsp.cpu.instruction_type = InstructionType::Su;
device.rsp.cpu.gpr[0] = 0; // gpr 0 is read only
@@ -186,6 +188,7 @@ pub fn run(device: &mut device::Device) -> u64 {
}
}
}
device.rsp.cpu.running = false;
(device.rsp.cpu.cycle_counter as f64 * 1.5) as u64 // converting RCP clock to CPU clock
}
+3 -2
View File
@@ -267,7 +267,9 @@ pub fn read_regs(
address: u64,
_access_size: device::memory::AccessSize,
) -> u32 {
device::cop0::add_cycles(device, 20);
if !device.rsp.cpu.running {
device::cop0::add_cycles(device, 20);
}
let reg = (address & 0xFFFF) >> 2;
match reg as u32 {
SP_DMA_BUSY_REG | SP_DMA_FULL_REG => {
@@ -292,7 +294,6 @@ pub fn read_regs(
let value = device.rsp.regs[reg as usize];
if value == 1 {
device.rsp.cpu.sync_point = true;
device.rsp.cpu.cycle_counter += 4; // needed for DK64
}
device.rsp.regs[reg as usize] = 1;
value
+1
View File
@@ -552,6 +552,7 @@ pub fn bgezal(device: &mut device::Device, opcode: u32) {
}
pub fn mfc0(device: &mut device::Device, opcode: u32) {
device.rsp.cpu.cycle_counter += 2;
if rd(opcode) < device::rsp_interface::SP_REGS_COUNT {
device.rsp.cpu.gpr[rt(opcode) as usize] = device::rsp_interface::read_regs(
device,
+1 -1
View File
@@ -137,7 +137,6 @@ pub fn write_regs(device: &mut device::Device, address: u64, value: u32, mask: u
}
pub fn vertical_interrupt_event(device: &mut device::Device) {
ui::video::update_screen();
ui::video::check_callback(device);
let mut enable_speed_limiter = true;
@@ -150,6 +149,7 @@ pub fn vertical_interrupt_event(device: &mut device::Device) {
if device.vi.vi_counter % device.vi.limit_freq == 0 && enable_speed_limiter {
speed_limiter(device);
}
ui::video::update_screen();
/*
let vis = if device.cart.pal { 50 } else { 60 };
+1
View File
@@ -132,6 +132,7 @@ impl Ui {
pak_audio: audio::PakAudio {
mempak: include_bytes!("../data/mempak.wav").to_vec(),
rumblepak: include_bytes!("../data/rumblepak.wav").to_vec(),
transferpak: include_bytes!("../data/transferpak.wav").to_vec(),
},
window: std::ptr::null_mut(),
audio_stream: std::ptr::null_mut(),
+3
View File
@@ -4,6 +4,7 @@ use crate::ui;
pub struct PakAudio {
pub mempak: Vec<u8>,
pub rumblepak: Vec<u8>,
pub transferpak: Vec<u8>,
}
pub fn init(ui: &mut ui::Ui, frequency: u64) {
@@ -76,6 +77,8 @@ pub fn play_pak_switch(ui: &mut ui::Ui, pak: device::controller::PakType) {
sound = &ui.pak_audio.rumblepak;
} else if pak == device::controller::PakType::MemPak {
sound = &ui.pak_audio.mempak;
} else if pak == device::controller::PakType::TransferPak {
sound = &ui.pak_audio.transferpak;
} else {
return;
}
+19 -4
View File
@@ -334,10 +334,20 @@ pub fn get(ui: &mut ui::Ui, channel: usize) -> (u32, bool) {
let mut keys = 0;
let controller = ui.controllers[channel].game_controller;
let joystick = ui.controllers[channel].joystick;
let alt_pressed = unsafe {
// ignore key presses if ALT is pressed
*ui.keyboard_state
.offset(i32::from(sdl3_sys::scancode::SDL_SCANCODE_LALT) as isize)
|| *ui
.keyboard_state
.offset(i32::from(sdl3_sys::scancode::SDL_SCANCODE_RALT) as isize)
};
for i in 0..14 {
if profile_name != "default" || channel == 0 {
let profile_key = profile.keys[i];
if profile_key.0 {
if profile_key.0 && !alt_pressed {
keys |= (unsafe { *ui.keyboard_state.offset(profile_key.1 as isize) } as u32) << i;
}
}
@@ -513,9 +523,14 @@ pub fn configure_input_profile(ui: &mut ui::Ui, profile: String, dinput: bool) {
if event_type == u32::from(sdl3_sys::events::SDL_EVENT_WINDOW_CLOSE_REQUESTED) {
close_controllers(open_joysticks, open_controllers);
return;
} else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_KEY_DOWN) {
new_keys[*value] = (true, i32::from(unsafe { event.key.scancode }));
key_set = true
} else if event_type == u32::from(sdl3_sys::events::SDL_EVENT_KEY_UP) {
if unsafe {
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 }));
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] =