From c4a2a1a8651c0b1199404704f69d6e36a559a9a3 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 11 Mar 2022 22:40:47 -0400 Subject: [PATCH] fix: resolve issues with sprite mirroring --- src/ppu.zig | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/ppu.zig b/src/ppu.zig index 3740dfd..b98a3e3 100644 --- a/src/ppu.zig +++ b/src/ppu.zig @@ -142,57 +142,31 @@ pub const Ppu = struct { } else break; } - // // TODO: Scanning OAM for every single pixel is insanely expensive - // // This should be done once per scanline (and then check for X bounds every pixel) - // var j: u32 = 0; - // while (j < self.oam.buf.len) : (j += 8) { - // // Attributes in OAM are 6 bytes long, with 2 bytes of padding - // // Grab Attributes from OAM - // const attr0 = @bitCast(Attr0, self.oam.get16(j)); - // const attr1 = @bitCast(Attr1, self.oam.get16(j + 2)); - // const attr2 = @bitCast(Attr2, self.oam.get16(j + 4)); - - // // Only consider enabled sprites on the current priority - // if (attr0.disabled.read() or attr2.rel_prio.read() != prio) continue; - - // // Determine sprite bounds - // const d = spriteDimensions(attr0.shape.read(), attr1.size.read()); - // const sy = attr0.y.read(); - // const sx = attr1.x.read(); - // const sx_end = sx + d[0]; - // const sy_end = sy + d[1]; - - // // If sprite is in range - // if (sy < y and sy_end > y and sx < x and sx_end > x) { - // maybe_sprite = Sprite.init(attr0, attr1, attr2); - // break; - // } - // } - // If we didn't find a sprite, progress to the next pixel const sprite: Sprite = if (maybe_sprite) |s| s else continue; const is_8bpp = sprite.is_8bpp(); // Y and X coordinates within the context of a singular 8x8 tile - const tile_y = y - sprite.y(); - const tile_x = x - sprite.x(); + const tile_y: u16 = (y - sprite.y()) ^ if (sprite.v_flip()) (sprite.height - 1) else 0; + const tile_x = (x - sprite.x()) ^ if (sprite.h_flip()) (sprite.width - 1) else 0; const tile_id: u32 = sprite.tile_id(); const tile_row_offset: u32 = if (is_8bpp) 8 else 4; const tile_len: u32 = if (is_8bpp) 0x40 else 0x20; - const row = if (sprite.v_flip()) 7 - (tile_y % 8) else tile_y % 8; - const col = if (sprite.h_flip()) 7 - (tile_x % 8) else tile_x % 8; + const row = tile_y % 8; + const col = tile_x % 8; const tile_base: u32 = char_base + (0x20 * tile_id) + (tile_row_offset * row) + if (is_8bpp) col else col / 2; - var tile_offset = (tile_x >> 3) * tile_len; + var tile_offset = (tile_x / 8) * tile_len; if (self.dispcnt.obj_mapping.read()) { // One Dimensional - tile_offset += (tile_y / 8) * tile_len * (sprite.width >> 3); + tile_offset += (tile_y / 8) * tile_len * (sprite.width / 8); } else { // Two Dimensional - tile_offset += (@as(u32, tile_y) >> 3) * tile_len * 0x20; + // TODO: This doesn't work + tile_offset += (tile_y / 8) * tile_len * 0x20; } const tile = self.vram.buf[tile_base + tile_offset];