272. Color index grid to framebuffer
Convert color-index grids into RGB framebuffer data.
Lesson 272 of 356 · tests/chapter_05_rendering_pipeline/test_272_color_index_grid_to_framebuffer.py
File to create
emulator/rendering/color_index_renderer.pyWhy this step exists
Earlier PPU/CHR helpers produce color indexes, not RGB pixels. For example, decode_chr_tile() produces values like:
0, 1, 2, 3Those values are palette indexes. They are not directly displayable colors yet.
This step creates a pure rendering helper that maps
color-index grid + RGB palette -> FramebufferWhat is a color-index grid? A color-index grid is a 2D grid where each number points into a palette.
Minimal example
grid = [
[0, 1, 1, 0, ...],
[2, 3, 3, 0, ...],
...
]
palette = [
(0, 0, 0),
(85, 85, 85),
(170, 170, 170),
(255, 255, 255),
]Expected framebuffer pixels
(x=0, y=0) -> palette[0] -> (0, 0, 0)
(x=1, y=0) -> palette[1] -> (85, 85, 85)
(x=0, y=1) -> palette[2] -> (170, 170, 170)
(x=1, y=1) -> palette[3] -> (255, 255, 255)Suggested implementation example
from emulator.rendering.framebuffer import Framebuffer, RGBColor
Grid = list[list[int]]
def color_index_grid_to_framebuffer(
grid: Grid,
palette: list[RGBColor],
) -> Framebuffer:
height = len(grid)
width = len(grid[0])
framebuffer = Framebuffer(width=width, height=height)
for y, row in enumerate(grid):
for x, color_index in enumerate(row):
framebuffer.set_pixel(x, y, palette[color_index])
return framebufferImportant simplification
For now, assume valid input
grid is not empty
grid is rectangular
palette contains every used index
color indexes are validFuture validations can be added later if this becomes a debugging problem.
Architecture rule
This helper is pure data transformation. It should not import pygame, CPU, PPU timing, ROM loading, or frontend code.
Out of scope
- NES palette memory lookup
- rendering CHR tiles directly
- rendering pattern tables directly
- rendering nametables/backgrounds
- pygame display
Run this lesson
uv run pytest tests/chapter_05_rendering_pipeline/test_272_color_index_grid_to_framebuffer.py -v