From 412b2ef851516c1de8ba5006ddd284192cbcaf9b Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Sun, 8 Jun 2025 17:32:05 +0200 Subject: tests --- ppu.c | 75 +++++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) (limited to 'ppu.c') diff --git a/ppu.c b/ppu.c index e0fce44..3b6200e 100644 --- a/ppu.c +++ b/ppu.c @@ -60,20 +60,23 @@ static inline void ppu_evaluate_sprites(struct nes_state *state) { __attribute__((hot)) static inline void ppu_fetch_sprite_patterns(struct nes_state *state) { struct ppu_state *restrict ppu = &state->ppu; - uint32_t addr; - uint32_t bank; - uint8_t lsb; - uint8_t msb; uint8_t * restrict s = ppu->secondary_oam; uint8_t height = (ppu->reg_ctrl & 0x20) ? 16 : 8; + uint8_t ctrl = ppu->reg_ctrl; + uint8_t scanline = ppu->scanline; + uint32_t sprite_pattern_table_base = (ctrl & 0x08) << 9; for(uint8_t i = 0; i < ppu->sprite_count; i++) { - uint8_t y = s[0], tile = s[1], attr = s[2], x = s[3]; - uint8_t row = ppu->scanline - y; + uint8_t y = s[0]; + uint8_t tile = s[1]; + uint8_t attr = s[2]; + uint8_t x = s[3]; + uint8_t row = scanline - y; row = (attr & 0x80) ? height - 1 - row : row; + uint32_t bank, addr; if(height == 16) { bank = (tile & 1) << 12; tile &= 0xfe; @@ -81,29 +84,29 @@ static inline void ppu_fetch_sprite_patterns(struct nes_state *state) { tile++; row -= 8; } - } else { - bank = (ppu->reg_ctrl & 0x08) << 9; - } - addr = bank + tile * 16 + row; + addr = bank + tile * 16 + row; - if(attr & 0x40) { - lsb = ppu_bitreverse_lut[state->mapper_function.chr_read(state, addr)]; - msb = ppu_bitreverse_lut[state->mapper_function.chr_read(state, addr + 8)]; } else { - lsb = state->mapper_function.chr_read(state, addr); - msb = state->mapper_function.chr_read(state, addr + 8); + addr = sprite_pattern_table_base + tile * 16 + row; } + uint8_t val_lo = state->mapper_function.chr_read(state, addr); + uint8_t val_hi = state->mapper_function.chr_read(state, addr + 8); + + uint8_t rev = -(!!(attr & 0x40)); + uint8_t lsb = (rev & ppu_bitreverse_lut[val_lo]) | (~rev & val_lo); + uint8_t msb = (rev & ppu_bitreverse_lut[val_hi]) | (~rev & val_hi); + ppu->sprite_shift_lo[i] = lsb; ppu->sprite_shift_hi[i] = msb; - ppu->sprite_positions[i] = x; ppu->sprite_priorities[i] = attr & 0x20; + s += 4; } } -__attribute__((always_inline, hot, flatten)) +__attribute__((always_inline, hot)) static inline void ppu_render_pixel(struct nes_state *state) { struct ppu_state *restrict ppu = &state->ppu; @@ -112,8 +115,6 @@ static inline void ppu_render_pixel(struct nes_state *state) { uint16_t bit = 0x8000 >> ppu->fine_x; - uint8_t bg_pixel = 0; - uint8_t bg_palette = 0; uint8_t sp_pixel = 0; uint8_t sp_palette = 0; uint8_t sp_prio = 0; @@ -133,23 +134,25 @@ static inline void ppu_render_pixel(struct nes_state *state) { uint8_t a0 = !!(ppu->bg_shift_attrib_low & bit); uint8_t a1 = !!(ppu->bg_shift_attrib_high & bit); - bg_pixel = ((p1 << 1) | p0) & bg_mask; - bg_palette = ((a1 << 1) | a0) & bg_mask; + uint8_t bg_pixel = ((p1 << 1) | p0) & bg_mask; + uint8_t bg_palette = ((a1 << 1) | a0) & bg_mask; // Sprite - for(uint8_t i = 0; i < ppu->sprite_count; i++) { - if(ppu->sprite_positions[i]) continue; + if(sp_mask) { + for(uint8_t i = 0; i < ppu->sprite_count; i++) { + if(ppu->sprite_positions[i]) continue; - uint8_t lo = ppu->sprite_shift_lo[i]; - uint8_t hi = ppu->sprite_shift_hi[i]; - sp_pixel = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7)) & sp_mask; + uint8_t lo = ppu->sprite_shift_lo[i]; + uint8_t hi = ppu->sprite_shift_hi[i]; + sp_pixel = (((hi & 0x80) >> 6) | ((lo & 0x80) >> 7)); - if(!sp_pixel) continue; + if(!sp_pixel) continue; - sp_palette = ppu->secondary_oam[i * 4 + 2] & 3; - sp_prio = ppu->sprite_priorities[i]; - sp_zero = (ppu->sprite_indexes[i] == 0); - break; + sp_palette = ppu->secondary_oam[i * 4 + 2] & 3; + sp_prio = ppu->sprite_priorities[i]; + sp_zero = (ppu->sprite_indexes[i] == 0); + break; + } } // Final pixel composition @@ -170,8 +173,8 @@ static inline void ppu_render_pixel(struct nes_state *state) { state->pixels[y * 256 + x] = ppu->palette[palette_index]; // NOTE(peter): Add color_emphasis bits (expand palette to 8x). } -__attribute__((hot, flatten)) -__attribute__((optimize("no-jump-tables"))) + +__attribute__((hot, optimize("no-jump-tables"))) static inline void ppu_tick(struct nes_state *state) { struct ppu_state *restrict ppu = &state->ppu; @@ -208,10 +211,10 @@ static inline void ppu_tick(struct nes_state *state) { case 1 ... 255: // fallthrough: this is 1->256 ppu_render_pixel(state); - __attribute__((fallthrough)); + __attribute__((fallthrough)); // fallthrough: the code below has to run 1->256 + 321->336 + + case 321 ... 336: { // Rendering and tile fetch; - case 321 ... 336: { // fallthrough: the code below has to run 1->256 + 321->336 - // Rendering and tile fetch goes here if(ppu->reg_mask & 0x10) { for(uint32_t i = 0; i < ppu->sprite_count; i++) { if(ppu->sprite_positions[i] > 0) { -- cgit v1.2.3