NES TDD

313. Построение маски непрозрачности фона PPU

Строим маску непрозрачности фона из текущей фоновой памяти PPU.

Урок 313 из 356 · tests/chapter_09_sprite_rendering/test_313_ppu_background_to_opaque_mask.py

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

emulator/rendering/ppu_background_renderer.py

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

Шаг 310 добавил чистую вспомогательную функцию

build_background_opaque_mask(pattern_table, nametable)

Эта функция работает с сырыми байтами. Этот шаг добавляет её аналог на уровне PPU для:

ppu_background_to_framebuffer(ppu)

Новая вспомогательная функция должна быть

ppu_background_to_opaque_mask(ppu)

Она очень похожа на ppu_background_to_framebuffer(), но ей требуется меньше информации.

ppu_background_to_framebuffer() требуется:

  • видимые байты nametable
  • байты таблицы атрибутов
  • байты выбранной таблицы фоновых паттернов
  • байты палитровой RAM

потому что она формирует RGB-пиксели.

ppu_background_to_opaque_mask() требуется только:

  • видимые байты nametable
  • байты выбранной таблицы фоновых паттернов

потому что непрозрачность зависит только от:

CHR color index != 0

Таблица атрибутов и палитровая RAM не влияют на непрозрачность.

Пример реализации

def ppu_background_to_opaque_mask(ppu: PPU) -> BackgroundOpaqueMask:
    nametable_bytes = bytes(
        ppu.ppu_bus.read(BASE_NAMETABLE_ADDR + offset)
        for offset in range(NAMETABLE_SIZE)
    )

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

    pattern_table_bytes = bytes(
        ppu.ppu_bus.read(pattern_table_base + offset)
        for offset in range(PATTERN_TABLE_SIZE)
    )

    return build_background_opaque_mask(
        pattern_table=pattern_table_bytes,
        nametable=nametable_bytes,
    )

Важно

Этот шаг пока не изменяет Console.render_framebuffer(). Следующий шаг подключит Console к вызову этой функции и передаче маски в компоновщик.

Вне рамок

  • изменение emulator/console.py
  • передача маски в composite_background_and_sprites()
  • sprite 0 hit
  • переполнение спрайтов
  • pygame

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

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