The ESP-BOX-EMU is a gameboy-inspired add-on for the ESP32-S3-BOX and ESP32-S3-BOX-3 which provides:
- Game Controller (gamepad input with a/b/x/y, start/select, d-pad)
- LiPo battery (1000 mAh) with charging over USB-C
- Micro-SD card for storing roms, boxart, and savegames
- TinyUSB MSC device wrapping the uSD card
- Volume +/- buttons
- USB-C port for charging and programming
- Haptics (using LRA powered by DRV2605)
- Custom software stack including:
- NES Emulator (nofrendo)
- Regular Controls (D-Pad/A/B/Start/Select)
- Unlocked mode (fastest execution), toggled with the X button
- Gameboy / Gameboy Color emulator (gnuboy)
- Regular Controls (D-Pad/A/B/Start/Select)
- Unlocked mode (fastest execution), toggled with the X button
- Sega Master System / Game Gear emulator (smsplus)
- Regular Controls (D-Pad/A/B/Start/Select)
- Unlocked mode (fastest execution), toggled with the X button
- Genesis emulator (gwenesis) - full speed / buttery smooth when muted; unmuted it runs a little slower but has nice sound
- Regular Controls (D-Pad/A/B/C/Start/Select) (note: A is mapped to B, B is mapped to A, and C is mapped to Y)
- LVGL main menu with rom select (including boxart display) and settings page (all generated from Squareline Studio)
- LVGL emulation paused menu with save slot select, save slot image display, and configuration (sound, brightness, display, etc.). (all generated from Squareline Studio)
- NES Emulator (nofrendo)
box-emu-input-refactor-compressed.mp4
esp-box-emu.housing.and.assembly.v162-compressed.mp4
This project is designed to be in the same form factor as the Gameboy Color and to reuse the same button plastics and membranes for a good play feel.
The housing is designed to be 3d printed (I use PLA or PETG on Prusa i3 mk3+), and assembled with M3 screws.
These are the parts / sources I'm using for stock / replacement GBC membranes and buttons.
- Silicone pads for gameboy color (1)
- Silicone pads for gameboy color (2)
- Gameboy Color Button Plastics
Link to Fusion 360 CAD (Free Version):
The printable files can be found in the ./mcad folder or can be downloaded from printables.
The electrical files can be found in the ./ecad folder. There are both Fusion/Eagle files as well as atopile + kicad files.
This project has the following features (still WIP):
- Squareline Studio design files for generating boilerplate LVGL (SLS files, Generated files)
- LVGL gui for selecting emulators / roms (showing boxart and name)
- LVGL gui for controlling settings (such as volume, video, haptics)
- Loading of gui data (rom titles and boxart) from metadata file (example here)
- Audio output (using I2S + es8311 audio codec, es8311 component)
- User input with d-pad + buttons (a/b/x/y, start/select) (using MCP23x17 [v0 hardware] or AW9523 [v1 hardware])
- Interaction with touchscreen (using tt21100 component)
- Navigation of LVGL rom menu with controller (up,down,a,b,start)
- Runnable emulators (automatically selected by rom extension):
- NES emulator
- GB/GBC emulator
- Sega Master System (SMS) / GameGear (GG) emulator
- MSX emulator (WIP)
- Sega Mega Drive / Genesis emulator (WIP)
- SNES emulator
- Doom (WIP)
- uSD card (FAT) filesystem over SPI
- TinyUSB MSC device for optionally exposing the uSD to the attached USB host
- Memory mapping of selected rom data from storage into raw data partition (SPIFLASH)
- Emulator framebuffers on SPIRAM
- Queued transfers of screen data for maximum draw speed while running emulation
- Scaling of emulator video data to support ORIGINAL, FIT, and FILL modes of display data to screen
- Use mute button to toggle volume output while running the roms
- Feedback through tiny haptic motor (DRV2605)
- Save state (with automated save screenshot creation saved to uSD card)
- Load state (up to 5 slots per game)
- State management (UI to select state when loading roms, ui/buttons for saving/loading states while running, and displaying save screenshots)
- Schematic / Layout for control board peripheral containing
- joystick / D-Pad / Button inputs (via i2c I/O expander / ADC)
- Battery
- Charger circuit
- DRV2605 haptic motor (LRM / ECM)
- uSD card
- boost converter
- usb 2.0 passthrough from usb-c
- CAD for control board peripheral case in the same footprint as GBC
- USB-C Port for programming / charging
- uSD card slot for roms
- start / select buttons (same location as GBC)
- ABXY buttons (basically same size / location as GBC)
- Directional Pad (same size / location as GBC)
- Use same audio + video tasks for all emulators
- Graphics in black borders next to rom display during NES / GB/C emulation
Since this repo contains a submodule, you need to make sure you clone it recursively, e.g. with:
git clone --recurse-submodules [email protected]:esp-cpp/esp-box-emu
Alternatively, you can always ensure the submodules are up to date after cloning (or if you forgot to clone recursively) by running:
git submodule update --init --recursive
Build the project and flash it to the board, then run monitor tool to view serial output:
idf.py -p PORT flash monitor
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type Ctrl-]
.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
Format your uSD card as a FAT filesystem and add your roms (.nes, .gb, .gbc), images (.jpg), and metadata.csv.
For ease of use, there is a
./boxart/source/resize.bash script which will
resize all jpg
images in the boxart/source
folder to be 100x px wide (keep
aspect ratio but make width 100 px) and put the resized versions in the boxart
folder. You can then copy them onto your sd card and update your metadata file
appropriately.
<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
- https://github.com/nesemu/NESemu
- https://github.com/NiwakaDev/NIWAKA_NES
- https://github.com/kanathan/plainNES
- https://github.com/blagalucianflorin/lbnes
- https://github.com/daniel5151/ANESE
- https://github.com/Grandduchy/YaNES
- https://github.com/alnacle/awesome-emulators
- https://www.zophar.net/nes.html
- https://yizhang82.dev/nes-emu-overview
- https://www.gridbugs.org/zelda-screen-transitions-are-undefined-behaviour/
- https://bgb.bircd.org/pandocs.htm
- https://github.com/pebri86/esplay-gb
- https://github.com/hex007/esp32-gnuboy
- https://github.com/rofl0r/gnuboy
- https://github.com/zid/gameboy
- https://github.com/Jean-MarcHarvengt/MCUME
- https://github.com/OtherCrashOverride/go-play
- SNES Signal Reference
- NES Signal Reference
- Genesis Signal Reference
- DIY Gameboy