270. Framebuffer data shape
Create the pure framebuffer data shape for the rendering pipeline.
Lesson 270 of 356 · tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py
Files to create
emulator/rendering/
emulator/rendering/framebuffer.pyWhy this step exists
Phase 7 starts by defining the data shape that the emulator core will produce for visual output. This should be pure Python data, not pygame-specific data.
What is a framebuffer? A framebuffer is a block of pixel data representing one complete image/frame.
Minimal example
A 256x240 NES framebuffer contains:
256 * 240 = 61440 pixelsEach pixel is represented as an RGB tuple
(red, green, blue)Example
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)Common misconception
Framebuffer does not mean pygame window. The framebuffer is core emulator data. Pygame can later display it, but pygame should not be required to create or test the framebuffer.
Suggested implementation example
from dataclasses import dataclass, field
RGBColor = tuple[int, int, int]
NES_SCREEN_WIDTH = 256
NES_SCREEN_HEIGHT = 240
BLACK: RGBColor = (0, 0, 0)
@dataclass
class Framebuffer:
width: int = NES_SCREEN_WIDTH
height: int = NES_SCREEN_HEIGHT
pixels: list[RGBColor] = field(default_factory=list)
def __post_init__(self) -> None:
if not self.pixels:
self.pixels = [BLACK] * (self.width * self.height)
if len(self.pixels) != self.width * self.height:
raise ValueError("Framebuffer pixel count must be equal width * height")Important invariant
After construction
len(framebuffer.pixels) == framebuffer.width * framebuffer.heightOut of scope
- get_pixel/set_pixel methods, tested in the next step
- coordinate validation
- RGB component validation
- converting NES palette indexes to RGB
- rendering CHR/nametable data
- pygame/frontend display
Run this lesson
uv run pytest tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py -v