334. Преобразование области просмотра фона Ppu во фреймбуфер

Составить горизонтальный фреймбуфер фона из текущего состояния прокрутки PPU.

Урок 334 из 356 · tests/chapter_13_scrolling/test_334_ppu_background_viewport_to_framebuffer.py

Файл для обновления

emulator/rendering/ppu_background_renderer.py

Справочные материалы

https://www.nesdev.org/wiki/PPU_scrolling
https://www.nesdev.org/wiki/PPU_nametables

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

Предыдущие шаги позволяют отрисовывать одну выбранную логическую таблицу имён и составлять два существующих фреймбуфера. Этот адаптер связывает эти механизмы с текущим состоянием прокрутки PPU.

Горизонтальный поток выполнения

temp_vram_addr + fine_x
          |
          v
    decode viewport X
          |
          v
select horizontal logical pair
          |
          v
render left and right nametables
          |
          v
compose one 256x240 framebuffer

Выбор логической пары

nametable Y = 0 -> left $2000, right $2400
nametable Y = 1 -> left $2800, right $2C00

Nametable X остаётся частью декодированного X области просмотра. Например, nametable X=1, coarse X=5 и fine X=3 дают X области просмотра 299.

Совместимость

Существующая функция ppu_background_to_framebuffer() продолжает отрисовывать одну выбранную таблицу имён. Этот новый адаптер вызывает её дважды, а затем составляет результаты.

Вне объёма работ

  • составление маски непрозрачности
  • интеграция Console
  • интеграция попадания нулевого спрайта
  • вертикальная попиксельная прокрутка
  • pygame

Полный пример реализации

# emulator/rendering/ppu_background_renderer.py

# --- NEW LINES: HORIZONTAL VIEWPORT OPERATIONS ---
from emulator.rendering.background_viewport import (
    compose_horizontal_framebuffer_viewport,
    compose_horizontal_opaque_mask_viewport,
    decode_background_viewport_position,
)

...

# --- NEW BLOCK: COMPOSE THE HORIZONTAL FRAMEBUFFER VIEWPORT ---
def ppu_background_viewport_to_framebuffer(ppu: PPU) -> Framebuffer:
    viewport_x, _ = decode_background_viewport_position(
        temp_vram_addr=ppu.temp_vram_addr,
        fine_x=ppu.fine_x,
    )

    nametable_y = (ppu.temp_vram_addr >> 11) & 1
    left_base = BASE_NAMETABLE_ADDR + nametable_y * 0x0800
    right_base = left_base + 0x0400

    left = ppu_background_to_framebuffer(
        ppu,
        base_nametable_addr=left_base,
    )
    right = ppu_background_to_framebuffer(
        ppu,
        base_nametable_addr=right_base,
    )

    return compose_horizontal_framebuffer_viewport(
        left=left,
        right=right,
        viewport_x=viewport_x,
    )

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

uv run pytest tests/chapter_13_scrolling/test_334_ppu_background_viewport_to_framebuffer.py -v