feat(cartridge): grab title from the ROM
This commit is contained in:
		| @@ -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)?) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/ppu.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								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,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); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user