258. Build pattern table debug grid

Implement a pattern table debug grid.

Lesson 258 of 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_258_build_pattern_table_debug_grid.py

Reference

https://www.nesdev.org/wiki/PPU_pattern_tables

File to update

emulator/ppu/chr_decoder.py

Function to implement

build_pattern_table_debug_grid(decoded_tiles: PatternTable) -> PatternTableDebugGrid

Constants to add

PATTERN_TABLE_TILES_PER_ROW = 16
CHR_TILE_WIDTH = 8
CHR_TILE_HEIGHT = 8
PATTERN_TABLE_DEBUG_GRID_SIZE = 128

What this step does

Previous tests decoded one pattern table into 256 separate 8x8 tiles. This step arranges those tiles into one 128x128 grid of color indexes.

Layout

16 tiles across
16 tiles down
each tile is 8x8 pixels
16 * 8 = 128 pixels

Examples

tile 0   -> top-left,     x=0,   y=0
tile 1   -> right of it,  x=8,   y=0
tile 16  -> next row,     x=0,   y=8
tile 255 -> bottom-right, x=120, y=120

Suggested implementation example

def build_pattern_table_debug_grid(decoded_tiles: PatternTable) -> PatternTableDebugGrid:
    if len(decoded_tiles) != PATTERN_TABLE_TILE_COUNT:
        raise ValueError("Pattern table debug grid requires 256 decoded tiles")

    grid = [
        [0 for _ in range(PATTERN_TABLE_DEBUG_GRID_SIZE)]
        for _ in range(PATTERN_TABLE_DEBUG_GRID_SIZE)
    ]

    for tile_index, tile in enumerate(decoded_tiles):
        tile_x = (tile_index % PATTERN_TABLE_TILES_PER_ROW) * CHR_TILE_WIDTH
        tile_y = (tile_index // PATTERN_TABLE_TILES_PER_ROW) * CHR_TILE_HEIGHT

        for row in range(CHR_TILE_HEIGHT):
            for col in range(CHR_TILE_WIDTH):
                grid[tile_y + row][tile_x + col] = tile[row][col]

    return grid

Synthetic data note

This test uses a tiny synthetic pattern table generated inside the test file.

Out of scope

  • file generation
  • image output
  • RGB/NES palette colors
  • nametable background rendering
  • PPU timing

Run this lesson

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_258_build_pattern_table_debug_grid.py -v