From fda447031a4314542b0cd5183826ddc46f97204e Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Wed, 29 Oct 2025 06:42:02 +0100 Subject: smb 3041fps, life force 2058fps --- mknes_ppu.c | 164 ++++++++++++++++++------------------------------------------ 1 file changed, 49 insertions(+), 115 deletions(-) diff --git a/mknes_ppu.c b/mknes_ppu.c index 249f9f9..b00e380 100644 --- a/mknes_ppu.c +++ b/mknes_ppu.c @@ -279,132 +279,75 @@ static void ppu_tick(struct nes_state *state) { if(rendering) { if(scanline <= 239) { - if(dot >= 1 && dot <= 256) { - if(dot == 256) { - if((ppu->vram_addr & 0x7000) != 0x7000) { - ppu->vram_addr += 0x1000; + if(dot >= 1 && dot < 256) { // NOTE(peter): dot 256 will be done in the next else in the chain + ppu_render_pixel(state, dot - 1, scanline, reg_mask); + goto shift_and_fetch; + + } else if(dot == 256) { + if((ppu->vram_addr & 0x7000) != 0x7000) { + ppu->vram_addr += 0x1000; + } else { + + ppu->vram_addr &= ~0x7000; + uint32_t y = (ppu->vram_addr & 0x03e0) >> 5; + if(y == 29) { + y = 0; + ppu->vram_addr ^= 0x0800; + } else if(y == 31) { + y = 0; } else { - - ppu->vram_addr &= ~0x7000; - uint32_t y = (ppu->vram_addr & 0x03e0) >> 5; - if(y == 29) { - y = 0; - ppu->vram_addr ^= 0x0800; - } else if(y == 31) { - y = 0; - } else { - y++; - } - ppu->vram_addr = (ppu->vram_addr & ~0x03e0) | (y << 5); + y++; } + ppu->vram_addr = (ppu->vram_addr & ~0x03e0) | (y << 5); } - ppu_render_pixel(state, dot - 1, scanline, reg_mask); - goto stupid; - } + goto shift_and_fetch; - if(dot == 257) { + } else if(dot == 257) { ppu->vram_addr = (ppu->vram_addr & ~0x041f) | (ppu->temp_addr & 0x041f); ppu_evaluate_sprites(state, scanline); - } - - if(dot >= 321 && dot <= 336) { -stupid: if(reg_mask & PPU_MASK_SHOW_SPRITES) { - for(uint32_t i = 0; i < ppu->sprite_count; i++) { - if(ppu->sprites[i].position > 0) { - ppu->sprites[i].position--; - } else { - ppu->sprites[i].shift_lo <<= 1; - ppu->sprites[i].shift_hi <<= 1; - } - } - } - - ppu->bg_shift_pattern_low <<= 1; - ppu->bg_shift_pattern_high <<= 1; - ppu->bg_shift_attrib_low <<= 1; - ppu->bg_shift_attrib_high <<= 1; - switch(dot % 8) { - case 1: { - uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff); - ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, nt_addr); - } break; - - case 3: { - uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07); - uint8_t attr = state->mapper_function.ciram_read(state, attr_addr & 0x0fff); - uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2); - ppu->bg_next_tile_attrib = (attr >> shift) & 3; - } break; - - case 5: { - uint32_t base = (ppu->reg_ctrl & PPU_CTRL_BG_TILE_SELECT) << 8; - uint32_t tile = ppu->bg_next_tile_id; - uint32_t fine_y = (ppu->vram_addr >> 12) & 7; - uint32_t addr_lsb = (base + tile * 16 + fine_y) & 0x1fff; - ppu->bg_next_tile_lsb = state->mapper_function.chr_read(state, addr_lsb); - } break; + } else if(dot >= 321 && dot <= 336) { + goto shift_and_fetch; - case 7: { - uint32_t base = (ppu->reg_ctrl & PPU_CTRL_BG_TILE_SELECT) << 8; - uint32_t tile = ppu->bg_next_tile_id; - uint32_t fine_y = (ppu->vram_addr >> 12) & 7; - uint32_t addr_msb = (base + tile * 16 + fine_y + 8) & 0x1fff; - ppu->bg_next_tile_msb = state->mapper_function.chr_read(state, addr_msb); - } break; - - case 0: { - ppu->bg_shift_pattern_low = (ppu->bg_shift_pattern_low) | ppu->bg_next_tile_lsb; - ppu->bg_shift_pattern_high = (ppu->bg_shift_pattern_high) | ppu->bg_next_tile_msb; - - uint8_t a = ppu->bg_next_tile_attrib; - ppu->bg_shift_attrib_low = (ppu->bg_shift_attrib_low) | ((a & 1) ? 0xff : 0x00); - ppu->bg_shift_attrib_high = (ppu->bg_shift_attrib_high) | ((a & 2) ? 0xff : 0x00); - - if((ppu->vram_addr & 0x001f) == 31) { - ppu->vram_addr &= ~0x001f; - ppu->vram_addr ^= 0x0400; - } else { - ppu->vram_addr++; - } - } break; - } - } - - if(dot == 340) { + } else if(dot == 340) { ppu_fetch_sprite_patterns(state, scanline); } - } if(scanline == 261) { - if(dot >= 1 && dot <= 256) { - if(dot == 256) { - if((ppu->vram_addr & 0x7000) != 0x7000) { - ppu->vram_addr += 0x1000; + if(dot >= 1 && dot < 256) { // NOTE(peter): dot 256 will be done in the next else in the chain + goto shift_and_fetch; + + } else if(dot == 256) { + if((ppu->vram_addr & 0x7000) != 0x7000) { + ppu->vram_addr += 0x1000; + } else { + + ppu->vram_addr &= ~0x7000; + uint32_t y = (ppu->vram_addr & 0x03e0) >> 5; + if(y == 29) { + y = 0; + ppu->vram_addr ^= 0x0800; + } else if(y == 31) { + y = 0; } else { - - ppu->vram_addr &= ~0x7000; - uint32_t y = (ppu->vram_addr & 0x03e0) >> 5; - if(y == 29) { - y = 0; - ppu->vram_addr ^= 0x0800; - } else if(y == 31) { - y = 0; - } else { - y++; - } - ppu->vram_addr = (ppu->vram_addr & ~0x03e0) | (y << 5); + y++; } + ppu->vram_addr = (ppu->vram_addr & ~0x03e0) | (y << 5); } + goto shift_and_fetch; - goto stupid2; - } + } else if(dot == 257) { + ppu->vram_addr = (ppu->vram_addr & ~0x041f) | (ppu->temp_addr & 0x041f); + + } else if(dot >= 280 && dot <= 304) { + ppu->vram_addr = (ppu->vram_addr & ~0x7be0) | (ppu->temp_addr & 0x7be0); - if(dot >= 321 && dot <= 336) { -stupid2: if(reg_mask & PPU_MASK_SHOW_SPRITES) { + } else if(dot >= 321 && dot <= 336) { +shift_and_fetch: + if(reg_mask & PPU_MASK_SHOW_SPRITES) { for(uint32_t i = 0; i < ppu->sprite_count; i++) { if(ppu->sprites[i].position > 0) { ppu->sprites[i].position--; @@ -420,7 +363,6 @@ stupid2: if(reg_mask & PPU_MASK_SHOW_SPRITES) { ppu->bg_shift_attrib_low <<= 1; ppu->bg_shift_attrib_high <<= 1; - switch(dot % 8) { case 1: { uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff); @@ -467,14 +409,6 @@ stupid2: if(reg_mask & PPU_MASK_SHOW_SPRITES) { } break; } } - - if(dot == 257) { - ppu->vram_addr = (ppu->vram_addr & ~0x041f) | (ppu->temp_addr & 0x041f); - } - - if(dot >= 280 && dot <= 304) { - ppu->vram_addr = (ppu->vram_addr & ~0x7be0) | (ppu->temp_addr & 0x7be0); - } } } -- cgit v1.2.3