chore: remove Emulator struct

This commit is contained in:
2021-11-21 05:27:04 -04:00
parent 939c25ce1a
commit 2405fd027f
4 changed files with 80 additions and 129 deletions

View File

@@ -15,125 +15,91 @@ pub const CYCLES_IN_FRAME: Cycle = 456 * 154; // 456 Cycles times 154 scanlines
pub(crate) const SM83_CLOCK_SPEED: u64 = 0x40_0000; // Hz which is 4.194304Mhz
const DEFAULT_TITLE: &str = "DMG-01 Emulator";
pub fn run_frame(emu: &mut Emulator, gamepad: &mut Gilrs, key: KeyboardInput) -> Cycle {
pub fn run_frame(cpu: &mut Cpu, gamepad: &mut Gilrs, key: KeyboardInput) -> Cycle {
let mut elapsed = 0;
if let Some(event) = gamepad.next_event() {
crate::joypad::handle_gamepad_input(&mut emu.cpu.bus.joyp, event);
crate::joypad::handle_gamepad_input(&mut cpu.bus.joyp, event);
}
crate::joypad::handle_keyboard_input(&mut emu.cpu.bus.joyp, key);
crate::joypad::handle_keyboard_input(&mut cpu.bus.joyp, key);
while elapsed < CYCLES_IN_FRAME {
elapsed += emu.step();
elapsed += cpu.step();
}
elapsed
}
pub fn pixel_buf(emu: &Emulator) -> &[u8; GB_HEIGHT * GB_WIDTH * 4] {
emu.cpu.bus.ppu.frame_buf.as_ref()
pub fn pixel_buf(cpu: &Cpu) -> &[u8; GB_HEIGHT * GB_WIDTH * 4] {
cpu.bus.ppu.frame_buf.as_ref()
}
pub struct Emulator {
cpu: Cpu,
timestamp: Cycle,
pub fn from_boot_rom<P: AsRef<Path>>(path: P) -> std::io::Result<Cpu> {
Ok(Cpu::new(read_boot(path)?))
}
impl Default for Emulator {
fn default() -> Self {
Self::new()
}
pub fn read_game_rom<P: AsRef<Path>>(cpu: &mut Cpu, path: P) -> std::io::Result<()> {
Ok(cpu.bus.load_cart(std::fs::read(path.as_ref())?))
}
impl Emulator {
pub fn new() -> Self {
Self {
cpu: Cpu::with_boot(*include_bytes!("../bin/bootix_dmg.bin")),
timestamp: Default::default(),
pub fn set_audio_producer(cpu: &mut Cpu, producer: SampleProducer<f32>) {
cpu.bus.apu.attach_producer(producer);
}
pub fn rom_title(cpu: &Cpu) -> &str {
cpu.bus.cart_title().unwrap_or(DEFAULT_TITLE)
}
pub fn write_save(cpu: &Cpu) -> std::io::Result<()> {
if let Some(ext_ram) = cpu.bus.cart.as_ref().map(|c| c.ext_ram()).flatten() {
if let Some(title) = cpu.bus.cart_title() {
let mut save_path = data_path().unwrap_or_else(|| PathBuf::from("."));
save_path.push(title);
save_path.set_extension("sav");
let mut file = File::create(save_path)?;
file.write_all(ext_ram)?;
}
}
pub fn from_boot_rom<P: AsRef<Path>>(path: P) -> std::io::Result<Self> {
Ok(Self {
cpu: Cpu::with_boot(Self::read_boot(path)?),
timestamp: Default::default(),
})
}
Ok(())
}
fn read_boot<P: AsRef<Path>>(path: P) -> std::io::Result<[u8; BOOT_SIZE]> {
let mut buf = [0; BOOT_SIZE];
let mut file = File::open(path.as_ref())?;
pub fn load_save(cpu: &mut Cpu) -> std::io::Result<()> {
if let Some(cart) = &mut cpu.bus.cart {
if let Some(title) = cart.title() {
let mut save_path = data_path().unwrap_or_else(|| PathBuf::from("."));
save_path.push(title);
save_path.set_extension("sav");
file.read_exact(&mut buf)?;
Ok(buf)
}
if let Ok(mut file) = File::open(&save_path) {
tracing::info!("Load {:?}", save_path);
fn step(&mut self) -> Cycle {
let cycles = self.cpu.step();
self.timestamp += cycles;
cycles
}
pub fn read_game_rom<P: AsRef<Path>>(&mut self, path: P) -> std::io::Result<()> {
self.load_rom(std::fs::read(path.as_ref())?);
Ok(())
}
fn load_rom(&mut self, rom: Vec<u8>) {
self.cpu.bus.load_cart(rom);
}
pub fn set_prod(&mut self, prod: SampleProducer<f32>) {
self.cpu.bus.apu_mut().attach_producer(prod)
}
pub fn title(&self) -> &str {
self.cpu.bus.cart_title().unwrap_or(DEFAULT_TITLE)
}
pub fn try_write_sav(&self) -> std::io::Result<()> {
if let Some(ext_ram) = self.cpu.bus.cart.as_ref().map(|c| c.ext_ram()).flatten() {
if let Some(title) = self.cpu.bus.cart_title() {
let mut save_path = Self::data_path().unwrap_or_else(|| PathBuf::from("."));
save_path.push(title);
save_path.set_extension("sav");
let mut file = File::create(save_path)?;
file.write_all(ext_ram)?;
let mut memory = Vec::new();
file.read_to_end(&mut memory)?;
cart.write_ext_ram(memory);
}
}
Ok(())
}
pub fn try_load_sav(&mut self) -> std::io::Result<()> {
if let Some(cart) = &mut self.cpu.bus.cart {
if let Some(title) = cart.title() {
let mut save_path = Self::data_path().unwrap_or_else(|| PathBuf::from("."));
save_path.push(title);
save_path.set_extension("sav");
Ok(())
}
if let Ok(mut file) = File::open(&save_path) {
tracing::info!("Load {:?}", save_path);
fn read_boot<P: AsRef<Path>>(path: P) -> std::io::Result<[u8; BOOT_SIZE]> {
let mut buf = [0; BOOT_SIZE];
let mut file = File::open(path.as_ref())?;
let mut memory = Vec::new();
file.read_to_end(&mut memory)?;
cart.write_ext_ram(memory);
}
}
}
Ok(())
}
fn data_path() -> Option<PathBuf> {
match directories_next::ProjectDirs::from("dev", "musuka", crate_name!()) {
Some(dirs) => {
let data_local = dirs.data_local_dir();
std::fs::create_dir_all(data_local).ok()?;
Some(data_local.to_path_buf())
}
None => None,
file.read_exact(&mut buf)?;
Ok(buf)
}
fn data_path() -> Option<PathBuf> {
match directories_next::ProjectDirs::from("dev", "musuka", crate_name!()) {
Some(dirs) => {
let data_local = dirs.data_local_dir();
std::fs::create_dir_all(data_local).ok()?;
Some(data_local.to_path_buf())
}
None => None,
}
}