aboutsummaryrefslogtreecommitdiff
path: root/src/desktop
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-05-22 00:07:30 +0200
committerAstatin <[email protected]>2025-05-22 00:07:30 +0200
commit4fce95c86e12f91e127605d440118e1b6a64208b (patch)
tree729ff48e04be1c6fef42a45afb17c0d0a2259ec1 /src/desktop
parent9a8e4117be8d30109229600346e7d9561c52a3e3 (diff)
Save wram,vram,io,hram with X button + move big arrays to Heap
Diffstat (limited to 'src/desktop')
-rw-r--r--src/desktop/audio.rs16
-rw-r--r--src/desktop/input.rs45
-rw-r--r--src/desktop/load_save.rs55
-rw-r--r--src/desktop/mod.rs4
-rw-r--r--src/desktop/window.rs2
5 files changed, 109 insertions, 13 deletions
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: Iterator + Send + 'static>(W);
-impl<W: Iterator + Send + 'static> Iterator for RodioWave<W> where <W as Iterator>::Item: rodio::Sample {
+impl<W: Iterator + Send + 'static> Iterator for RodioWave<W>
+where
+ <W as Iterator>::Item: rodio::Sample,
+{
type Item = W::Item;
fn next(&mut self) -> Option<Self::Item> {
@@ -19,7 +22,10 @@ impl<W: Iterator + Send + 'static> Iterator for RodioWave<W> where <W as Iterato
}
}
-impl<W: Iterator + Send + 'static> Source for RodioWave<W> where <W as Iterator>::Item: rodio::Sample {
+impl<W: Iterator + Send + 'static> Source for RodioWave<W>
+where
+ <W as Iterator>::Item: rodio::Sample,
+{
fn current_frame_len(&self) -> Option<usize> {
None
}
@@ -37,15 +43,13 @@ impl<W: Iterator + Send + 'static> Source for RodioWave<W> where <W as Iterator>
}
}
-
impl Audio for RodioAudio {
- fn new<S: Iterator<Item = f32> + Send + 'static>(wave: S) -> Self {
+ fn new<S: Iterator<Item = f32> + 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<GamepadId>,
+ 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<u128>,
+ 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<String>,
}
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<String>) -> 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<S: Serial, A: Audio>(&self, state: &GBState<S, A>) {
+ 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;