280. Paletas de fondo a partir de la RAM de paletas
Construir paletas de fondo RGB a partir de bytes de la RAM de paletas de la PPU.
Lección 280 de 356 · tests/chapter_05_rendering_pipeline/test_280_background_palettes_from_palette_ram.py
Referencia
https://www.nesdev.org/wiki/PPU_palettes#Palette_RAMArchivo a crear
emulator/rendering/palette_ram.pyPor qué existe este paso
El renderizador de nametable consciente de atributos espera cuatro paletas de fondo RGB ya resueltas:
background_palettes[palette_id][color_index]Pero los juegos reales de la NES no almacenan colores RGB en el nametable ni en la tabla de atributos. Escriben índices de color de la NES en la RAM de paletas de la PPU.
Este ayudante convierte
PPU palette RAM bytes -> RGB background palettes¿Qué es la RAM de paletas de la PPU?
La RAM de paletas de la PPU es una pequeña área de 32 bytes mapeada en
$3F00-$3F1FPara este paso solo usamos los primeros 16 bytes
$3F00-$3F0F = background palette areaEsos bytes almacenan índices de color de la NES $00-$3F, no valores RGB.
Flujo
palette RAM byte
-> NES color index $00-$3F
-> get_nes_rgb_color(index)
-> RGB tupleColor de respaldo / de fondo universal
Para el renderizado de fondo, el índice de color 0 usa el color de respaldo compartido en $3F00.
Así que cada paleta de fondo devuelta usa el mismo primer color RGB
background_palettes[0][0] == backdrop
background_palettes[1][0] == backdrop
background_palettes[2][0] == backdrop
background_palettes[3][0] == backdropDiseño de paleta de fondo para $3F00-$3F0F:
$3F00 -> backdrop / universal background color
palette 0:
entry 0 -> $3F00
entry 1 -> $3F01
entry 2 -> $3F02
entry 3 -> $3F03
palette 1:
entry 0 -> $3F00
entry 1 -> $3F05
entry 2 -> $3F06
entry 3 -> $3F07
palette 2:
entry 0 -> $3F00
entry 1 -> $3F09
entry 2 -> $3F0A
entry 3 -> $3F0B
palette 3:
entry 0 -> $3F00
entry 1 -> $3F0D
entry 2 -> $3F0E
entry 3 -> $3F0FObserva
$3F04, $3F08, and $3F0C are not used as independent background color-0
entries in this simplified helper. Color index 0 uses the shared backdrop.Ejemplo de implementación sugerida
from emulator.rendering.framebuffer import RGBColor
from emulator.rendering.nes_palette import get_nes_rgb_color
PALETTE_RAM_SIZE = 16
TOTAL_PALETTES = 4
COLORS_PER_PALETTE = 4
BackgroundPalettes = list[list[RGBColor]]
def build_background_palettes_from_palette_ram(
palette_ram: bytes,
) -> BackgroundPalettes:
if len(palette_ram) != PALETTE_RAM_SIZE:
raise ValueError(f"Background palette RAM must be {PALETTE_RAM_SIZE} bytes")
backdrop_color = get_nes_rgb_color(palette_ram[0])
background_palettes = []
for palette_id in range(TOTAL_PALETTES):
base = palette_id * COLORS_PER_PALETTE
palette = [
backdrop_color,
get_nes_rgb_color(palette_ram[base + 1]),
get_nes_rgb_color(palette_ram[base + 2]),
get_nes_rgb_color(palette_ram[base + 3]),
]
background_palettes.append(palette)
return background_palettesFuera de alcance
- paletas de sprites
- comportamiento de transparencia de sprites
- espejado de la RAM de paletas
- lectura directa desde el bus de la PPU
- colores de énfasis de PPUMASK
- pantalla de pygame
Ejecutar esta lección
uv run pytest tests/chapter_05_rendering_pipeline/test_280_background_palettes_from_palette_ram.py -v