#[cfg(test)]
use crate::cartridge::Cartridge;
#[cfg(test)]
pub struct InesRomBuilder {
prg_rom_size: u8, chr_rom_size: u8, mapper: u8,
mirroring: u8, chr_rom_data: Option<Vec<u8>>,
prg_rom_data: Option<Vec<u8>>,
}
#[cfg(test)]
#[allow(dead_code)] impl InesRomBuilder {
pub fn new() -> Self {
Self {
prg_rom_size: 2, chr_rom_size: 1, mapper: 0, mirroring: 0, chr_rom_data: None,
prg_rom_data: None,
}
}
pub fn prg_rom_size(mut self, size: u8) -> Self {
self.prg_rom_size = size;
self
}
pub fn chr_rom_size(mut self, size: u8) -> Self {
self.chr_rom_size = size;
self
}
pub fn mapper(mut self, mapper: u8) -> Self {
self.mapper = mapper;
self
}
pub fn mirroring(mut self, mirroring: u8) -> Self {
self.mirroring = mirroring;
self
}
pub fn chr_rom_data(mut self, data: Vec<u8>) -> Self {
self.chr_rom_data = Some(data);
self
}
pub fn prg_rom_data(mut self, data: Vec<u8>) -> Self {
self.prg_rom_data = Some(data);
self
}
pub fn build(self) -> Vec<u8> {
let mut ines_data = Vec::new();
ines_data.extend_from_slice(b"NES\x1A"); ines_data.push(self.prg_rom_size);
ines_data.push(self.chr_rom_size);
ines_data.push((self.mapper << 4) | (self.mirroring & 0x01)); ines_data.push(self.mapper & 0xF0); ines_data.extend_from_slice(&[0; 8]);
let prg_size = self.prg_rom_size as usize * 0x4000; if let Some(prg_data) = self.prg_rom_data {
if prg_data.len() > prg_size {
panic!(
"PRG ROM data ({} bytes) exceeds declared size ({} bytes)",
prg_data.len(),
prg_size
);
}
ines_data.extend_from_slice(&prg_data);
if prg_data.len() < prg_size {
ines_data.resize(ines_data.len() + (prg_size - prg_data.len()), 0);
}
} else {
ines_data.resize(ines_data.len() + prg_size, 0);
}
let chr_size = self.chr_rom_size as usize * 0x2000; if let Some(chr_data) = self.chr_rom_data {
if chr_data.len() > chr_size {
panic!(
"CHR ROM data ({} bytes) exceeds declared size ({} bytes)",
chr_data.len(),
chr_size
);
}
ines_data.extend_from_slice(&chr_data);
if chr_data.len() < chr_size {
ines_data.resize(ines_data.len() + (chr_size - chr_data.len()), 0);
}
} else {
ines_data.resize(ines_data.len() + chr_size, 0);
}
ines_data
}
pub fn build_cartridge(self) -> Cartridge {
let rom_data = self.build();
let app_context = crate::app_context::AppContext::new();
Cartridge::load_from_file(&rom_data, "ppu-test-rom.nes", &app_context)
.expect("Failed to create cartridge")
}
}
#[cfg(test)]
impl Default for InesRomBuilder {
fn default() -> Self {
Self::new()
}
}