From 4fce95c86e12f91e127605d440118e1b6a64208b Mon Sep 17 00:00:00 2001 From: Astatin Date: Thu, 22 May 2025 00:07:30 +0200 Subject: Save wram,vram,io,hram with X button + move big arrays to Heap --- src/desktop/audio.rs | 16 ++++++++------ src/desktop/input.rs | 45 +++++++++++++++++++++++++++++++++++++-- src/desktop/load_save.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++-- src/desktop/mod.rs | 4 ++-- src/desktop/window.rs | 2 +- 5 files changed, 109 insertions(+), 13 deletions(-) (limited to 'src/desktop') diff --git a/src/desktop/audio.rs b/src/desktop/audio.rs index 60d32df..c32433b 100644 --- a/src/desktop/audio.rs +++ b/src/desktop/audio.rs @@ -1,7 +1,7 @@ use rodio::{OutputStream, Sink, Source}; -use crate::io::Audio; use crate::audio::SAMPLE_RATE; +use crate::io::Audio; use std::time::Duration; pub struct RodioAudio { @@ -11,7 +11,10 @@ pub struct RodioAudio { struct RodioWave(W); -impl Iterator for RodioWave where ::Item: rodio::Sample { +impl Iterator for RodioWave +where + ::Item: rodio::Sample, +{ type Item = W::Item; fn next(&mut self) -> Option { @@ -19,7 +22,10 @@ impl Iterator for RodioWave where Source for RodioWave where ::Item: rodio::Sample { +impl Source for RodioWave +where + ::Item: rodio::Sample, +{ fn current_frame_len(&self) -> Option { None } @@ -37,15 +43,13 @@ impl Source for RodioWave where } } - impl Audio for RodioAudio { - fn new + Send + 'static>(wave: S) -> Self { + fn new + Send + 'static>(wave: S) -> Self { let (stream, stream_handle) = OutputStream::try_default().unwrap(); let sink = Sink::try_new(&stream_handle).unwrap(); sink.append(RodioWave(wave)); - RodioAudio { _stream: stream, _sink: sink, diff --git a/src/desktop/input.rs b/src/desktop/input.rs index 1a2a212..d7c10c8 100644 --- a/src/desktop/input.rs +++ b/src/desktop/input.rs @@ -1,14 +1,15 @@ use std::fs::File; use std::io::{ErrorKind, Read, Write}; -use gilrs::{Button, GamepadId, Gilrs}; use crate::desktop::window::Keys; use crate::io::Input; +use gilrs::{Button, GamepadId, Gilrs}; use winit::keyboard::KeyCode; pub struct Gamepad { gilrs: Gilrs, gamepad_id: Option, + last_save_state: bool, } impl Gamepad { @@ -23,7 +24,11 @@ impl Gamepad { None }; - Self { gilrs, gamepad_id } + Self { + gilrs, + gamepad_id, + last_save_state: false, + } } pub fn check_special_actions(&self, is_debug: &mut bool) { @@ -92,6 +97,19 @@ impl Input for Gamepad { res } + + fn save_state(&mut self) -> bool { + let mut ret = false; + + if let Some(gamepad_id) = self.gamepad_id { + if let Some(gamepad) = self.gilrs.connected_gamepad(gamepad_id) { + let pressed = gamepad.is_pressed(Button::North); + ret = pressed && !self.last_save_state; + self.last_save_state = pressed; + } + } + ret + } } pub struct Keyboard { @@ -163,6 +181,10 @@ impl Input for Keyboard { fn get_direction_gamepad_reg(&self) -> u8 { self.direction_reg } + + fn save_state(&mut self) -> bool { + false + } } pub struct GamepadRecorder { @@ -221,6 +243,10 @@ impl Input for GamepadRecorder { fn get_direction_gamepad_reg(&self) -> u8 { self.direction_reg } + + fn save_state(&mut self) -> bool { + false + } } pub struct GamepadReplay { @@ -228,6 +254,7 @@ pub struct GamepadReplay { action_reg: u8, direction_reg: u8, next_cycle_update: Option, + last_save_state: bool, } impl GamepadReplay { @@ -247,6 +274,7 @@ impl GamepadReplay { action_reg: 0xff, direction_reg: 0xff, next_cycle_update, + last_save_state: false, } } } @@ -284,4 +312,17 @@ impl Input for GamepadReplay { fn get_direction_gamepad_reg(&self) -> u8 { self.direction_reg } + + fn save_state(&mut self) -> bool { + if self.last_save_state { + return false; + } + if self.next_cycle_update == None { + println!("SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE"); + + self.last_save_state = true; + return true; + } + false + } } diff --git a/src/desktop/load_save.rs b/src/desktop/load_save.rs index dfe2083..5c3a123 100644 --- a/src/desktop/load_save.rs +++ b/src/desktop/load_save.rs @@ -1,10 +1,13 @@ +use crate::io::{Audio, LoadSave, Serial}; +use crate::state::GBState; use std::fs::File; -use std::io::{Write, Read}; -use crate::io::LoadSave; +use std::io::{Read, Write}; +#[derive(Debug)] pub struct FSLoadSave { rom_file: String, save_file: String, + state_file: Option, } impl FSLoadSave { @@ -12,8 +15,14 @@ impl FSLoadSave { Self { rom_file: rom_file.into(), save_file: save_file.into(), + state_file: None, } } + + pub fn state_file(mut self, state_file: impl Into) -> Self { + self.state_file = Some(state_file.into()); + self + } } impl LoadSave for FSLoadSave { @@ -66,4 +75,46 @@ impl LoadSave for FSLoadSave { Ok(()) } + + fn save_state(&self, state: &GBState) { + if let Some(state_file) = &self.state_file { + { + let mut vram_dump_file = File::create(format!("{}.vram", state_file)).unwrap(); + + for addr in 0x8000..0xa000 { + vram_dump_file + .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); + } + } + + { + let mut wram_dump_file = File::create(format!("{}.wram", state_file)).unwrap(); + + for addr in 0xc000..0xe000 { + wram_dump_file + .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); + } + } + + { + let mut io_dump_file = File::create(format!("{}.io", state_file)).unwrap(); + + for addr in 0xff00..0xff80 { + io_dump_file + .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); + } + } + + { + let mut hram_dump_file = File::create(format!("{}.hram", state_file)).unwrap(); + + for addr in 0xff80..=0xffff { + hram_dump_file + .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); + } + } + } else { + panic!("{:?}", self) + } + } } diff --git a/src/desktop/mod.rs b/src/desktop/mod.rs index af773b6..3448c0e 100644 --- a/src/desktop/mod.rs +++ b/src/desktop/mod.rs @@ -1,5 +1,5 @@ -pub mod window; -pub mod input; pub mod audio; +pub mod input; pub mod load_save; pub mod serial; +pub mod window; diff --git a/src/desktop/window.rs b/src/desktop/window.rs index 14ac3a7..78a7c42 100644 --- a/src/desktop/window.rs +++ b/src/desktop/window.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use std::sync::Arc; use std::time::Duration; -use crate::io::{WindowSignal, Window}; +use crate::io::{Window, WindowSignal}; use pixels::{Error, Pixels, SurfaceTexture}; use winit::dpi::LogicalSize; -- cgit v1.2.3-70-g09d2