333. Nametable lógico de la PPU a máscara de opacidad

Construye una máscara de opacidad a partir de un nametable lógico seleccionado de la PPU.

Lección 333 de 356 · tests/chapter_13_scrolling/test_333_ppu_logical_nametable_to_opaque_mask.py

Archivo a actualizar

emulator/rendering/ppu_background_renderer.py

Referencia

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

Por qué existe este paso

La función auxiliar existente construye la máscara que usan la prioridad de sprites y la detección de sprite-zero-hit, pero originalmente solo lee el nametable lógico $2000. El desplazamiento horizontal también necesita la máscara perteneciente al nametable lógico adyacente.

Compatibilidad

Omitir base_nametable_addr sigue seleccionando $2000, por lo que el código llamante existente de Console y de sprite-zero hit sigue siendo válido hasta que la integración del viewport se realice deliberadamente.

Entradas de opacidad

  • 960 IDs de tile del nametable lógico seleccionado
  • la tabla de patrones de fondo seleccionada por el bit 4 de PPUCTRL

La opacidad no usa bytes de atributos, RAM de paleta ni colores RGB finales.

Fuera del alcance

  • componer las máscaras izquierda y derecha
  • renderizado de framebuffer
  • integración en Console
  • integración del viewport del sprite-zero-hit
  • desplazamiento vertical

Implementación de ejemplo completa

# emulator/rendering/ppu_background_renderer.py

def ppu_background_to_opaque_mask(
    ppu: PPU,
    # --- NEW LINE: OPTIONAL LOGICAL NAMETABLE SELECTION ---
    base_nametable_addr: int = BASE_NAMETABLE_ADDR,
) -> BackgroundOpaqueMask:
    # --- NEW BLOCK: REJECT NON-NAMETABLE BASE ADDRESSES ---
    if base_nametable_addr not in LOGICAL_NAMETABLE_BASE_ADDRS:
        raise ValueError(
            "Logical nametable base address must be $2000, $2400, $2800, $2C00"
        )

    nametable_bytes = bytes(
        # --- UPDATED LINE: READ FROM THE SELECTED NAMETABLE ---
        ppu.ppu_bus.read(base_nametable_addr + offset)
        for offset in range(NAMETABLE_SIZE)
    )

    ...
    # Everything remains the same below this point.

Ejecutar esta lección

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