270. Forma de datos del framebuffer

Crear la forma de datos pura del framebuffer para el pipeline de renderizado.

Lección 270 de 356 · tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py

Archivos a crear

emulator/rendering/
emulator/rendering/framebuffer.py

Por qué existe este paso

La fase 7 comienza definiendo la forma de datos que el núcleo del emulador producirá para la salida visual. Esto debe ser datos puros de Python, no datos específicos de pygame.

¿Qué es un framebuffer? Un framebuffer es un bloque de datos de píxeles que representa una imagen/fotograma completo.

Ejemplo mínimo

A 256x240 NES framebuffer contains:

    256 * 240 = 61440 pixels

Cada píxel se representa como una tupla RGB

    (red, green, blue)

Ejemplo

    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)

Concepto erróneo común

Framebuffer no significa ventana de pygame. El framebuffer son datos del núcleo del emulador. Pygame puede mostrarlo después, pero pygame no debería ser necesario para crear o probar el framebuffer.

Ejemplo de implementación sugerido

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")

Invariante importante

Después de la construcción

len(framebuffer.pixels) == framebuffer.width * framebuffer.height

Fuera de alcance

  • métodos get_pixel/set_pixel, probados en el siguiente paso
  • validación de coordenadas
  • validación de componentes RGB
  • conversión de índices de paleta NES a RGB
  • renderizado de datos CHR/nametable
  • visualización en pygame/frontend

Ejecutar esta lección

uv run pytest tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py -v