311. Thread background opaque mask through sprite pipeline
Thread the background opacity mask through the sprite rendering pipeline.
Lesson 311 of 356 · tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py
Files to update
emulator/rendering/frame_compositor.py
emulator/rendering/sprite_renderer.pyWhy this step exists
Step 310 created a BackgroundOpaqueMask. Before we apply sprite priority behavior, we first make the relevant functions accept and forward that mask.
This keeps the tutorial incremental
Step 310 -> build the mask
Step 311 -> thread the mask through function signatures
Step 312 -> use the mask to enforce sprite priority bit 5Required API shape
def composite_background_and_sprites(
background: Framebuffer,
oam: bytes | bytearray,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> Framebuffer:
...
render_oam_sprites_to_framebuffer(
framebuffer,
oam,
pattern_table,
sprite_palettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask,
)
...
def render_oam_sprites_to_framebuffer(
framebuffer: Framebuffer,
oam: bytes | bytearray,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
...
render_sprite_8x8_to_framebuffer(
framebuffer,
sprite,
pattern_table,
sprite_palettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask,
)
def render_sprite_8x8_to_framebuffer(
framebuffer: Framebuffer,
sprite: SpriteEntry,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
...Also add the type import where needed
# --- ADD THIS NEW LINE ---
from emulator.rendering.nametable_renderer import BackgroundOpaqueMaskImportant
This step does not require using the mask yet. The next step will add the rule:
if sprite is behind background and background_opaque_mask[pixel] is True:
skip drawing this sprite pixelWhy optional None? Older tests and older tutorial steps already call these rendering helpers without a background mask. Keeping the argument optional preserves backward compatibility while we evolve the pipeline.
Out of scope
- applying sprite priority bit 5
- changing Console.render_framebuffer()
- building the mask from PPU state
- sprite 0 hit
- sprite overflow
- pygame
Run this lesson
uv run pytest tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py -v