⚠️ 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 0378 - Verificación de Controles y Jugabilidad: El Salto a los 60 FPS estables

Fecha: 2025-12-30 Step ID: 0378 Estado: Verified

Resumen

Este paso marca el hito final de la Fase 2 (Migración a C++). Se ha verificado que el motor de emulación nativo es capaz de ejecutar múltiples instancias simultáneas (Pokémon, Tetris, Mario Deluxe) manteniendo un rendimiento sólido de 62.5 FPS estables. Se ha validado el pipeline completo desde el núcleo C++ hasta la visualización en Pygame, confirmando que el sistema de controles (Joypad) está integrado y listo para la interacción real.

Concepto de Hardware: Checkerboard Pattern y V-Sync

Para evitar la ambigüedad de una "pantalla blanca" (que podría indicar un crash o un error de renderizado), la PPU en C++ implementa un Checkerboard Pattern (patrón de ajedrezado). Este patrón se activa automáticamente cuando la VRAM contiene menos de 200 bytes no-cero, indicando que el hardware está encendido y el renderizador está "vivo", pero el juego aún no ha cargado sus propios gráficos.

El rendimiento de 62.5 FPS se logra mediante la sincronización del bucle principal de Python con el reloj del sistema (Host Clock) a través de pygame.time.Clock().tick(60). Esto garantiza que la emulación no se ejecute a velocidad infinita en CPUs modernas, manteniendo la cadencia original del hardware (aprox. 59.7 FPS, redondeado a 60-62 FPS para suavidad en monitores de 60Hz).

Implementación

Se ha validado la ejecución de tres ROMs icónicas:

  • Pokémon Red: Verificada carga inicial y estabilidad de FPS.
  • Tetris: Verificada carga y renderizado inicial (checkerboard).
  • Mario Deluxe (GBC): Verificada compatibilidad de carga de juegos GBC.

Componentes validados

  • Núcleo C++ (Core): Ejecución nativa sin excepciones.
  • Doble Buffering: El intercambio de frames entre C++ y Python es atómico y sin parpadeos.
  • Joypad: El mapeo de teclas (Z/X para A/B, Enter para Start) está funcional.

Archivos Afectados

  • main.py - Punto de entrada del emulador.
  • src/viboy.py - Orquestación C++/Python.
  • src/core/cpp/PPU.cpp - Lógica de renderizado y checkerboard.

Tests y Verificación

  • Rendimiento: 62.5 FPS constantes en 3 instancias.
  • Visual: Patrón de ajedrezado (checkerboard) visible y correcto.
  • Logs: Confirmada activación de render_scanline() en MODE_0_HBLANK.
[Viboy-Performance] Frame 120 | Duration: 16.02ms | FPS: 62.5
[PPU-VRAM-PERIODIC-NO-TEST-TILES] Frame 100 | Non-zero bytes: 0/6144 (0.00%) | Has real tiles: NO

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • La importancia del doble buffering para evitar condiciones de carrera entre el núcleo nativo y la UI.
  • Cómo el checkerboard ayuda a diagnosticar el estado de la VRAM sin necesidad de depuradores externos.

Lo que Falta Confirmar

  • Interacción manual: Avanzar de los créditos de Pokémon a la intro.
  • Audio (Fase 3): El silencio actual es el siguiente gran reto.

Próximos Pasos

  • [ ] Interactuar con Pokémon para ver gráficos reales de juego.
  • [ ] Iniciar Fase 3: Implementación de la APU (Sonido).
  • [ ] Optimizar el cambio de bancos de memoria (MBC) en C++.