feat(cartridge): grab title from the ROM
This commit is contained in:
parent
cbd085c25b
commit
b43c8ac7c9
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -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)?)
|
||||||
|
|
10
src/ppu.rs
10
src/ppu.rs
|
@ -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,13 +155,15 @@ 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
|
||||||
|
&& line_y < (attr.y + sprite_height)
|
||||||
|
&& !self.sprite_buffer.full()
|
||||||
|
{
|
||||||
self.sprite_buffer.add(attr);
|
self.sprite_buffer.add(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&mut self, cycle: u32) {
|
fn draw(&mut self, cycle: u32) {
|
||||||
use FetcherState::*;
|
use FetcherState::*;
|
||||||
|
|
Loading…
Reference in New Issue