258. 构建图案表调试网格

实现一个图案表调试网格。

258 / 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_258_build_pattern_table_debug_grid.py

参考资料

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

需要更新的文件

emulator/ppu/chr_decoder.py

需要实现的函数

build_pattern_table_debug_grid(decoded_tiles: PatternTable) -> PatternTableDebugGrid

需要添加的常量

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

本步骤的作用

之前的测试把一个图案表解码成了 256 个独立的 8x8 图块。这一步把这些图块排列成一个 128x128 的颜色索引网格。

布局

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

示例

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

建议的实现示例

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

关于合成数据的说明

这个测试使用的是在测试文件内部生成的一个微型合成图案表。

不在本步骤范围内

  • 文件生成
  • 图像输出
  • RGB/NES 调色板颜色
  • 名称表背景渲染
  • PPU 时序

运行本课

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