NES TDD

308. Отрисовка фреймбуфера в Console

Предоставить из Console полный фреймбуфер с фоном и спрайтами.

Урок 308 из 356 · tests/chapter_09_sprite_rendering/test_308_console_render_framebuffer.py

Изменяемый файл

emulator/console.py

Зачем нужен этот шаг

Фронтенды не должны знать, как извлекать по отдельности память фона, OAM спрайтов, палитровую RAM спрайтов или таблицы шаблонов спрайтов. Console координирует системы CPU/PPU, поэтому она должна предоставить один метод для фронтендов:

console.render_framebuffer()

Этот метод возвращает текущий видимый фреймбуфер, используя

background renderer
PPU.oam sprites
sprite palette RAM $3F10-$3F1F
sprite pattern table selected by PPUCTRL bit 3

Предлагаемый пример реализации

# Add this constant to the existing ppu_background_renderer import.
from emulator.rendering.ppu_background_renderer import PALETTE_RAM_ADDR


def render_framebuffer(self) -> Framebuffer:
    background = self.render_background_framebuffer()

    sprite_palette_start = PALETTE_RAM_ADDR + 16
    sprite_palette_ram = bytes(
        self.ppu.ppu_bus.read(sprite_palette_start + offset)
        for offset in range(16)
    )
    sprite_palettes = build_sprite_palettes_from_palette_ram(sprite_palette_ram)

    pattern_table_base = (
        PATTERN_TABLE_1_ADDR
        if self.ppu.ctrl & CTRL_SPRITE_PATTERN_TABLE
        else PATTERN_TABLE_0_ADDR
    )

    pattern_table = bytes(
        self.ppu.ppu_bus.read(pattern_table_base + offset)
        for offset in range(0x1000)
    )

    return composite_background_and_sprites(
        background=background,
        oam=self.ppu.oam,
        pattern_table=pattern_table,
        sprite_palettes=sprite_palettes,
    )

Важная граница

Console может вызывать чистые вспомогательные функции отрисовки. Console не должна импортировать pygame.

Вне рамок этого шага

  • попадание спрайта 0
  • переполнение спрайтов
  • спрайты 8x16
  • поведение бита приоритета спрайт/фон
  • отображение через pygame

Запустить этот урок

uv run pytest tests/chapter_09_sprite_rendering/test_308_console_render_framebuffer.py -v