diff --git a/src/device.rs b/src/device.rs index 42b54b0b..a7160f6c 100644 --- a/src/device.rs +++ b/src/device.rs @@ -302,6 +302,7 @@ impl Device { pal: false, latch: 0, cic_seed: 0, + rtc_timestamp: 0, rtc: cart::AfRtc { control: 0x0200 }, sc64: cart::sc64::Sc64 { regs: [0; cart::sc64::SC64_REGS_COUNT as usize], diff --git a/src/device/cart.rs b/src/device/cart.rs index 157ee366..448fc02a 100644 --- a/src/device/cart.rs +++ b/src/device/cart.rs @@ -52,6 +52,7 @@ pub struct Cart { pub rtc: AfRtc, pub sc64: sc64::Sc64, pub flashram: sram::Flashram, + pub rtc_timestamp: i64, } pub fn process(device: &mut device::Device, channel: usize) { @@ -151,7 +152,9 @@ fn eeprom_write_block(device: &mut device::Device, block: usize, offset: usize, } fn time2data(device: &mut device::Device, offset: usize) { - let now: chrono::DateTime = chrono::Local::now(); + let timestamp = + device.cart.rtc_timestamp + (device.vi.frame_time * device.vi.vi_counter as f64) as i64; + let now = chrono::DateTime::from_timestamp(timestamp, 0).unwrap(); device.pif.ram[offset] = byte2bcd(now.second()); device.pif.ram[offset + 1] = byte2bcd(now.minute()); diff --git a/src/device/cart/rom.rs b/src/device/cart/rom.rs index b74f31b7..87a9b386 100644 --- a/src/device/cart/rom.rs +++ b/src/device/cart/rom.rs @@ -1,4 +1,5 @@ use crate::device; +use crate::netplay; use sha2::{Digest, Sha256}; const CART_MASK: usize = 0xFFFFFFF; @@ -121,6 +122,17 @@ pub fn dma_write( } pub fn init(device: &mut device::Device, rom_file: Vec) { + let now: chrono::DateTime = chrono::Local::now(); + device.cart.rtc_timestamp = now.naive_local().and_utc().timestamp(); + if device.netplay.is_some() { + let netplay = device.netplay.as_mut().unwrap(); + if netplay.player_number == 0 { + netplay::send_rtc(netplay, device.cart.rtc_timestamp); + } else { + device.cart.rtc_timestamp = netplay::receive_rtc(netplay); + } + } + device.cart.sc64.cfg[device::cart::sc64::SC64_BOOTLOADER_SWITCH as usize] = 1; device.cart.rom = rom_file; diff --git a/src/netplay.rs b/src/netplay.rs index b0a4a78b..f9cd27da 100644 --- a/src/netplay.rs +++ b/src/netplay.rs @@ -16,6 +16,8 @@ const TCP_REGISTER_PLAYER: u8 = 5; const TCP_GET_REGISTRATION: u8 = 6; const TCP_DISCONNECT_NOTICE: u8 = 7; const TCP_RECEIVE_SAVE_WITH_SIZE: u8 = 8; +const TCP_SEND_RTC: u8 = 64; +const TCP_RECEIVE_RTC: u8 = 128; const CS4: u32 = 32; @@ -50,6 +52,22 @@ pub const NETPLAY_ERROR_PLAYER_2_DISCONNECTED: u32 = 4; pub const NETPLAY_ERROR_PLAYER_3_DISCONNECTED: u32 = 5; pub const NETPLAY_ERROR_PLAYER_4_DISCONNECTED: u32 = 6; +pub fn send_rtc(netplay: &mut Netplay, rtc: i64) { + let mut request: Vec = [TCP_SEND_RTC].to_vec(); + let size: u32 = 8; + request.extend_from_slice(&size.to_be_bytes()); + request.extend_from_slice(&rtc.to_be_bytes()); + netplay.tcp_stream.write_all(&request).unwrap(); +} + +pub fn receive_rtc(netplay: &mut Netplay) -> i64 { + let request: Vec = [TCP_RECEIVE_RTC].to_vec(); + netplay.tcp_stream.write_all(&request).unwrap(); + let mut rtc: [u8; 8] = [0; 8]; + netplay.tcp_stream.read_exact(&mut rtc).unwrap(); + i64::from_be_bytes(rtc) +} + pub fn send_save(netplay: &mut Netplay, save_type: &str, save_data: &[u8], size: usize) { let mut request: Vec = [TCP_SEND_SAVE].to_vec(); request.extend_from_slice(save_type.as_bytes());