Skip to content

esp-cpp/esp-box-emu

Repository files navigation

esp-box-emu

Logo Rendering

Release License Platform: ESP32-S3

A pocket-sized, Game Boy-style retro emulation handheld built around the ESP32-S3-BOX. Drop in a micro-SD card of ROMs and play NES, Game Boy / Color, Sega, MSX, and Genesis games — plus a full-speed port of Doom — on hardware you can 3D print and build yourself.

image

doom_test-compressed.mp4

Table of Contents

Overview

The ESP-BOX-EMU turns an ESP32-S3-BOX or ESP32-S3-BOX-3 into a handheld retro game console. A custom add-on board and 3D-printed shell wrap the BOX in a Game Boy Color form factor — real d-pad and buttons, battery, haptics, and a micro-SD slot — and the firmware runs a stack of emulators behind a polished LVGL interface with boxart, save states, and settings.

Highlights

  • 🎮 Six systems + Doom — NES, Game Boy / Color, Sega Master System / Game Gear, Sega Genesis, and MSX 1/2 emulators, plus a full-speed Doom port — all with sound.
  • 🧬 Full-speed Genesis — a custom dual-core port of gwenesis splits the emulation across both of the ESP32-S3's cores (CPU + video on one, the sound unit on the other) for full-speed Sega Genesis / Mega Drive with audio.
  • No reboots — every core and game loads on demand right from the menu, so you can jump between titles and even different systems without ever restarting the device.
  • 🕹️ Real controls — d-pad, A/B/X/Y, Start/Select and volume buttons in a familiar Game Boy Color layout; the emulator is auto-selected from the ROM file extension.
  • 💾 Load from SD — keep ROMs, boxart, and save states on a micro-SD card, and mount the card over USB-C as a mass-storage drive (TinyUSB MSC).
  • 💤 Save anywhere — up to 5 save slots per game, each with an auto-generated screenshot shown in the load menu.
  • 🔋 Portable — 1000 mAh LiPo battery with USB-C charging.
  • 📳 Haptics — LRA haptic feedback (DRV2605), including in-game effects in Doom (weapon fire, taking damage, pickups, and more).
  • 🖼️ Polished UI — LVGL menus for ROM select (with boxart) and settings (sound, brightness, display scaling, haptics), designed in Squareline Studio.
  • 🛠️ Fully open hardware — 3D-printable GBC-style case and an open PCB (Fusion/Eagle and atopile + KiCad), all included in this repo.

Emulators

The right emulator is chosen automatically from each ROM's file extension, and games load on demand straight from the menu — no reboot required. Pick a title, play, then drop back to the menu and launch a different game (or a completely different system) without ever restarting the device. Every core runs with audio, and several offer an Unlocked mode (toggle with the X button) that removes the frame-rate cap for maximum speed.

System Core Unlocked mode Notes
NES nofrendo D-Pad / A / B / Start / Select
Game Boy / Color gnuboy D-Pad / A / B / Start / Select
Sega Master System / Game Gear smsplus D-Pad / A / B / Start / Select
Sega Genesis / Mega Drive gwenesis Full speed with sound; 6-button pad (A→B, B→A, C→Y)
MSX 1 / 2 fmsx D-Pad / A / B / Start / Select
Doom prboom Full speed with audio and haptic feedback

🧬 Full-speed Genesis on the S3. The Genesis core ships with a custom dual-core modification of gwenesis that spreads the workload across both of the ESP32-S3's CPU cores: core 0 runs the 68000 CPU and VDP (video), while core 1 runs the sound unit (Z80 + YM2612 FM synth + PSG). Sound-chip writes are queued and applied in order on core 1, which lets Genesis / Mega Drive games run at full speed with audio — something a single core can't keep up with.

Doom controls and haptics

Controls: A fire / enter · B strafe / backspace · X use · Y weapon toggle · START escape · SELECT map.

Haptic feedback is triggered when you fire a weapon (varies by weapon), take damage (scaled to the health/armor lost), interact with something (e.g. a door), or pick up a weapon, ammo, health, armor, a power-up, or a key / card.

Gallery

image image image

image

box-emu-input-refactor-compressed.mp4
esp-box-emu.housing.and.assembly.v162-compressed.mp4

Quick Start — Play It

Already have the add-on hardware (or an ESP32-S3-BOX you want to flash)? You don't need to build anything from source — a prebuilt one-time programmer is published with every release.

  1. Download the programmer for your OS (windows, macos, or linux) from the latest releases page.

  2. Unzip it.

  3. Run it: double-click the .exe on Windows, or run it from a terminal on macOS / Linux, e.g.:

    ./esp-box-emu_programmer_v1.0.0_macos.bin

    (The version in the filename matches the release you downloaded.)

Then set up a micro-SD card with your ROMs and you're ready to play.

Build the Hardware

The add-on is designed to match the Game Boy Color form factor and reuse GBC button plastics and silicone membranes for an authentic feel. The shell is meant to be 3D printed (PLA or PETG on a Prusa i3 mk3+) and assembled with M3 screws.

Case / mechanical — printable files are in ./mcad or on Printables. CAD is on Fusion 360 (free viewer):

Fusion 360 CAD

Electronics — schematic and layout files are in ./ecad, provided as both Fusion/Eagle files and atopile + KiCad sources. You can also order the board directly:

PCB from PCBWay

GBC replacement buttons / membranes used for a good play feel:

Build the Firmware

This repo uses submodules, so clone it recursively:

git clone --recurse-submodules git@github.com:esp-cpp/esp-box-emu

If you already cloned it non-recursively (or forgot the flag), pull the submodules with:

git submodule update --init --recursive

Then build, flash, and open the serial monitor with ESP-IDF:

idf.py -p PORT flash monitor

Replace PORT with your board's serial port. To exit the monitor, type Ctrl-].

ROMs and SD Card Setup

Format a micro-SD card as FAT and add your ROMs (.nes, .gb, .gbc, …), boxart images (.jpg), and a metadata.csv file (see the example metadata.csv).

Boxart images

Boxart displays best at 100 px wide. The ./boxart/source/resize.bash script resizes every .jpg in boxart/source to 100 px wide (preserving aspect ratio) and writes the results to the boxart folder. Copy those onto the SD card and reference them from your metadata file.

metadata.csv format

Each line maps a ROM to its boxart and display name:

<rom filename>, <rom boxart filename>, <rom display name>

Example:

mario.nes, boxart/mario.jpg, Mario Bros.
super_mario_1.nes, boxart/super_mario_bros_1.jpg, Super Mario Bros.
super_mario_3.nes, boxart/super_mario_bros_3.jpg, Super Mario Bros. 3
zelda.nes, boxart/zelda1.jpg, The Legend of Zelda
zelda_2.nes, boxart/zelda2.jpg, The Legend of Zelda 2: the Adventure of Link
mega_man.nes, boxart/megaman1.jpg, MegaMan
metroid.nes, boxart/metroid1.jpg, Metroid
pokemon_blue.gb, boxart/pokemon_blue.jpg, Pokemon Blue
pokemon_red.gb, boxart/pokemon_red.jpg, Pokemon Red
pokemon_yellow.gbc, boxart/pokemon_yellow.jpg, Pokemon Yellow
links_awakening.gb, boxart/tloz_links_awakening.jpg, The Legend of Zelda: Link's Awakening
links_awakening.gbc, boxart/tloz_links_awakening_dx.jpg, The Legend of Zelda: Link's Awakening DX

Features and Roadmap

A checklist of what's implemented and what's still in progress.

Emulation

  • Auto-select emulator by ROM extension: NES, GB/GBC, SMS/GG, MSX, Genesis, Doom
  • On-demand core loading — every emulator and game loads at runtime with no reboot needed to switch games or systems
  • Custom dual-core Genesis (gwenesis): 68000 + VDP on one ESP32-S3 core, sound unit (Z80 + YM2612 + PSG) on the other, for full-speed audio and gameplay
  • Doom haptic feedback 🚀
  • Save state (with automatic save-screenshot creation to the SD card)
  • Load state — up to 5 slots per game, with save-screenshot previews
  • Shared-memory system so many emulators can be built in together while keeping their hot state in fast internal RAM
  • Dark Forces (WIP)
  • SNES emulator (WIP)

User interface

  • LVGL ROM-select menu with boxart and title, navigable by controller
  • LVGL settings menu (volume, video, haptics) and in-game pause menu
  • GUI data (titles + boxart) loaded from the metadata file
  • Squareline Studio source for the LVGL boilerplate (SLS files, generated files)

Video and audio

  • Emulator framebuffers in SPIRAM, with queued screen transfers for maximum draw speed
  • Video scaling with ORIGINAL, FIT, and FILL display modes
  • Audio output over I2S via the es8311 codec (codec component)
  • Mute button toggles audio while a ROM is running
  • Haptic feedback via a DRV2605-driven LRA
  • Decorative graphics in the black borders during NES / GB/C emulation (WIP)

Storage and input

  • micro-SD (FAT) filesystem over SPI
  • TinyUSB MSC device to expose the SD card to an attached USB host
  • Memory-mapping of the selected ROM from storage into a raw data partition (SPI flash)
  • D-pad + A/B/X/Y + Start/Select input (MCP23x17 on v0 hardware, AW9523 on v1)
  • Touchscreen input (tt21100 component)

Hardware

  • Control-board schematic / layout: joystick / d-pad / buttons (via I²C I/O expander + ADC), battery, charger, DRV2605 haptics, micro-SD, boost converter, and USB 2.0 passthrough from USB-C
  • Case CAD in the GBC footprint: USB-C port, micro-SD slot, Start/Select, ABXY, and D-pad in familiar locations

References and Inspiration

Other NES emulators

Other Genesis emulators

Useful background / information

License

This project is licensed under the terms in LICENSE.

About

Doom, NES, Gameboy/Color, Sega Master System / GameGear, Sega Genesis / MegaDrive, and MSX I/II Emulators running on ESP BOX and ESP BOX-3 with a custom gamepad

Topics

Resources

License

Stars

126 stars

Watchers

5 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors