alanm/proyectos

← Consola ESP32-S3

Motor de consola — ESP32-S3 (16 MB PSRAM)

Markdown

Motor de consola — ESP32-S3 (16 MB PSRAM)

Motor gráfico 2D + mode 7 + binding Lua para una consola portátil estilo
Playdate/PicoSystem, corriendo sobre ESP32-S3 con 16 MB de PSRAM octal.

Estructura

consola-esp32/
├── src/
│   ├── main.cpp              # arranque + game loop + input GPIO
│   └── motor/
│       ├── motor.hpp/.cpp    # NÚCLEO: framebuffer, blitter, mode 7, texto
│       ├── pantalla.hpp      # capa hardware (LovyanGFX, DMA, doble buffer)
│       └── lua_api.hpp/.cpp  # binding de la API a Lua 5.4
├── tests/
│   └── test_motor.cpp        # verificación del núcleo (compila en PC)
├── games/pong/main.lua       # juego de ejemplo
└── docs/                     # documentación y diagramas

Hardware: ESP32-S3 con PSRAM octal de 16 MB

La configuración clave está en platformio.ini:

board_build.arduino.memory_type = qio_opi

16 MB de PSRAM en el ESP32-S3 es siempre octal (OPI). qio_opi activa
CONFIG_SPIRAM_MODE_OCT en el SDK y enlaza los scripts correctos. Con quad
(8 MB) usarías qio_qspi.

Todo el consumo de memoria va a PSRAM:

  • Framebuffer doble → heap_caps_malloc(..., MALLOC_CAP_SPIRAM) explícito.
  • Heap de Lua → lua_newstate(luaPsramAlloc, ...) con realloc en PSRAM.

Con 16 MB hay sitio de sobra para framebuffer 480×320 (×2), texturas de mode 7,
y que cada juego Lua cargue tablas/sprites grandes sin tocar la RAM interna
(que queda libre para el stack y el sistema).

Verificar el núcleo en el Mac (sin hardware)

clang++ -std=c++17 -O2 -Isrc/motor tests/test_motor.cpp src/motor/motor.cpp -o /tmp/test_motor
/tmp/test_motor

18 pruebas: clear, rect con recorte, sprite con transparencia/flip/recorte,
line, texto, y mode 7 (horizonte, textura, rotación). Todo debe dar "TODAS
LAS PRUEBAS DEL MOTOR PASARON".

Compilar para el ESP32-S3

  1. Instala PlatformIO (pip install platformio o extensión de VS Code).
  2. cd consola-esp32 && pio run
  3. pio run -t upload

Diseño del motor (resumen)

  • Framebuffer en PSRAM (doble buffer): se pinta en uno, se muestra el otro.
  • RGB565 (16 bits/píxel): el estándar de las pantallas SPI.
  • Color key magenta = transparente en sprites.
  • Mode 7 por software: plano de suelo con perspectiva, punto fijo 16.16,
    textura potencia-de-dos con wrap por máscara.
  • Lua embebido: el juego es un main.lua con init(), update(dt) y
    onButton(n). El juego nunca toca el hardware, solo llama a la API.

API pública (Lua, naming estándar inglés)

clear(), rect(), line(), text(), textWidth(), spr(), sprSize(),
mode7(), btn(), btnp(), dt().

Consulta docs/api.md para la documentación completa de cada función.