An ESP32-S3 based, dual-screen (TFT+OLED) handmade gaming console project running on a FreeRTOS architecture.
This project is a handheld console developed from scratch using the ESP32-S3 microcontroller. Without relying on any pre-built UI frameworks or emulators, the operating system (E-OS) and the game engines were custom coded in C++ to run specifically on this hardware.
- Processor: Dual-Core ESP32-S3 running at 240 MHz.
- Dual Display:
- Main Screen: 160x128 Color TFT (SPI). Handles the main game rendering and UI.
- Secondary Screen: 128x64 OLED (I2C). Located at the top of the device; displays system status and high scores.
- Memory: 16MB Flash + 8MB PSRAM OPI. Massive memory bandwidth ensures a stutter-free experience.
- Audio & Controls: 8-bit buzzer and an analog joystick (with hardware deadzone filtering).
- Storage: Micro SD Card integration for game assets.
- FreeRTOS: One processor core (Core 0) handles the game logic, while the other core (Core 1) is entirely dedicated to screen rendering.
- Carousel UI: Features an animated, rotating carousel menu design for navigating between games.
- Hardware Pause: Thanks to RTOS task management, games can be paused instantly at the hardware level.
All games are heavily optimized for the device's resolution and hardware limits.
The E-OS Launcher acts as the main OS, providing a fluid, rotating (carousel) main menu interface hosting all games.
- Hardware Pause: Instantly suspend the active RTOS task by pressing the joystick button in any game.
- Double-Buffered UI: Rotating carousel menu runs completely tear-free, offering smartphone-like smooth transitions.
- OTA Bootloader: Reads binaries from SD card and writes to flash. Reboot state is remembered via RTC magic values.
- Hardware Sound Control: Mute, lower (LOW), or play games at full volume (HIGH) globally via the Settings menu.
- Live FPS Overlay: Real-time frame rate (FPS) overlay available for developers on all games.
- Asynchronous Dual-Core: Core 0 strictly handles background tasks and game logic, while Core 1 is dedicated to drawing graphics.
Screenshots and GIFs are captured over the USB serial connection. The asynchronous FrameDumper streams the framebuffer to the PC while the game keeps running at 60 FPS.
To process and save this data as PNGs or GIFs on your computer, the Python tools (capture.py, capture_gif.py, etc.) located in the tools/ directory are used.
TFT_eSPI— TFT display driver (ST7735)U8g2— OLED display driver (SH1106)SD— SD card accessPreferences— NVS high-score saving
- TFT_eSPI Setup: Copy the
User_Setup.hfile into your TFT_eSPI library folder:Windows: C:\Users\<user>\Documents\Arduino\libraries\TFT_eSPI\User_Setup.h - Partitions: Use the
partitions.csvfile provided in each game folder. - Board Settings (Arduino IDE):
- Board: ESP32S3 Dev Module
- Flash Size: 16MB (128Mb)
- PSRAM: OPI 8MB
- Partition Scheme: Custom (partitions.csv)
- Compilation: Each game is compiled as a separate
.inofile in its own folder.launcher.inois the main OS.
| Pin | Function |
|---|---|
| 12 | SPI SCK |
| 11 | SPI MOSI |
| 42 | SPI MISO |
| 15 | TFT CS |
| 10 | SD CS |
| 41 | TFT DC |
| 8 | I2C SDA (OLED) |
| 9 | I2C SCL (OLED) |
| 1 | Joystick X |
| 2 | Joystick Y |
| 18 | Joystick SW |
| 3 | Button A |
| 21 | Button B |
| 4 | Button C |
| 6 | Button D |
| 5 | Buzzer |

















