281. 带调色板 RAM 的名称表

使用属性表和 PPU 调色板 RAM 字节渲染名称表背景。

281 / 356 · tests/chapter_05_rendering_pipeline/test_281_nametable_with_palette_ram.py

待更新文件

emulator/rendering/nametable_renderer.py

为什么需要这一步

前面的步骤已经分别构建了各个组成部分

attribute table
    -> palette ID for each tile coordinate

palette RAM bytes
    -> four RGB background palettes

nametable + attributes + background palettes
    -> framebuffer

这一步将这些部分组合成一个纯渲染辅助函数

nametable_with_palette_ram_to_framebuffer(
    nametable_bytes,
    attribute_table,
    pattern_table_bytes,
    palette_ram,
)

它应该做什么

background_palettes = build_background_palettes_from_palette_ram(palette_ram)

return nametable_with_attributes_to_framebuffer(
    nametable_bytes,
    attribute_table,
    pattern_table_bytes,
    background_palettes,
)

为什么这有用

这个辅助函数接受更接近真实 PPU 渲染输入形态的数据,同时保持完全可测试:

nametable visible tile bytes
attribute table bytes
pattern table CHR bytes
background palette RAM bytes

依然是纯数据

没有 PPU 总线读取,没有 pygame,没有窗口,没有帧循环。

重要的硬件模型

CHR pixel color index 0-3
    -> attribute table selects background palette ID 0-3
    -> palette RAM selects NES color index $00-$3F
    -> NES RGB palette converts to RGB
    -> framebuffer pixel

建议的实现示例

from emulator.rendering.palette_ram import build_background_palettes_from_palette_ram


def nametable_with_palette_ram_to_framebuffer(
    nametable_bytes: bytes,
    attribute_table: bytes,
    pattern_table_bytes: bytes,
    palette_ram: bytes,
) -> Framebuffer:
    background_palettes = build_background_palettes_from_palette_ram(palette_ram)

    return nametable_with_attributes_to_framebuffer(
        nametable_bytes,
        attribute_table,
        pattern_table_bytes,
        background_palettes,
    )

范围之外

  • 从 PPU 总线读取名称表/调色板字节
  • 调色板 RAM 镜像
  • 滚动
  • 精灵
  • OAMDMA
  • pygame 显示

运行本课

uv run pytest tests/chapter_05_rendering_pipeline/test_281_nametable_with_palette_ram.py -v