feat(cartridge): grab title from the ROM

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-04-14 01:21:45 -05:00
parent cbd085c25b
commit b43c8ac7c9
5 changed files with 39 additions and 9 deletions

View File

@ -63,6 +63,10 @@ impl Bus {
Ok(()) Ok(())
} }
pub fn rom_title(&self) -> Option<&str> {
self.cartridge.as_ref()?.title()
}
pub fn step(&mut self, cycles: Cycle) { pub fn step(&mut self, cycles: Cycle) {
self.ppu.step(cycles); self.ppu.step(cycles);
self.timer.step(cycles); self.timer.step(cycles);

View File

@ -9,6 +9,7 @@ const MBC_TYPE_ADDRESS: usize = 0x0147;
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct Cartridge { pub struct Cartridge {
memory: Vec<u8>, memory: Vec<u8>,
title: Option<String>,
mbc: Box<dyn MemoryBankController>, mbc: Box<dyn MemoryBankController>,
} }
@ -20,6 +21,7 @@ impl Cartridge {
Ok(Self { Ok(Self {
mbc: Self::detect_mbc(&memory), mbc: Self::detect_mbc(&memory),
title: Self::find_title(&memory),
memory, memory,
}) })
} }
@ -46,6 +48,21 @@ impl Cartridge {
} }
} }
fn find_title(memory: &[u8]) -> Option<String> {
// FIXME: Get rid of magic values and handle cases
// where 0x134..0x143 reads past the length of the
// string
let slice = &memory[0x134..0x143];
let str_with_nulls = std::str::from_utf8(slice).ok();
str_with_nulls.map(|s| s.trim_matches('\0').to_string())
}
pub fn title(&self) -> Option<&str> {
self.title.as_deref()
}
fn find_ram_size(memory: &[u8]) -> RamSize { fn find_ram_size(memory: &[u8]) -> RamSize {
let id = memory[RAM_SIZE_ADDRESS]; let id = memory[RAM_SIZE_ADDRESS];
id.into() id.into()

View File

@ -68,6 +68,10 @@ impl Cpu {
pub fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> { pub fn load_cartridge(&mut self, path: &str) -> std::io::Result<()> {
self.bus.load_cartridge(path) self.bus.load_cartridge(path)
} }
pub fn rom_title(&self) -> Option<&str> {
self.bus.rom_title()
}
} }
impl Cpu { impl Cpu {

View File

@ -31,7 +31,7 @@ fn main() -> Result<()> {
.takes_value(true) .takes_value(true)
.required(true) .required(true)
.index(1) .index(1)
.help("The ROM that the emulator will run"), .help("Path to the Game ROM"),
) )
.arg( .arg(
Arg::with_name("boot") Arg::with_name("boot")
@ -58,10 +58,13 @@ fn main() -> Result<()> {
.load_cartridge(rom_path) .load_cartridge(rom_path)
.expect("Failed to load ROM"); .expect("Failed to load ROM");
let default_title = "DMG-01 Emulator";
let cartridge_title = game_boy.rom_title().unwrap_or(&default_title);
// Initialize GUI // Initialize GUI
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
let mut input = WinitInputHelper::new(); let mut input = WinitInputHelper::new();
let window = create_window(&event_loop)?; let window = create_window(&event_loop, cartridge_title)?;
let mut pixels = create_pixels(&window)?; let mut pixels = create_pixels(&window)?;
let mut now = Instant::now(); let mut now = Instant::now();
@ -114,10 +117,10 @@ fn main() -> Result<()> {
}); });
} }
fn create_window(event_loop: &EventLoop<()>) -> Result<Window> { fn create_window(event_loop: &EventLoop<()>, title: &str) -> Result<Window> {
let size = LogicalSize::new((GB_WIDTH as f64) * SCALE, (GB_HEIGHT as f64) * SCALE); let size = LogicalSize::new((GB_WIDTH as f64) * SCALE, (GB_HEIGHT as f64) * SCALE);
Ok(WindowBuilder::new() Ok(WindowBuilder::new()
.with_title("DMG-1 Emulator") .with_title(title)
.with_inner_size(size) .with_inner_size(size)
.with_min_inner_size(size) .with_min_inner_size(size)
.build(&event_loop)?) .build(&event_loop)?)

View File

@ -49,7 +49,7 @@ impl Ppu {
let start: u32 = self.cycles.into(); let start: u32 = self.cycles.into();
let end: u32 = cycles.into(); let end: u32 = cycles.into();
for cycle in start..(start + end).into() { for _ in start..(start + end) {
self.cycles += 1; self.cycles += 1;
match self.stat.mode() { match self.stat.mode() {
@ -155,10 +155,12 @@ impl Ppu {
let attr = self.oam.attribute((cycle / 2) as usize); let attr = self.oam.attribute((cycle / 2) as usize);
let line_y = self.pos.line_y + 16; let line_y = self.pos.line_y + 16;
if attr.x > 0 && line_y >= attr.y && line_y < (attr.y + sprite_height) { if attr.x > 0
if !self.sprite_buffer.full() { && line_y >= attr.y
self.sprite_buffer.add(attr); && line_y < (attr.y + sprite_height)
} && !self.sprite_buffer.full()
{
self.sprite_buffer.add(attr);
} }
} }
} }