From f65e22cc41150c63e09d5460b0cfe38b8af9d40c Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Sat, 30 May 2020 13:41:10 +0300 Subject: [PATCH] core/gpu: Fix bitmap mode displaying invalid sprites fixes #107 Former-commit-id: 4b307c80f0519a5034dad1188d285cb44a2c8eeb Former-commit-id: 8879aababad1aef0690adb0a88cdeb36368c024a --- rustboyadvance-core/src/gpu/mod.rs | 29 ++++++++++++++++++----- rustboyadvance-core/src/gpu/render/obj.rs | 6 +++++ rustboyadvance-core/src/iodev.rs | 2 +- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/rustboyadvance-core/src/gpu/mod.rs b/rustboyadvance-core/src/gpu/mod.rs index 252d873..5d4adf7 100644 --- a/rustboyadvance-core/src/gpu/mod.rs +++ b/rustboyadvance-core/src/gpu/mod.rs @@ -51,6 +51,9 @@ pub mod consts { pub const CYCLES_FULL_REFRESH: usize = 280896; pub const TILE_SIZE: u32 = 0x20; + + pub(super) const VRAM_OBJ_TILES_START_TEXT: u32 = 0x1_0000; + pub(super) const VRAM_OBJ_TILES_START_BITMAP: u32 = 0x1_4000; } pub use self::consts::*; @@ -201,6 +204,8 @@ pub struct Gpu { pub vram: BoxedMemory, pub oam: BoxedMemory, + pub(super) vram_obj_tiles_start: u32, + #[debug_stub = "Sprite Buffer"] pub obj_buffer: Vec, @@ -230,6 +235,8 @@ impl Gpu { bldalpha: BlendAlpha(0), bldy: 0, + vram_obj_tiles_start: VRAM_OBJ_TILES_START_TEXT, + state: HDraw, vcount: 0, cycles_left_for_current_state: CYCLES_HDRAW, @@ -244,6 +251,21 @@ impl Gpu { } } + pub fn write_dispcnt(&mut self, value: u16) { + let new_dispcnt = DisplayControl(value); + let old_mode = self.dispcnt.mode(); + let new_mode = new_dispcnt.mode(); + if old_mode != new_mode { + debug!("[GPU] Display mode changed! {} -> {}", old_mode, new_mode); + self.vram_obj_tiles_start = if new_dispcnt.mode() >= 3 { + VRAM_OBJ_TILES_START_BITMAP + } else { + VRAM_OBJ_TILES_START_TEXT + }; + } + self.dispcnt = new_dispcnt; + } + pub fn skip_bios(&mut self) { for i in 0..2 { self.bg_aff[i].pa = 0x100; @@ -543,12 +565,7 @@ impl Bus for Gpu { if ofs > 0x18000 { ofs -= 0x8000; } - let obj_offset = if self.dispcnt.mode() >= 3 { - 0x14000 - } else { - 0x10000 - }; - if ofs < obj_offset { + if ofs < self.vram_obj_tiles_start { self.vram.write_16(ofs & !1, expand_value(value)); } } diff --git a/rustboyadvance-core/src/gpu/render/obj.rs b/rustboyadvance-core/src/gpu/render/obj.rs index 296084d..205a1a4 100644 --- a/rustboyadvance-core/src/gpu/render/obj.rs +++ b/rustboyadvance-core/src/gpu/render/obj.rs @@ -98,6 +98,9 @@ impl Gpu { } let tile_base = OVRAM - VRAM_ADDR + 0x20 * (attrs.2.tile() as u32); + if tile_base < self.vram_obj_tiles_start { + return; + } let (tile_size, pixel_format) = attrs.tile_format(); let palette_bank = match pixel_format { @@ -191,6 +194,9 @@ impl Gpu { } let tile_base = OVRAM - VRAM_ADDR + 0x20 * (attrs.2.tile() as u32); + if tile_base < self.vram_obj_tiles_start { + return; + } let (tile_size, pixel_format) = attrs.tile_format(); let palette_bank = match pixel_format { diff --git a/rustboyadvance-core/src/iodev.rs b/rustboyadvance-core/src/iodev.rs index 70ba1b6..5eea3f8 100644 --- a/rustboyadvance-core/src/iodev.rs +++ b/rustboyadvance-core/src/iodev.rs @@ -161,7 +161,7 @@ impl Bus for IoDevices { } match io_addr { - REG_DISPCNT => io.gpu.dispcnt.0 = value, + REG_DISPCNT => io.gpu.write_dispcnt(value), REG_DISPSTAT => io.gpu.dispstat.0 = value | (io.gpu.dispstat.0 & 7), REG_BG0CNT => io.gpu.backgrounds[0].bgcnt.0 = value, REG_BG1CNT => io.gpu.backgrounds[1].bgcnt.0 = value,