313. Ppu background to opaque mask

Build a background opacity mask from current PPU background memory.

Lesson 313 of 356 · tests/chapter_09_sprite_rendering/test_313_ppu_background_to_opaque_mask.py

File to update

emulator/rendering/ppu_background_renderer.py

Why this step exists

Step 310 added the pure helper

build_background_opaque_mask(pattern_table, nametable)

That helper works from raw bytes. This step adds the PPU-level sibling of:

ppu_background_to_framebuffer(ppu)

The new helper should be

ppu_background_to_opaque_mask(ppu)

It is very similar to ppu_background_to_framebuffer(), but it needs less information.

ppu_background_to_framebuffer() needs:

  • visible nametable bytes
  • attribute table bytes
  • selected background pattern table bytes
  • palette RAM bytes

because it produces RGB pixels.

ppu_background_to_opaque_mask() only needs:

  • visible nametable bytes
  • selected background pattern table bytes

because opacity depends only on:

CHR color index != 0

Attribute table and palette RAM do not affect opacity.

Example implementation

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,
    )

Important

This step does not modify Console.render_framebuffer() yet. The next step will wire Console to call this helper and pass the mask to the compositor.

Out of scope

  • changing emulator/console.py
  • passing the mask to composite_background_and_sprites()
  • sprite 0 hit
  • sprite overflow
  • pygame

Run this lesson

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