255. Decodificador de tiles CHR

Implementa un decodificador de tiles CHR.

Lección 255 de 356 · tests/chapter_03_ppu_memory_and_graphics_data/test_255_chr_tile_decoder.py

Referencia

https://www.nesdev.org/wiki/PPU_pattern_tables

Archivo a crear

emulator/ppu/chr_decoder.py

Función a implementar

decode_chr_tile(tile_bytes: bytes) -> list[list[int]]

¿Qué es un tile CHR? Un tile CHR es un tile gráfico de 8x8 almacenado como 16 bytes.

No almacena colores RGB finales. Almacena índices de color de 2 bits:

0, 1, 2, or 3

Esos índices se combinarán más adelante con la RAM de paleta para elegir los colores reales de la NES.

Disposición de bytes de un tile CHR

bytes 0-7   -> low bitplane, one byte per row
bytes 8-15  -> high bitplane, one byte per row

Para cada fila

low_byte  = tile_bytes[row]
high_byte = tile_bytes[row + 8]

Para cada columna, lee los bits de izquierda a derecha

column 0 -> bit 7
column 1 -> bit 6
...
column 7 -> bit 0

Ejemplo de implementación sugerida

def decode_chr_tile(tile_bytes: bytes) -> list[list[int]]:
    if len(tile_bytes) != 16:
        raise ValueError("To decode CHR tile, tile must be 16 bytes")

    rows = []

    for row in range(8):
        low_byte = tile_bytes[row]
        high_byte = tile_bytes[row + 8]
        columns = []

        for col in range(8):
            bit_position = 7 - col

            low = (low_byte >> bit_position) & 1
            high = (high_byte >> bit_position) & 1

            pixel = (high << 1) | low
            columns.append(pixel)

        rows.append(columns)

    return rows

Fuera de alcance

  • renderizado de la tabla de patrones
  • colores RGB/paleta de la NES
  • renderizado de fondo de nametable
  • renderizado de sprites
  • temporización de la PPU

Ejecutar esta lección

uv run pytest tests/chapter_03_ppu_memory_and_graphics_data/test_255_chr_tile_decoder.py -v