⚠️ 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.

Investigación del Contenido del Framebuffer y Correspondencia Tilemap-Tiles

Fecha: 2025-12-29 Step ID: 0338 Estado: VERIFIED

Resumen

Investigación exhaustiva del contenido del framebuffer cuando hay tiles reales (no checkerboard) y verificación de la correspondencia entre el tilemap y los tiles en VRAM. Se implementaron logs de diagnóstico para verificar qué contiene el framebuffer cuando hay tiles reales, si el tilemap apunta a tiles con datos en VRAM, si los tiles se renderizan completamente, y si hay problemas con el scroll o offset. El objetivo es identificar por qué los tiles aparecen difusos o a medias cuando deberían mostrarse correctamente.

Concepto de Hardware

Framebuffer

El framebuffer contiene índices de color (0-3) para cada píxel de la pantalla. Tamaño: 160×144 = 23,040 píxeles. Cada píxel tiene un índice de color que se mapea a RGB mediante la paleta BGP. El framebuffer se genera línea por línea durante el renderizado de cada scanline.

Tilemap

El tilemap es un mapa de 32×32 tiles que apunta a tiles en VRAM. Cada entrada del tilemap contiene un tile ID (0-255). El tile ID se usa para calcular la dirección del tile en VRAM según el direccionamiento (signed o unsigned). El tilemap se lee durante el renderizado para determinar qué tile se debe dibujar en cada posición de pantalla.

Scroll

SCX (Scroll X) desplaza el background horizontalmente y SCY (Scroll Y) desplaza el background verticalmente. El scroll se aplica al calcular la posición en el tilemap. El scroll puede causar que solo parte de un tile sea visible, lo que requiere calcular correctamente el offset dentro del tile.

Fuente: Pan Docs - "Background", "Tile Map", "Scroll Registers (SCX/SCY)"

Implementación

Se implementaron 4 bloques de logs de diagnóstico en PPU::render_scanline() para investigar el contenido del framebuffer y la correspondencia tilemap-tiles cuando hay tiles reales.

1. Verificación del Contenido del Framebuffer con Tiles Reales

Se agregaron logs que verifican qué contiene el framebuffer cuando hay tiles reales (no checkerboard). Los logs se activan cuando vram_has_tiles es true y se ejecutan en la línea 72 (línea central de la pantalla).

  • Distribución de índices: Cuenta cuántos píxeles tienen cada índice de color (0, 1, 2, 3) en la línea 72
  • Píxeles específicos: Verifica algunos píxeles específicos (x=0, 40, 80, 120, 159) para ver qué índices contienen
  • Tag: [PPU-FRAMEBUFFER-CONTENT]

2. Verificación de Correspondencia Tilemap-Tiles

Se agregaron logs que verifican si el tilemap apunta a tiles con datos en VRAM. Los logs verifican los primeros 20 tiles visibles en la línea 72 y determinan si cada tile tiene datos o está vacío.

  • Tiles con datos: Cuenta cuántos tiles visibles tienen datos en VRAM
  • Tiles vacíos: Cuenta cuántos tiles visibles están vacíos (todas las líneas = 0x00)
  • Tiles inválidos: Cuenta cuántos tiles apuntan a direcciones fuera de VRAM
  • Tag: [PPU-TILEMAP-TILES]

3. Verificación de Renderizado Completo de Tiles

Se agregaron logs que verifican si los tiles se renderizan completamente (todas las líneas). Los logs verifican un tile específico (tile en posición (0, 0) del tilemap) y comparan los píxeles esperados con los píxeles renderizados en el framebuffer.

  • Píxeles renderizados: Cuenta cuántos píxeles del tile se renderizaron correctamente
  • Píxeles esperados: Debería ser 8 (un tile completo en una línea)
  • Tag: [PPU-TILE-RENDER-COMPLETE]

4. Verificación Detallada de Scroll y Offset

Se agregaron logs que verifican que el scroll y el offset se calculan correctamente. Los logs verifican algunos píxeles específicos y muestran cómo se calcula la posición en el tilemap con scroll.

  • Posición en tilemap: Muestra MapX y MapY calculados con scroll
  • Posición en tile: Muestra TileX, TileY y el offset dentro del tile (PixelInTileX, PixelInTileY)
  • Tag: [PPU-SCROLL-OFFSET]

Componentes creados/modificados

  • src/core/cpp/PPU.cpp: Agregados 4 bloques de logs de diagnóstico en render_scanline()

Archivos Afectados

  • src/core/cpp/PPU.cpp - Agregados logs de diagnóstico del Step 0338

Tests y Verificación

Los logs de diagnóstico se activarán automáticamente cuando se detecten tiles reales en VRAM. Para verificar los logs, se deben ejecutar las pruebas con las 5 ROMs durante 2.5 minutos cada una:

  • Comandos de prueba:
    timeout 150 python3 main.py roms/pkmn.gb 2>&1 | tee logs/test_pkmn_step0338.log
    timeout 150 python3 main.py roms/tetris.gb 2>&1 | tee logs/test_tetris_step0338.log
    timeout 150 python3 main.py roms/mario.gbc 2>&1 | tee logs/test_mario_step0338.log
    timeout 150 python3 main.py roms/pkmn-amarillo.gb 2>&1 | tee logs/test_pkmn_amarillo_step0338.log
    timeout 150 python3 main.py roms/Oro.gbc 2>&1 | tee logs/test_oro_step0338.log
  • Análisis de logs:
    # Verificar contenido del framebuffer con tiles reales
    grep "\[PPU-FRAMEBUFFER-CONTENT\]" logs/test_*_step0338.log | head -n 30
    
    # Verificar correspondencia tilemap-tiles
    grep "\[PPU-TILEMAP-TILES\]" logs/test_*_step0338.log | head -n 30
    
    # Verificar renderizado completo de tiles
    grep "\[PPU-TILE-RENDER-COMPLETE\]" logs/test_*_step0338.log | head -n 30
    
    # Verificar scroll y offset
    grep "\[PPU-SCROLL-OFFSET\]" logs/test_*_step0338.log | head -n 30
  • Validación Nativa: Validación de módulo compilado C++

Fuentes Consultadas

Integridad Educativa

Lo que Entiendo Ahora

  • Framebuffer: Contiene índices de color (0-3) para cada píxel. Se genera línea por línea durante el renderizado.
  • Tilemap: Mapa de 32×32 tiles que apunta a tiles en VRAM. Cada entrada contiene un tile ID que se usa para calcular la dirección del tile.
  • Scroll: SCX y SCY desplazan el background. El scroll se aplica al calcular la posición en el tilemap y puede causar que solo parte de un tile sea visible.

Lo que Falta Confirmar

  • Contenido del framebuffer: Verificar qué índices contiene el framebuffer cuando hay tiles reales. ¿Hay índices 1 o 2 (grises) además de 0 y 3?
  • Correspondencia tilemap-tiles: Verificar si el tilemap apunta a tiles con datos en VRAM. ¿Hay tiles vacíos o inválidos?
  • Renderizado completo: Verificar si los tiles se renderizan completamente. ¿Se renderizan todas las líneas del tile?
  • Scroll y offset: Verificar que el scroll y el offset se calculan correctamente. ¿Hay problemas con el wrap-around del scroll?

Hipótesis y Suposiciones

Los logs de diagnóstico se activarán cuando se detecten tiles reales en VRAM. Si los tiles aparecen difusos o a medias, los logs deberían revelar si el problema está en:

  • El contenido del framebuffer (índices incorrectos)
  • La correspondencia tilemap-tiles (tiles vacíos o inválidos)
  • El renderizado completo (tiles parcialmente renderizados)
  • El scroll o offset (cálculos incorrectos)

Próximos Pasos

  • [ ] Ejecutar pruebas completas con las 5 ROMs (2.5 minutos cada una)
  • [ ] Analizar los logs para identificar la causa de los tiles difusos
  • [ ] Si se identifica la causa: Implementar corrección en Step 0339
  • [ ] Si el problema persiste: Análisis más profundo y solución alternativa en Step 0339