303. Paletas de sprite desde la RAM de paleta

Construir paletas de sprite a partir de los bytes de la RAM de paleta de la PPU.

Lección 303 de 356 · tests/chapter_09_sprite_rendering/test_303_sprite_palettes_from_palette_ram.py

Archivo a actualizar

emulator/rendering/palette_ram.py

Por qué existe este paso

Antes de renderizar píxeles de sprite, necesitamos convertir los bytes de la RAM de paleta de sprite en paletas RGB. La RAM de paleta de sprite reside en el rango de direcciones de paleta de la PPU:

$3F10-$3F1F

Este helper recibe esos 16 bytes y devuelve cuatro paletas RGB de sprite.

Referencias

https://www.nesdev.org/wiki/PPU_palettes#Palette_RAM

Terminología importante

CHR color index
    The 2-bit pixel value decoded from CHR tile data: 0, 1, 2, or 3.

PPU palette RAM byte
    A runtime NES color index, usually $00-$3F.

RGB color
    The emulator's display color tuple from NES_PALETTE_RGB.

Forma de la paleta de sprite

palette 0 uses bytes 0, 1, 2, 3
palette 1 uses bytes 4, 5, 6, 7
palette 2 uses bytes 8, 9, 10, 11
palette 3 uses bytes 12, 13, 14, 15

Ejemplo de implementación sugerido

SpritePalettes = list[list[RGBColor]]


def build_sprite_palettes_from_palette_ram(palette_ram: bytes) -> SpritePalettes:
    if len(palette_ram) != PALETTE_RAM_SIZE:
        raise ValueError(f"Sprite palette RAM must be {PALETTE_RAM_SIZE} bytes")

    sprite_palettes = []

    for palette_id in range(TOTAL_PALETTES):
        base = palette_id * COLORS_PER_PALETTE

        palette = [
            get_nes_rgb_color(palette_ram[base]),
            get_nes_rgb_color(palette_ram[base + 1]),
            get_nes_rgb_color(palette_ram[base + 2]),
            get_nes_rgb_color(palette_ram[base + 3]),
        ]

        sprite_palettes.append(palette)

    return sprite_palettes

Regla importante de transparencia de sprites

El índice de color CHR 0 de un sprite es transparente durante el renderizado. Este helper no aplica transparencia. Solo convierte bytes de la RAM de paleta a colores RGB. El renderizador de sprites posterior decidirá:

if sprite_color_index == 0:
    skip drawing this pixel

Concepto erróneo frecuente

"Sprite palette entry 0 should be removed from the palette helper."

No. Mantener cuatro entradas. El renderizador necesita indexación estable 0..3, aunque el índice 0 signifique transparente al dibujar píxeles de sprite.

Fuera del alcance

  • renderizado de píxeles de sprite
  • aplicación de transparencia
  • prioridad de sprites
  • volteo de sprites
  • sprite 0 hit
  • sprite overflow
  • pygame

Ejecutar esta lección

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