303. Sprite palettes from palette ram
Build sprite palettes from PPU palette RAM bytes.
Lesson 303 of 356 · tests/chapter_09_sprite_rendering/test_303_sprite_palettes_from_palette_ram.py
File to update
emulator/rendering/palette_ram.pyWhy this step exists
Before rendering sprite pixels, we need to convert sprite palette RAM bytes into RGB palettes. Sprite palette RAM lives in the PPU palette address range:
$3F10-$3F1FThis helper receives those 16 bytes and returns four RGB sprite palettes.
References
https://www.nesdev.org/wiki/PPU_palettes#Palette_RAMImportant terminology
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.Sprite palette shape
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, 15Suggested implementation example
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_palettesImportant sprite transparency rule
Sprite CHR color index 0 is transparent during rendering. This helper does not apply transparency. It only converts palette RAM bytes to RGB colors. The later sprite renderer will decide:
if sprite_color_index == 0:
skip drawing this pixelCommon misconception
"Sprite palette entry 0 should be removed from the palette helper."No. Keep four entries. The renderer needs stable indexing 0..3, even though index 0 means transparent when drawing sprite pixels.
Out of scope
- rendering sprite pixels
- applying transparency
- sprite priority
- sprite flipping
- sprite 0 hit
- sprite overflow
- pygame
Run this lesson
uv run pytest tests/chapter_09_sprite_rendering/test_303_sprite_palettes_from_palette_ram.py -v