chore: simplify 4bpp palette code
This commit is contained in:
parent
c907552864
commit
8f5d054195
37
src/ppu.zig
37
src/ppu.zig
|
@ -183,26 +183,20 @@ pub const Ppu = struct {
|
||||||
const tile_row_offset: u32 = if (is_8bpp) 8 else 4;
|
const tile_row_offset: u32 = if (is_8bpp) 8 else 4;
|
||||||
const tile_len: u32 = if (is_8bpp) 0x40 else 0x20;
|
const tile_len: u32 = if (is_8bpp) 0x40 else 0x20;
|
||||||
|
|
||||||
const row = tile_y % 8;
|
const row = tile_y & 7;
|
||||||
const col = tile_x % 8;
|
const col = @truncate(u3, tile_x);
|
||||||
|
|
||||||
// When calcualting the inital address, the first entry is always 0x20 * tile_id, even if it is 8bpp
|
// When calcualting the inital address, the first entry is always 0x20 * tile_id, even if it is 8bpp
|
||||||
const tile_base = char_base + (0x20 * @as(u32, tile_id)) + (tile_row_offset * row) + if (is_8bpp) col else col / 2;
|
const tile_base = char_base + (0x20 * @as(u32, tile_id)) + (tile_row_offset * row) + if (is_8bpp) col else col >> 1;
|
||||||
|
|
||||||
// TODO: Finish that 2D Sprites Test ROM
|
// TODO: Finish that 2D Sprites Test ROM
|
||||||
const offset_base = (tile_x / 8) * tile_len;
|
const offset_base = (tile_x >> 3) * tile_len;
|
||||||
const offset_offset = (tile_y / 8) * tile_len * if (self.dispcnt.obj_mapping.read()) sprite.width / 8 else if (is_8bpp) @as(u32, 0x10) else 0x20;
|
const offset_offset = (tile_y >> 3) * tile_len * if (self.dispcnt.obj_mapping.read()) sprite.width >> 3 else if (is_8bpp) @as(u32, 0x10) else 0x20;
|
||||||
|
|
||||||
const tile_offset = offset_base + offset_offset;
|
const tile_offset = offset_base + offset_offset;
|
||||||
const tile = self.vram.buf[tile_base + tile_offset];
|
const tile = self.vram.buf[tile_base + tile_offset];
|
||||||
|
|
||||||
const pal_id: u16 = if (!is_8bpp) blk: {
|
const pal_id: u16 = if (!is_8bpp) get4bppTilePalette(sprite.pal_bank(), col, tile) else tile;
|
||||||
const nybble_tile = if (col & 1 == 1) tile >> 4 else tile & 0xF;
|
|
||||||
if (nybble_tile == 0) break :blk 0;
|
|
||||||
|
|
||||||
const pal_bank = @as(u8, sprite.pal_bank()) << 4;
|
|
||||||
break :blk pal_bank | nybble_tile;
|
|
||||||
} else tile;
|
|
||||||
|
|
||||||
// Sprite Palette starts at 0x0500_0200
|
// Sprite Palette starts at 0x0500_0200
|
||||||
if (pal_id != 0) self.scanline_buf[@bitCast(u9, x)] = self.palette.read(u16, 0x200 + pal_id * 2);
|
if (pal_id != 0) self.scanline_buf[@bitCast(u9, x)] = self.palette.read(u16, 0x200 + pal_id * 2);
|
||||||
|
@ -252,24 +246,25 @@ pub const Ppu = struct {
|
||||||
// Calculate on which column in a tile we're on
|
// Calculate on which column in a tile we're on
|
||||||
// Similarly to when we calculated the row, if we're in 4bpp we want to account
|
// Similarly to when we calculated the row, if we're in 4bpp we want to account
|
||||||
// for 1 byte consisting of two pixels
|
// for 1 byte consisting of two pixels
|
||||||
const col = if (entry.h_flip.read()) 7 - (x % 8) else x % 8;
|
const col = @truncate(u3, x) ^ if (entry.h_flip.read()) 7 else @as(u3, 0);
|
||||||
const tile = self.vram.buf[tile_addr + if (is_8bpp) col else col / 2];
|
const tile = self.vram.buf[tile_addr + if (is_8bpp) col else col >> 1];
|
||||||
|
|
||||||
// If we're in 8bpp, then the tile value is an index into the palette,
|
// If we're in 8bpp, then the tile value is an index into the palette,
|
||||||
// If we're in 4bpp, we have to account for a pal bank value in the Screen entry
|
// If we're in 4bpp, we have to account for a pal bank value in the Screen entry
|
||||||
// and then we can index the palette
|
// and then we can index the palette
|
||||||
const pal_id: u16 = if (!is_8bpp) blk: {
|
const pal_id: u16 = if (!is_8bpp) get4bppTilePalette(entry.pal_bank.read(), col, tile) else tile;
|
||||||
const nybble_tile = if (col & 1 == 1) tile >> 4 else tile & 0xF;
|
|
||||||
if (nybble_tile == 0) break :blk 0;
|
|
||||||
|
|
||||||
const pal_bank = @as(u8, entry.pal_bank.read()) << 4;
|
|
||||||
break :blk pal_bank | nybble_tile;
|
|
||||||
} else tile;
|
|
||||||
|
|
||||||
if (pal_id != 0) self.scanline_buf[i] = self.palette.read(u16, pal_id * 2);
|
if (pal_id != 0) self.scanline_buf[i] = self.palette.read(u16, pal_id * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fn get4bppTilePalette(pal_bank: u4, col: u3, tile: u8) u8 {
|
||||||
|
const nybble_tile = tile >> ((col & 1) << 2) & 0xF;
|
||||||
|
if (nybble_tile == 0) return 0;
|
||||||
|
|
||||||
|
return (@as(u8, pal_bank) << 4) | nybble_tile;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn drawScanline(self: *Self) void {
|
pub fn drawScanline(self: *Self) void {
|
||||||
const bg_mode = self.dispcnt.bg_mode.read();
|
const bg_mode = self.dispcnt.bg_mode.read();
|
||||||
const bg_enable = self.dispcnt.bg_enable.read();
|
const bg_enable = self.dispcnt.bg_enable.read();
|
||||||
|
|
Loading…
Reference in New Issue