diff --git a/src/gpu/oam_search.rs b/src/gpu/oam_search.rs index bb78522..81a8f83 100644 --- a/src/gpu/oam_search.rs +++ b/src/gpu/oam_search.rs @@ -11,7 +11,9 @@ impl GameBoy { self.gpu.y = 0; self.gpu.sprites.clear(); - for i in (0xFE00..0xFE9C).step_by(4) { + // We access sprites in reverse because the sprite with the lowest address has + // the most priority + for i in (0xFE00..0xFE9C).rev().step_by(4) { self.gpu.sprites.push(self.get_sprite_data(i)); } } @@ -20,10 +22,10 @@ impl GameBoy { } fn get_sprite_data(&self, address: u16) -> SpriteData { - let y = self.bus[address]; - let x = self.bus[address + 1]; - let tile_number = self.bus[address + 2]; - let flags = self.bus[address + 3]; + let y = self.bus[address - 3]; + let x = self.bus[address - 2]; + let tile_number = self.bus[address - 1]; + let flags = self.bus[address]; SpriteData { y, diff --git a/src/gpu/pixel_transfer/sprite.rs b/src/gpu/pixel_transfer/sprite.rs index 83ab83d..91ec9c6 100644 --- a/src/gpu/pixel_transfer/sprite.rs +++ b/src/gpu/pixel_transfer/sprite.rs @@ -78,7 +78,10 @@ impl Layer for SpriteLayer { render_bottom_tall_sprite(&mut sprite_to_draw); } - self.sprite_to_draw = Some(sprite_to_draw); + self.sprite_to_draw = Some(match self.sprite_to_draw { + Some(existing_sprite) => sprite_priority(existing_sprite, sprite_to_draw), + None => sprite_to_draw, + }); } } } @@ -180,6 +183,15 @@ fn render_bottom_tall_sprite(sprite: &mut SpriteData) { }; } +/// Returns the sprite with the highest priority +fn sprite_priority(sprite1: SpriteData, sprite2: SpriteData) -> SpriteData { + if sprite1.x < sprite2.x { + return sprite1; + } + + sprite2 +} + #[derive(Clone, Copy)] pub(crate) struct SpriteData { pub(crate) y: u8,