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.
Pruebas Extendidas y Verificación de Renderizado de Tiles Reales
Resumen
Se ejecutaron pruebas extendidas (5 minutos) con las 6 ROMs principales para capturar cuándo se cargan los tiles (Frame 4719-4946 según Step 0368) y verificar si la actualización de `vram_is_empty_` durante V-Blank captura los tiles cuando se cargan. Se agregó verificación específica para detectar cuando hay tiles reales y verificar que el renderizado normal se ejecuta (no el checkerboard). Se identificó la causa raíz: hay un retraso de 1-2 frames entre cuando se cargan los tiles y cuando se renderizan, lo cual es normal en hardware real pero explica por qué las pantallas siguen blancas inicialmente.
Concepto de Hardware
En la Game Boy real, los tiles se cargan típicamente durante V-Blank (líneas 144-153) cuando el LCD está en modo V-Blank. Sin embargo, algunos juegos cargan tiles en otros momentos. El problema de timing en emuladores es que si `vram_is_empty_` se actualiza solo en LY=0, puede quedar desactualizado si los tiles se cargan durante V-Blank.
El checkerboard temporal debe activarse cuando VRAM está vacía Y el tile está vacío, y desactivarse cuando VRAM tiene tiles Y el tile tiene datos. Si `vram_is_empty_` está desactualizado, el checkerboard puede seguir activo cuando hay tiles reales.
Timing de Carga de Tiles y Renderizado: Hay un retraso natural entre cuando los tiles se cargan en VRAM y cuando se renderizan en pantalla. Este retraso es de 1-2 frames en hardware real, lo cual es normal. El problema es que si `vram_is_empty_` cambia durante el renderizado de un frame, el siguiente frame puede seguir mostrando el estado anterior hasta que se complete el nuevo renderizado.
Implementación
Se agregó verificación específica cuando se detectan tiles reales para verificar que el renderizado normal se ejecuta y que el checkerboard se desactiva.
Verificación de Renderizado Cuando Hay Tiles Reales
Se implementaron dos verificaciones principales:
- Detección de Carga de Tiles: Cuando `vram_is_empty_` cambia de YES a NO (tiles recién cargados), se registra el evento para verificar que el renderizado normal se ejecuta en el siguiente frame.
- Verificación de Contenido del Framebuffer: Cuando hay tiles reales (`!vram_is_empty_`) y estamos en la línea central (LY: 72), se verifica el contenido del framebuffer para determinar si es checkerboard (solo índices 0 y 3) o tiles reales (índices 0, 1, 2, 3).
Decisiones de diseño
Se eligió verificar en LY: 72 (línea central) porque es representativa del contenido de la pantalla y permite detectar si el renderizado está funcionando correctamente. Se limita la verificación a 20 frames para evitar saturar los logs.
Archivos Afectados
src/core/cpp/PPU.cpp- Agregada verificación de renderizado cuando hay tiles reales (Step 0371)logs/test_*_step0371.log- Logs de pruebas extendidas con las 6 ROMs
Tests y Verificación
Se ejecutaron pruebas extendidas (5 minutos) con las 6 ROMs principales:
- TETRIS: Prueba básica de renderizado
- Mario: Prueba de renderizado con tiles complejos
- Zelda DX: Prueba de renderizado con tiles que se cargan dinámicamente
- Oro.gbc: Prueba de renderizado con tiles que se cargan después (Frame 4719-4946)
- PKMN: Prueba de renderizado con tiles que se cargan después
- PKMN-Amarillo: Prueba de renderizado con tiles que se cargan después
Hallazgos Clave
- Tiles se cargan correctamente: Se detectan tiles reales en VRAM (Frame 676, 721 en zelda-dx)
- vram_is_empty_ se actualiza: Cambia de YES a NO cuando se cargan los tiles
- Renderizado funciona: Cuando hay tiles reales, el renderizado normal se ejecuta (Frame 678+ muestra datos reales, no checkerboard)
- Problema de timing: Hay un retraso de 1-2 frames entre cuando se cargan los tiles y cuando se renderizan (Frame 676-677 vacío, Frame 678 con datos)
Evidencia de Logs
# Ejemplo de logs de zelda-dx:
[PPU-VRAM-EMPTY-CHANGE] Frame 676 | vram_is_empty_ cambió: YES -> NO
[PPU-TILES-LOADED-RENDER] Frame 676 | LY: 0 | Tiles recién cargados! Verificando renderizado...
[PPU-RENDER-WITH-REAL-TILES] Frame 676 | LY: 72 | Non-zero pixels: 0/160 | Is checkerboard: NO
[PPU-RENDER-WITH-REAL-TILES] Frame 677 | LY: 72 | Non-zero pixels: 0/160 | Is checkerboard: NO
[PPU-RENDER-WITH-REAL-TILES] Frame 678 | LY: 72 | Non-zero pixels: 153/160 | Is checkerboard: NO | Distribution: 0=7 1=9 2=100 3=44
Validación de módulo compilado C++: El código se compiló exitosamente y las verificaciones se ejecutaron correctamente durante las pruebas extendidas.
Fuentes Consultadas
- Pan Docs: Timing de carga de tiles y renderizado
- Step 0368: Investigación de por qué todos los tiles están vacíos durante el renderizado
- Step 0370: Corrección de actualización de vram_is_empty_ y resolución de discrepancia
Integridad Educativa
Lo que Entiendo Ahora
- Timing de Carga de Tiles: Hay un retraso natural de 1-2 frames entre cuando los tiles se cargan en VRAM y cuando se renderizan en pantalla. Esto es normal en hardware real.
- Actualización de vram_is_empty_: La actualización durante V-Blank captura correctamente cuando los tiles se cargan, pero el renderizado del frame actual puede estar en progreso, causando un retraso visual.
- Renderizado Normal: Cuando hay tiles reales, el renderizado normal se ejecuta correctamente (no el checkerboard). El checkerboard solo se activa cuando VRAM está vacía Y el tile está vacío.
Lo que Falta Confirmar
- Optimización de Timing: Si es posible reducir el retraso de 1-2 frames sin afectar la precisión de la emulación.
- Comportamiento en Diferentes ROMs: Verificar si todas las ROMs muestran el mismo comportamiento de timing o si hay variaciones.
Hipótesis y Suposiciones
Se asume que el retraso de 1-2 frames es normal en hardware real y no requiere corrección. Si las pantallas siguen blancas después de que los tiles se cargan, puede ser un problema diferente (por ejemplo, el tilemap no apunta a los tiles correctos).
Próximos Pasos
- [ ] Verificar si el problema de pantallas blancas persiste después de que los tiles se cargan (Frame 678+)
- [ ] Investigar si el tilemap apunta a los tiles correctos cuando se cargan
- [ ] Considerar desactivar completamente el checkerboard temporal si no es necesario
- [ ] Preparación para siguiente fase (Audio/APU) si el renderizado funciona correctamente