diff --git a/src/core/gpu/mod.rs b/src/core/gpu/mod.rs index 1b8b482..c0a94da 100644 --- a/src/core/gpu/mod.rs +++ b/src/core/gpu/mod.rs @@ -215,6 +215,7 @@ pub struct Gpu { pub bldy: u16, pub obj_line: Scanline, + pub obj_line_priorities: Scanline, pub frame_buffer: FrameBuffer, } @@ -238,6 +239,7 @@ impl Gpu { current_scanline: 0, cycles: 0, obj_line: Scanline::default(), + obj_line_priorities: Scanline([3; DISPLAY_WIDTH]), frame_buffer: FrameBuffer([0; DISPLAY_WIDTH * DISPLAY_HEIGHT]), } } diff --git a/src/core/gpu/obj.rs b/src/core/gpu/obj.rs index 6aabebe..3fafdc5 100644 --- a/src/core/gpu/obj.rs +++ b/src/core/gpu/obj.rs @@ -96,6 +96,7 @@ impl Gpu { let screen_y = self.current_scanline; // reset the scanline self.obj_line = Scanline::default(); + self.obj_line_priorities = Scanline([3; DISPLAY_WIDTH]); for obj_num in (0..128).rev() { let obj = read_obj_attrs(sb, obj_num); if obj.is_hidden() { @@ -140,6 +141,9 @@ impl Gpu { if screen_x > DISPLAY_WIDTH { break; } + if self.obj_line_priorities[screen_x] < obj.2.priority() { + continue; + } let mut sprite_y = screen_y - obj_y; let mut sprite_x = screen_x - obj_x; if (!is_affine) { @@ -169,8 +173,8 @@ impl Gpu { let pixel_color = self.get_palette_color(sb, pixel_index as u32, palette_bank, PALRAM_OFS_FG); if pixel_color != Rgb15::TRANSPARENT { - // TODO - handle priority self.obj_line[screen_x] = pixel_color; + self.obj_line_priorities[screen_x] = obj.2.priority(); } } } diff --git a/src/core/gpu/sfx.rs b/src/core/gpu/sfx.rs index 2bb7985..c06ccf9 100644 --- a/src/core/gpu/sfx.rs +++ b/src/core/gpu/sfx.rs @@ -47,12 +47,12 @@ impl Gpu { bflags: BlendFlags, wflags: WindowFlags, ) -> Option { - // TODO - only BGs are supported, don't forget OBJs // priorities are 0-4 when 0 is the highest 'outer: for priority in 0..4 { if bflags.contains(BlendFlags::OBJ) && wflags.contains(WindowFlags::OBJ) && !self.obj_line[screen_x].is_transparent() + && self.obj_line_priorities[screen_x] == priority { return Some(Layer { color: self.obj_line[screen_x],