300. Decode sprite entry
Decode one sprite entry from OAM bytes.
Lesson 300 of 356 · tests/chapter_09_sprite_rendering/test_300_decode_sprite_entry.py
File to update
emulator/rendering/sprite_renderer.pyWhy this step exists
The previous step defined SpriteEntry. Now we add the small decoder that converts raw PPU OAM bytes into one SpriteEntry.
Raw OAM layout
sprite 0 -> bytes 0, 1, 2, 3
sprite 1 -> bytes 4, 5, 6, 7
...
sprite 63 -> bytes 252, 253, 254, 255Suggested implementation example
def decode_sprite_entry(oam: bytes | bytearray, sprite_index: int) -> SpriteEntry:
if len(oam) < OAM_SIZE:
raise ValueError("OAM must contain 256 bytes")
if not 0 <= sprite_index < OAM_SPRITE_COUNT:
raise ValueError("sprite_index must be in range 0..63")
base = sprite_index * BYTES_PER_SPRITE
return SpriteEntry(
y=oam[base],
tile_index=oam[base + 1],
attributes=oam[base + 2],
x=oam[base + 3],
)Important NES detail
The raw Y byte has special rendering semantics on real hardware. Sprites appear one scanline below the stored Y value. Do not adjust it in this decoder. This function returns raw OAM data only.
Out of scope
- sprite attribute bit decoding
- sprite palettes
- rendering pixels
- sprite 0 hit
- sprite overflow
- pygame
Run this lesson
uv run pytest tests/chapter_09_sprite_rendering/test_300_decode_sprite_entry.py -v