Développement GameBoy #1 : Hello World

Il y a quelques années, je m'étais intéressé au développement de jeux rétro pour la GameBoy de Nintendo. J'avais entrepris de développer un Snake-like sans prétention, mais je ne l'ai malheureusement jamais terminé. J'ai décidé aujourd'hui de retenter l'expérience et je vais en profiter pour écrire une série d'articles sur le développement pour la GameBoy.

Le présent article est donc le premier de la série, il portera sur les bases : l'écriture d'un programme « Hello world » ainsi que l'obtention d'un environnement de développement fonctionnel (un compilateur pour... compiler notre programme et un émulateur pour l'exécuter).

Note

NOTE : Pour cette série d'articles, je partirais du principe que le lecteur dispose de quelques connaissances de base en C et en utilisation de la ligne de commande sous Linux.

Présentation de la GameBoy

La GameBoy est une console portable sortie en 1989 au Japon et aux États Unis et en 1990 chez nous. Ses principales caractéristiques sont :

  • un CPU 8-bit cadencé à 4.194304 MHz,
  • 8 Mo de RAM,
  • 8 Mo de mémoire vidéo,
  • un écran de 2.6" affichant 4 niveaux de gris à une résolution de 160×144 pixels,
  • du son stéréo (en branchant des écouteurs car la console n'inclut qu'un unique haut-parleur),
  • un port link permettant de connecter plusieurs consoles entre elles,
  • le tout alimenté par 4 piles AA de 1.5v.

Les jeux GameBoy sont distribués sous forme de cartouches interchangeables dont les caractéristiques varient d'un jeu à l'autre :

  • de 32 ko à 4 Mo de ROM (mémoire en lecture seule contenant le jeu et ses données),
  • de la RAM optionnelle (avec une pile) pour sauvegarder des données,
  • et parfois d'autres éléments, comme une horloge, un port infrarouge, un vibreur,...

Note

NOTE : J'ai résumé ici les caractéristiques de la machine, mais vous pouvez trouver tout le détail sur le hardware de la GameBoy dans le document « Everything You Always Wanted To Know About GAMEBOY » (en anglais).

GBDK : Tout ce qu'il faut pour construire une ROM

GBDK (The GameBoy Developer's Kit) est un ensemble d'outils permettant de développer des programmes pour la GameBoy. Il contient notamment tout ce qu'il faut pour générer une ROM depuis un code en C (compilateur, éditeur de lien,...) ainsi qu'un ensemble de bibliothèques facilitant grandement le développement pour cette machine.

Pour installer GBDK, il faut le compiler depuis les sources. Étant donné que la base de code originale (hébergée sur SourceForge) n'est plus maintenue depuis 2002, il n'est plus possible de la compiler sur une distribution récente. Heureusement, quelqu'un a forké le projet sur Github et a corrigé les différents problèmes qui empêchaient la compilation.

Pour commencer on va installer les dépendances nécessaires à la compilation de GBDK. Il nous faut :

  • GNU make,
  • GCC / G++,
  • bison,
  • flex.

Pour installer tout ça, on peut taper la commande suivante sous Debian / Ubuntu (pour les autres distributions, les paquets doivent avoir des noms assez similaires) :

sudo apt install build-essential bison flex

En suite, il faut cloner le dépôt git :

git clone https://github.com/gheja/gbdk.git

puis se rendre dans le dossier du projet :

cd gbdk

et enfin lancer la compilation :

make

Si tout s'est bien passé, on se retrouve avec un dossier build/ppc-unknown-linux2.2/gbdk/ qui contient nos outils.

Il est ensuite possible d'installer tout ça sur le système à l'aide de la commande make install, ce qui aura pour effet d'installer GBDK dans le dossier /opt/gbdk par défaut... Personnellement je préfère ne pas l'installer et l'utiliser directement depuis le dossier de mon projet.

Mednafen : Un émulateur pour exécuter notre programme

Une fois le compilateur prêt à fonctionner, il reste une dernière étape avant de se lancer dans le développement d'un programme GameBoy : installer de quoi exécuter nos futures ROM sur notre PC.

De nombreux émulateurs sont disponibles pour chaque OS. Personnellement j'utilise Mednafen, il supporte pas mal de consoles et fonctionne bien.

Pour l'installer, il faut taper la commande suivante sous Debian / Ubuntu :

sudo apt install mednafen

Ensuite, il est possible de configurer Mednafen, notament l'assignation des touches, à l'aide du fichier ~/.mednafen/mednafen-09x.cfg. Comme le fichier de configuration est assez long et pas très pratique, je vous colle ci-dessous un extrait du mien :

gb.enable 1
gb.system_type auto

gb.xscale 3.000000
gb.yscale 3.000000

gb.input.builtin.gamepad.up keyboard 122
gb.input.builtin.gamepad.left keyboard 113
gb.input.builtin.gamepad.down keyboard 115
gb.input.builtin.gamepad.right keyboard 100
gb.input.builtin.gamepad.a keyboard 109
gb.input.builtin.gamepad.b keyboard 108
gb.input.builtin.gamepad.select keyboard 118
gb.input.builtin.gamepad.start keyboard 98

La configuration ci-dessus définit le mapping suivant :

  • z, q, s, d pour la croix directionnelle,
  • m pour le bouton A,
  • l pour le bouton B,
  • v pour le bouton select,
  • b pour le bouton start.
Mednafen GameBoy assignation des touches clavier

Note

NOTE : si vous souhaitez changer l'attribution des touches, il faut entrer le numéro dans la table ASCII du caractère se situant sur la touche de clavier désirée (par exemple 122 pour "z", 113 pour q,...).

Premier programme : Hello World

Comme le veut la tradition, on va commencer par écrire un programme « hello world » et voir comment le compiler et l'exécuter.

On va donc commencer par créer un fichier "hello.c" avec le contenu suivant :

#include <stdio.h>

void main(void) {
    printf("Hello world!\n");
}

Ici, aucune surprise, on aurait pu écrire la même chose pour un programme destiné à s'exécuter sur un PC. Voici donc l'état de mon dossier de projet après avoir ajouté mon programme :

01_hello_world/
    |
    +-- gbdk/           <- dépôt git de GBDK dans lequel j'ai compilé GBDK tout à l'heure
    |
    +-- hello.c         <- Mon programme à compiler

Pour compiler ce programme, rien de bien compliqué : on commence par exporter quelques variables d'environnement pour nous faciliter la vie :

export GBDKDIR="./gbdk/build/ppc-unknown-linux2.2/gbdk/"
PATH="./gbdk/build/ppc-unknown-linux2.2/gbdk/bin/:$PATH"

Ces variables permettent d'indiquer au compilateur où se trouvent ses fichiers et d'ajouter son binaire au PATH pour éviter d'avoir des lignes de commande trop longues à taper. Cette étape n'est probablement pas nécessaire si vous avez installé GBDK sur le système (make install).

Une fois les variables d'environnement définies, on peut compiler le programme à l'aide de la commande lcc :

lcc hello.c -o hello.gb

Si la compilation s'est bien déroulée, on se retrouve avec notre ROM, nommée hello.gb, dans le dossier courant. Il ne reste plus qu'à l'exécuter avec l'émulateur de notre choix (Mednafen dans mon cas) :

mednafen hello.gb

Et voilà notre magnifique programme en action :

GameBoy Hello World program

The Hello World Project

Afin de faciliter la compilation du « projet » ci-dessus, j'ai rédigé un Makefile prenant en charge l'obtention du compilateur et la compilation de la ROM. Vous trouverez ce projet d'exemple sur Github à l'adresse suivante :

Voici les commandes disponibles:

  • make buildenv : télécharge et compile GBDK (à exécuter la première fois)
  • make : compile le programme (construit la ROM)
  • make run : compile et exécute le programme dans Mednafen
  • make clean : supprime les artéfacts de construction et la ROM

Bien qu'un peu long, cet article fournit toutes les informations nécessaires pour commencer à programmer pour la GameBoy. J'espère qu'il vous a été utile et je vous donne rendez-vous dans un prochain article dans lequel j'aborderai d'autres aspects du développement pour la console de Nintendo.