⚠️ Clean-Room / Educativo

Este proyecto es educativo y Open Source. No se copia código de otros emuladores. Implementación basada únicamente en documentación técnica y tests permitidas.

Step 0255 - Inspector OAM y Paletas

Fecha: 2025-12-23 Step ID: 0255 Estado: Draft

Resumen

Este Step extiende el monitor GPS (Step 0240) en src/viboy.py para incluir inspección en tiempo real de los registros de paleta (BGP, OBP0, OBP1) y los primeros sprites de la OAM (Object Attribute Memory). El objetivo es diagnosticar por qué la pantalla aparece verde/blanca cuando debería mostrar sprites, verificando si el problema está en los datos (OAM vacía o DMA no funcionando) o en el renderizado (paletas incorrectas).

Concepto de Hardware

En la Game Boy, los sprites (objetos) se almacenan en la OAM (Object Attribute Memory), ubicada en el rango 0xFE00-0xFE9F (160 bytes = 40 sprites × 4 bytes). Cada sprite ocupa 4 bytes consecutivos:

  • Byte 0 (Y): Posición vertical (0-255, pero Y=0 o Y≥160 oculta el sprite)
  • Byte 1 (X): Posición horizontal (0-255, pero X=0 o X≥168 oculta el sprite)
  • Byte 2 (Tile): Índice del tile en VRAM (0-255)
  • Byte 3 (Attributes): Atributos (paleta, flip X/Y, prioridad, etc.)

Los registros de paleta controlan cómo se traducen los colores de los tiles:

  • BGP (0xFF47): Paleta del Background (4 colores: 00, 01, 10, 11)
  • OBP0 (0xFF48): Paleta de Sprites (canal 0, colores 1-3; color 0 es transparente)
  • OBP1 (0xFF49): Paleta de Sprites (canal 1, colores 1-3; color 0 es transparente)

Problema crítico: Si OBP0 o OBP1 están en 0x00 o 0xFF (todos blancos o todos transparentes), los sprites serán invisibles incluso si están correctamente renderizados. Si la OAM está vacía (todos ceros), la DMA no está funcionando o el juego no ha inicializado los sprites aún.

Fuente: Pan Docs - OAM (Object Attribute Memory), Sprite Attributes, Palette Registers

Implementación

Se modificó el bloque del monitor GPS en src/viboy.py (líneas 944-976) para añadir lectura de registros de paleta y los primeros 2 sprites de la OAM. La inspección se ejecuta cada segundo (60 frames) junto con el reporte GPS estándar.

Componentes modificados

  • src/viboy.py: Extendido el bloque GPS (Step 0240) con inspección de OAM y paletas

Lógica de inspección

El código lee:

  • Paletas: 0xFF47 (BGP), 0xFF48 (OBP0), 0xFF49 (OBP1)
  • Sprite 0: 0xFE00-0xFE03 (Y, X, Tile, Attributes)
  • Sprite 1: 0xFE04-0xFE07 (Y, X, Tile, Attributes)

Los valores se registran usando logger.info() con formato hexadecimal para facilitar el diagnóstico. El formato es:

[VIDEO] BGP:XX OBP0:XX OBP1:XX | LCDC:XX
[SPRITE 0] Y:XX X:XX T:XX A:XX
[SPRITE 1] Y:XX X:XX T:XX A:XX

Escenarios de diagnóstico:

  • OAM vacía (Y:00 X:00 T:00): La DMA no está copiando datos o la memoria se borra
  • OAM con datos válidos (Y:10 X:08 T:5A): Los sprites están presentes. Si no se ven, el problema está en el renderizado C++ o en las paletas
  • Paletas en 0x00 o 0xFF: Los sprites serán invisibles (blancos o transparentes)

Archivos Afectados

  • src/viboy.py - Extendido el monitor GPS con inspección de OAM y paletas (Step 0255)

Tests y Verificación

Este Step no requiere tests unitarios, ya que es una herramienta de diagnóstico en tiempo real. La validación se realiza ejecutando el emulador y observando los logs:

  • Comando: python main.py roms/pkmn.gb (o cualquier ROM con sprites)
  • Observación: Los logs [VIDEO] y [SPRITE] aparecen cada segundo en la consola
  • Validación: Verificar que los valores de OAM y paletas sean coherentes con el estado del juego

Nota: Este Step no modifica el núcleo C++, solo añade instrumentación en Python para diagnóstico. No se requiere recompilación de C++.

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • OAM Structure: Cada sprite ocupa 4 bytes consecutivos (Y, X, Tile, Attributes) en el rango 0xFE00-0xFE9F
  • Palette Registers: BGP controla el fondo, OBP0/OBP1 controlan los sprites. Si están en 0x00 o 0xFF, los sprites serán invisibles
  • Diagnóstico: La inspección de OAM y paletas permite distinguir entre problemas de datos (OAM vacía) y problemas de renderizado (paletas incorrectas)

Lo que Falta Confirmar

  • DMA Timing: Verificar que la DMA se ejecuta frecuentemente y no se borra la OAM entre frames
  • Sprite Visibility: Confirmar que los sprites con Y=0 o X=0 se ocultan correctamente en el renderizado
  • Palette Mapping: Verificar que el renderizado C++ respeta correctamente los valores de OBP0/OBP1

Hipótesis y Suposiciones

Hipótesis principal: Si la pantalla aparece verde/blanca con sprites implementados, el problema más probable es que las paletas OBP0/OBP1 estén en 0x00 (todos transparentes) o que la OAM esté vacía (DMA no funcionando o juego aún inicializando).

Esta herramienta de diagnóstico permitirá confirmar o refutar esta hipótesis observando los valores reales en tiempo de ejecución.

Próximos Pasos

  • [ ] Ejecutar el emulador con una ROM (Pokémon Red, Mario) y observar los logs de OAM y paletas
  • [ ] Analizar los valores reportados para determinar si el problema es de datos (OAM vacía) o renderizado (paletas incorrectas)
  • [ ] Si OAM está vacía: Investigar la DMA y verificar que se ejecuta frecuentemente
  • [ ] Si OAM tiene datos pero sprites invisibles: Verificar el renderizado C++ y el mapeo de paletas
  • [ ] Corregir el problema identificado y validar que los sprites se muestran correctamente