Emulazione NES con ESP32

Sono sempre stato affascinato dal retro gaming, da quando ho scoperto i MAME verso la fine degli anni 90. Ci sono ricordi d’infanzia legati ad alcuni videogiochi che riaffiorano quando vedo di nuovo sul display quei pupazzetti o quando riascolto quelle melodie 8bit che ti entravano nella testa :smile:

Ma la cosa che più mi attrae non è tanto il rigiocare certi titoli, ma proprio l’emulazione in se, e la genialità degli sviluppatori che hanno reso possibile tutto questo. Già nel 2003 avevo realizzato il mio cabinet mame rimappando con il saldatore una tastiera meccanica sui comandi del cabinet, con tanto di gettoniera funzionante :rofl: Il mio divertimento è proprio vedere il tutto funzionante, poi magari neanche ci gioco :innocent: E’ ancora in magazzino e prima o poi lo tirerò di nuovo fuori per aggiornarlo e magari scriverci un articolo qui sul blog!

Quando ho iniziato a smanettare con arduino prima e con esp32 poi, mi è venuta quindi naturale la domanda “sarà in grado di emulare qualche vecchio gioco della nostra infanzia?“… una breve ricerca e la risposta è arrivata subito: SI!

Ci siamo dunque messi subito all’opera e negli ultimi 2 anni nel laboratorio abbiamo realizzato un numero infinito di prototipi, sia su breadboard, sia su millefori e 10000 saldature che si reggevano per grazia ricevuta :rofl: sia realizzando pcb con i vecchi metodi (acido e trasferibili), sia con la CNC! Quella della realizzazione di pcb fai da te è stata un’esperienza fantastica e che presto condivideremo con voi con articoli dedicati. Di seguito metto solo qualche foto per anticiparvi qualcosa:

Come ho già scritto all’inizio dell’articolo, la soddisfazione sta nel vedere il tutto funzionante, nel perfezionarlo e migliorarlo, non tanto nel giocarci. Ed è anche grazie all’emulazione che è nata l’idea della Multimedia Board. Sentivamo la necessità di una board di sviluppo che ci permettesse in poco tempo di iniziare un nuovo progetto senza dover ogni volta cablare tutto da zero, con la certezza di non fare errori.

E come ormai da tradizione del laboratorio, ho preparato un progetto di base, che permette di caricare una rom NES da SPIFFS e giocarci. Da questo progetto di base poi ci divertiremo integrando una SD Card, un menu di navigazione e tante altre funzionalità che vedremo in articoli futuri. La cosa più bella è imparare divertendosi :smile:

NESP32-Single-game è presente nel repository GitHub . Informazioni dettagliate su come clonare un repository remoto le trovi nell’apposito articolo.

Il progetto è compatibile con 3 display: ILI9341, ILI9488, ST7789 e con l’amplificatore MAX98357A per la parte audio. Maggiori informazioni sulla connessione della mmb con queste periferiche le trovi qui. In mancanza di una mmb, il progetto ovviamente può essere riprodotto e/o modificato su una classica breadboard.

Ci tengo a chiarire una cosa importantissima: noi nel laboratorio non ci siamo inventati niente, abbiamo solo studiato il meraviglioso lavoro trovato in rete, lo abbiamo rielaborato e ricondiviso qui con voi. Tutti i ringraziamenti e tutta la nostra reverente ammirazione va innanzi tutto a Matt Conte, il creatore di Nofrendo, l’emulatore NES, realizzato in C tra il finire degli anni 90 e gli inizi del 2000. Ovviamente è stato importantissimo il porting del progetto Nofrendo su ESP-IDF fatto dalla Espressif stessa e l’ulteriore porting da ESP-IDF al framework Arduino fatto dall’utente GitHub moononournation presente qui, che ha anche realizzato la libreria grafica utilizzata nel progetto.

Altra precisazione doverosa: contrariamente alla stragrande maggioranza dei progetti che trovi nel laboratorio, in questo caso ho deciso di includere le due librerie utilizzate direttamente nel progetto copiandole nella directory ext_libs. Questo perchè nel corso del tempo, quando dopo mesi provavo a rimettere le mani sul NESP32 incorrevo sempre in problemi di compilazione, vuoi per aggiornamenti, vuoi per incompatibilità tra nuove versioni. Ho deciso quindi di “freezare” il codice ad una versione sicuramente funzionante. So che qualcuno storcerà il naso, ma sono del parere che quando una cosa funziona, non va più toccata :rofl:

Veniamo ora a qualche considerazione sul codice.

Come da consuetudine per i progetti che trovi nel laboratorio, tutte le configurazioni risiedono sul file platformio.ini. Qui sono definiti tutti i pin utilizzati che ovviamente, in caso di uso di una MMB non vanno modificati, altrimenti possono essere scelti a piacimento nel caso si utilizzasse una breadboard.

Una cosa da tenere a mente è che per moltissime roms NES che si trovano in rete è necessaria una quantità di ram superiore a quella disponibile sui modelli ESP32 WROOM. Il progetto prevede quindi l’utilizzo di un ESP32 Wrover e della sua ram SPI aggiuntiva, che viene attivata per mezzo delle direttive di platformio.ini seguenti:

; wrover SPIRAM
    -DBOARD_HAS_PSRAM
    -mfix-esp32-psram-cache-issue

è sempre possibile provare a compilare il progetto con un ESP32 Wroom, ma è necessario commentare questa parte di configurazione. Ovviamente, come detto in precedenza, quel particolare gioco che state provando ad utilizzare potrebbe non funzionare per insufficienza di memoria.

Anche in questo caso facciamo uso degli environments di Platform.IO per rendere compatibile il progetto con diversi display. Per non ripeterci di nuovo, puoi approfondire il discorso sugli environments qui e nell’esempio qui che è pressocchè identico all’implementazione del presente articolo.

Veniamo ora al gioco vero e proprio: la rom da caricare va posizionata nella directory data che va flashata come partizione SPIFFS. Come fare l’upload su spiffs dei files della directory data lo abbiamo già visto nell’articolo dedicato. Ho già incluso due roms “a sorpresa” in questa directory, ma puoi trovare facilmente un numero infinito di roms per nes, google in questo caso è tuo amico :wink:

Una volta che hai effettuato l’upload, la rom viene caricata nel file main.cpp alla riga 43:

argv[0] = (char *)"/fs/t.nes";

Ora non ti resta che fare la build del progetto e giocare! :sunglasses:

Un’ultima nota sui pulsanti utilizzati che sono 10, come definito sul file di configurazione platformio.ini.

i 4 di sinistra sono utilizzati per i movimenti, i 4 di destra sono il select, start, A, B.

I due tasti centrali sono per il salvataggio (sinistra) e per il caricamento (destra) dei progressi in game!

In articoli successivi vedremo insieme con migliorare questo progetto base: implementeremo un menù di selezione dei giochi, utilizzeremo una SD Card per avere più spazio di archiviazione a disposizione per i nostri giochi e tanto altro!

Web installer

Per questo progetto sono disponibili anche i web installers nell’area dedicata. E’ possibile installare il firmware direttamente dalla pagina web.

A presto! :smile: