First steps designing a retro console with ESP32

Before starting any project I made a list of features I personally wanted on this console.

To prototype I am using an ESP32 mainly because I have several of them laying around. There’s also other reasons.

ESP32s might not be good enough for the final version, but it gets the job done while designing and testing features due to its 4MB of ram and 30+ GPIO pins.

Although for the final version I might switch to a iMXRT1062 which is way more powerful and adequate for the job.

So… Whats the plan?

I’ve separated the project in different sections.

Game Storage:

One of the most important aspects of a console, its the possibility to play different games on the same device. Which sounds obvious, but it adds a significant amount of complexity to the project.

The way I am handling this problem is with micro sd cards. Even though they are not reliable in the long run, they are good enough for now.

Every micro sd will contain the necessary files, sprites and sounds for the game to work. It will even contain save states if the game allows it.

Games and Engine:

Every game will be built using LUA.

There will be several game engines, each one used for its purpose and the chosen engine will be shipped alongside the game in the micro sd card. The game engines will also be written in LUA to build games easier.

Low level api:

LUA scripts will not have direct access to hardware components or compute heavy functionalities.

When embedding LUA in a C/C++ project, it is allowed to define functions that LUA can call and instead of LUA executing those functions, the C/C++ program will run them.

I will be using this functionality to create a bridge between hardware components and high level scripts.

It is also possible to append this functions to a global variable. This way I can create various bridges/APIs without much effort.

For example, instead of using the function:

drawSprite(...)
drawRectangle(...)
drawCircle(...)

I will define:

_display.drawSprite(...)
_display.drawRectangle(...)
_display.drawCircle(...)

This pattern allows to locate similar functions without complications and in an ordered manner under a common namespace.

I’ve began to think about the different namespaces I will need:

_display;
_input;
_sound;
_filesystem;

Display/Screen:

To prototype I am using a 128×160 display, which works great with ESP32, but when I change microcontrollers to a more powerful one, I might switch to a bigger one.

I am interested in using TFT Displays which uses the SPI interface to prototype but for the final build I might change to RCA connectors and regular screens.

Periferals:

I haven’t given much thought about periferals just yet.

But I would love to build a controler that can be plugged/unplugged and use them on another build.

Which is why I have thought about using Mini-DIN connectors.

I will also build a separate periferal to control audio, connected similarly as the controller. This new device will contain up to twuelve buzzers and will play midi files assigning specific notes to each buzzer. But if I end up using RCA connectors, this idea will be scratched since they can carry audio signals to a screen.

I know its a very ambitious project, but I am having fun so far.

Leave a Comment