Page de David Odin

Le Défi NES

Cette page ne devrait peut-être pas être présente dans la partie "Historique" de ce site puisque je commence à peine à programmer sur NES. Au moment où j'écris ces lignes (le 5 mars 2019), je n'ai en effet jamais programmé pour la NES. Je sais plus ou moins de quoi est capable cette machine (que je n'ai jamais possédée, honte à moi !), je ne connais l'assembleur 6502 que théoriquement, je n'ai jamais rien écrit pour cette architecture même si je connais ses limitations (trois registres utilisables : A, X et Y - peu d'instructions et de modes d'adressage). Mais je connais bien différents assembleurs (Z80, 68000, i386, ARM), et j'ai déjà travaillé sur des machines très restreintes.

Aussi, je me suis lancé un petit défi : arriver à créer un jeu pour NES (que je testerai sur tous les émulateurs que je trouverai, et pourquoi pas sur une vraie NES si j'arrive à créer une cartouche) en écrivant tout le code moi-même, en dessinant les graphismes et en composant la musique et effets sonores. En me relisant, je trouve la tâche colossale, mais bon, c'est le principe des défis.

5 mars 2019

Ma santé n'étant pas au top, je commence doucement. Mon but du jour est de trouver des émulateurs et quelques ROMs de jeux homebrew pour les tester. Je vais aussi essayer de trouver un maximum de documentation technique sur l'assembleur 6502 et les spécificités de la NES. L'analyse du code d'un émulateur open source pourrait peut-être bien aussi m'aider grandement.

J'ai trouvé deux émulateurs qui ont l'air sympa : nestopia et fceux. Les deux semblent intéressants et configurables afin d'être assez proche de la NES d'origine. Par exemple la NES est limité à 8 sprites par scanline et ces deux émulateurs permettent de garder cette restriction ou pas. J'aimerais autant que possible un émulateur qui soit aussi exigeant que la vraie console, afin de pouvoir vraiment créer une cartouche par la suite.

Je ne suis pas le seul à vouloir développer pour la NES, et ce Wiki qui regorge de plein d'info me parait très prometteur. J'y ai d'ailleurs trouvé quelques programmes exemples et démos. Une toolchain extrêmement simple consiste à utiliser un assembleur nesasm qui produit directement un fichier de type .nes utilisable directement dans un émulateur.

J'avoue avoir la flemme de faire des screenshots et de fournir les liens de ce que j'ai trouvé. Mais tout ça est très encourageant. J'espère commencer l'étude de l'assembleur 6502 ce soir ou demain.

6 mars 2019

L'assembleur nommé asm6 parait plus "moderne". Déjà, j'ai trouvé sa documentation. Il est open source, supporte les macros, différents types de labels locaux, plein d'opérateurs arithmétiques et a d'autres petits avantage. Je vais essayer de me concentrer sur son utilisation.

Avec les infos que j'ai glanées à droite et à gauche, je vais pouvoir commencer mon premier programme.

Apparemment, il y a plein de formats de ROMs supportées par la NES et donc aussi par les émulateurs. Le format le plus simple étant "NROM". Ce qui correspond à une cartouche qui aurait deux eeproms de 16 ko, une pour le code et une pour les graphismes (j'avoue que je ne suis pas bien sûr de ce que j'avance, là). Beaucoup d'autres formats existent notamment pour supporter plus de mémoire en découpant les ROMs en tranches (ce qui est un coup à se mettre des associations humanitaires à dos, mais bon...) ou d'apporter des fonctionnalités supplémentaires. Je n'ai pas fait le tour des formats.

On arrive à trouver des documentations sur l'organisation de la mémoire de la NES, je ne vais pas les reproduire ici. Cependant quelques adresses vont être immédiatement utiles :

Avec tout ça, je vais pouvoir faire mon premier programme : simplement un truc qui change la palette et dont le seul effet visible est de mettre une couleur de fond. L'assembleur 6502 s'apprend très vite, il y a peu d'instructions et de registres, et la philosophie est proche du Z80 que je connais très bien. Quelques macros et définitions permettent de rendre le code plus clair (en tout cas pour moi). J'espère faire un screenshot (vide mais coloré) dès aujourd'hui !

Yes ! J'ai un premier programme qui fonctionne ! Plus exactement compile sans le moindre problème, s'exécute correctement sur fceux en affichant simplement un fond rose (couleur 37 de la palette de la NES). Mais il ne se lance pas sur nestopia qui affiche un message assez énigmatique : "Error: Corrupt or Missing File". Le fichier existe pourtant et n'est pas si corrompu puisque fceux arrive à le lancer. Je vais enquêter sur le sujet.

J'ai failli oublier de poster un screenshot !
Premier programme NES

7 mars 2019

Mon premier programme NES fonctionne maintenant également sur nestopia qui semble plus pointilleux sur les formats des fichiers ROM.

Beaucoup de temps perdu à essayer de trouver un éditeur de tiles facilement utilisable dans mon environnement. Le plus simple semble de créer des images avec n'importe quel éditeur puis d'utiliser un script pour transformer ça dans le format ultra simple utilisable par le PPU. Je vais faire ça ou même écrire un fichier de graphismes à la main pour commencer. Ma prochaine étape sera d'afficher un fond, comme pour un jeu de plateformes. Mais ça attendra mon retour de l'hôpital...

8 mars 2019

Bon, comme prévu, j'ai écrit un petit programme en C pour créer des graphismes (juste un damier et un triangle d'une autre couleur). Pas grand chose, mais ça permet de tester le fonctionnement de tout cela sur NES. Encore une fois, ça fonctionne mieux avec fceux qu'avec nestopia. J'ai à peu près ce que je veux sur le premier (voir screenshot ci-dessous) alors que le second affiche les éléments en noir.
Premiers tests background

Prochaine étape : avoir un fond formé de plein de "tiles" différents, avant de passer à la partie scrolling.

9 mars 2019

Pas grand chose aujourd'hui. J'ai surtout lu plein de docs. Je commence à bien voir les possibilités et limitations de cette console. Il y a de quoi s'amuser.

10 mars 2019

Aujourd'hui, je me suis fait un petit programme permettant de facilement utiliser une police de caractères. Je pourrai donc facilement en changer par la suite.

Et voici donc le screenshot de l'utilisation d'une police. Ça permettra d'afficher un score ou plein d'autres trucs.
Hello, world!

11 mars 2019

Encore beaucoup de temps passé à découvrir le fonctionnement interne de la bête. Il semblerait qu'on puisse dépasser certaines limitations assez facilement finalement. Encore et toujours le même truc : on synchronise le CPU avec la partie vidéo (comme sur ZX81, ZX spectrum, C64, Atari ST) et on change certains paramètres exactement au bon moment. Il me semble possible de positionner les tiles du background au pixel près horizontalement dans certaines conditions. La 3D n'est pas loin ;) !

En attendant que je maîtrise mieux ces choses exotiques, je me suis donné un but plus accessible : porter mon jeu favorit sur cette plateforme nouvelle pour moi. Ça n'est pas gagné puisque je continue de découvrir l'assembleur 6502, mais au moins je connais assez bien le jeu pour l'avoir codé sur pas mal de machines. La partie décor semble facile, si ce n'est que la résolution verticale de la NES n'est pas suffisante pour tout afficher à la fois. Je vais donc devoir implémenter un scrolling vertical plus rapidement que prévu !

Et voici l'habituel screenshot.
Pacman décor

12 mars 2019

Plein de nouveautés aujourd'hui !
J'arrive à afficher des sprites par dessus mon décor, et j'ai progressé en assembleur 6502. Le labyrinthe de pacman (qui s'est vu étoffé de pac-gommes), peut maintenant être visité par pacman. Ça veut dire que j'arrive à gérer les joypads et que mon niveau d'assembleur 6502 me permet de tester si pacman rentre dans un mur ou pas !
Pour mieux vous rendre compte, en plus du screenshot du jour, il y a aussi la vidéo du jour (cliquez sur l'image) :
Pacman du jour
Le jeu est beaucoup moins saccadé que la vidéo le laisse supposer. D'ailleurs, si vous disposez d'un émulateur comme fceux ou nestopia, vous pouvez le tester vous-même en cliquant sur ce lien

Bilan provisoire Compte tenu que je ne m'intéresse au développement sur NES et à l'assembleur 6502 que depuis une semaine, je suis assez content du résultat. N'hésitez pas à me contacter si vous avez besoin d'un programmeur assembleur (pour NES ou autre !)

13 mars 2019

Plein d'emmerdes personnelles aujourd'hui, du coup je n'ai pas avancé beaucoup. J'ai tout de même incorporé un début de "vrai" moteur graphique dans mon code assembleur (avec une séparation forte entre la logique et le rendu). Les limitations de l'assembleur 6502 (et mes connaissances aussi, probablement) font qu'il est assez complexe de se déplacer dans un tableau de plus de 256 octets, mais on y arrive. Cela méritera probablement une réécriture ou au moins une optimisation du code dans l'avenir. Cela a tout de même permis de mettre à jour certaines données pour effacer les pilules que pacman mange. Pacman peut aussi maintenant emprunter le tunnel dans les deux sens.

Les prochaines étapes qui me viennent en tête sont l'actualisation du score, avoir un pacman qui regarde dans la bonne direction et qui mâche, puis je passerai aux fantômes. J'ai encore de quoi m'occuper un moment !

La vidéo du jour montre que pacman dévore maintenant ses pilules préférées :
video

14 mars 2019

Ça continue d'avancer doucement. J'ai nettoyé une partie du code et ajouté quelques fonctionnalités. Mon pacman regarde maintenant dans la bonne direction !

Les pilules sont vraiment mangées correctement et rapportent 10 points chacune, comme on peut le voir dans la vidéo du jour.

video

15 mars 2019

Pacman mâche maintenant correctement sa nourriture. Pas de difficulté particulière pour l'animation de pacman, il s'agit simplement de sprites à enchaîner dans le bon ordre.

Une partie un peu plus complexe a été la mise en place d'un scrolling vertical. En effet, je voulais garder le même plan de labyrinthe que dans le jeu original, et cela ne tient pas dans l'écran de la NES. L'écran défile donc en suivant les mouvements de Pacman. Pas mal de difficultés rencontrées, même si la NES fournit un registre pour effectuer le défilement du fond (background). En effet, ce registre ne concerne pas les sprites qu'il faut donc repositionner en fonction. De plus, les informations concernant le haut et le bas du labyrinthe ne sont pas contiguë en mémoire, ce qui complexifie pas mal les choses. Sans compter que l'écran virtuel étant de plus de 256 pixels de haut, il est assez pénible de stocker les positions dans les registres 8 bits du 6502.

Mais finalement, rien d'insurmontable, et cela m'a obligé à réécrire plus proprement certaines parties du code. La gestion des sprites des fantômes ne devrait pas être rendue plus complexe avec le défilement, le gros du travail ayant été fait pour Pacman.

La vidéo du jour montre tout ça.

video

16 mars 2019

Un peu de réflexion aujourd'hui avant de se replonger dans le code.

Maintenant que Pacman se déplace bien dans le labyrinthe, il est temps de passer à l'affichage des fantômes. Voici ce que j'avais en tête pour les sprites des fantômes :

Et C'est là qu'arrivent les problèmes.

Sur NES, il y a deux façons d'afficher des graphismes : le fond et les sprites. Le fond permet d'afficher des trucs comme les murs du labyrinthe qui ne bougent pas, mais uniquement à des positions qui sont des multiples de 8. Il y a aussi d'autres limitations, mais peu importe pour le moment.

Pacman et les fantômes doivent donc être affichés via le système de sprites. La NES permet d'afficher simultanément jusqu'a 64 sprites, ce qui est amplement suffisant pour un jeu comme Pacman, même en considérant que chaque personnage "consomme" 4 sprites. Cependant, chaque sprite de 8x8 ne peut être utiliser qu'une palette parmi 4. Et chaque palette est composée de 3 couleurs plus une pour la transparence. On peut toutefois composer les palettes comme on le veut, reste à trouver comment.

Si on part de l'idée que les fantômes sont créés comme décrits précédemment, on a besoin des palettes suivantes :

Les palettes sont alors toutes utilisées, et il ne reste plus de couleur possible pour le jaune de Pacman, c'est inenvisageable ! Les couleurs Noir et Blanc doivent être dupliquées dans chaque palette à cause de la limitation disant qu'un sprite donné ne peut utiliser les couleurs que d'une seule palette.

Il va donc falloir ruser.
Une idée qui m'est venue était d'utiliser des sprites avec juste les robes des fantômes par dessus lesquelles on pourrait ajouter des sprites pour les yeux, ça permet d'éviter le problème de duplication du noir et du blanc, on peut même tout faire tenir dans trois palettes de cette façon. Mais on se heurte alors à une autre limitation de la NES : sur chaque ligne horizontale (de 1 pixel), seuls 8 sprites peuvent être affichés. Si on essaie d'en mettre plus, ils ne seront tout simplement pas affichés. On peut donc afficher 64 sprites, mais uniquement s'ils sont bien répartis verticalement ! Hors, avec l'idée des robes et des yeux superposés, pour un seul fantôme, on a déjà 4 sprites sur la même ligne, et donc dès qu'on aura trois fantômes ou plus (ou deux fantômes et pacman) sur la même ligne, certains sprites ne seront pas affichés !

On ne peut donc pas vraiment utiliser l'idée des yeux dans des sprites séparés, dommage.

Idée suivante :utiliser la couleur transparente au lieu du noir pour l'iris des yeux des fantômes.

Cela présente un léger inconvénient : on voit ce qu'il y a derrière un fantôme au niveau de ces yeux. Mais bon, après tout il s'agit de fantôme, et la plupart du temps, ce qu'il y a derrière les yeux d'un fantôme, c'est le noir du fond du labyrinthe. Les pilules ne sont par au niveau des yeux, ni horizontalement ni verticalement. Le problème ne sera donc visible que si le fantôme passe au dessus d'une des 4 pac-gommes, d'un autre fantôme ou de pacman. C'est donc un inconvénient que l'on peut tolérer, surtout que cela résout les problèmes précédents, ou presque.

En effet, si Pacman et les quatre fantômes sont sur la même ligne, on a toujours le problème de la limite des 8 sprites par ligne. Et l'un des personnages risque de disparaître. La seule solution que je vois à ça consiste à changer l'ordre d'affichage des fantômes régulièrement et assez rapidement. (Hors de question de ne pas avoir Pacman à l'écran)

Avant d'implémenter tout ça, je me suis demandé si la version officielle de Pacman sur NES souffrait des mêmes problèmes, et je me suis penché sur cette vidéo :

On peut remarquer plusieurs choses :

Même si c'est rare, je trouve perturbant qu'un fantôme puisse totalement disparaître et réapparaitre plus tard (ce qui arrive notamment un dixième de seconde avant la première image ci-dessus). C'est pourquoi je veux tester ma solution qui consiste à changer régulièrement l'ordre des fantômes. Ainsi en cas de problème les fantômes clignoteront à tour de rôle ce qui permettra de ne pas les perdre des yeux. Cela pourra cependant être gênant lorsque deux fantômes feront un bout de chemin ensemble, l'ordre de superposition changera. Reste à savoir si ces changements seront plus ou moins pénibles que de voir un fantôme disparaître totalement.

Mais je suis content de voir que le jeu officiel a le même genre solution aux contraintes imposées par la machine. Il reste tout de même à implémenter tout ça.

Je peux au moins commencer par lister les couleurs de chaque palette pour les sprites afin de pouvoir commencer à créer les graphismes des fantômes :

Palette # Couleur Utilisation
1 0 Noire Transparent
1 Jaune Pacman
2 Inutilisé
3 Inutilisé
2 0 Noire Transparent
1 Rouge Robe du Fantôme Rouge
2 Cyan Robe du Fantôme Cyan
3 Blanc Yeux des deux premiers fantômes
3 0 Noire Transparent
1 Rose Robe du Fantôme Rose
2 Orange Robe du Fantôme Orange
3 Blanc Yeux de ces deux fantômes
4 0 Noire Transparent
1 Bleu foncé Fantômes en mode pac-gomme
2 Bleu clair Contour des fantômes en mode pac-gomme
3 Inutilisé

19 mars 2019

Après deux jous sans rien pour cause de dimanche et d'anniversaire, le développement avec l'arrivée des fantômes. Le post de samedi a bien aidé à débroussailler toute la partie affichage.

Sur le screenshot du jour, on peut voir l'apparition des fantômes.
Apparition des fantômes

21 mars 2019

Les fantômes commencent à se déplacer correctement. Dans la vidéo suivante, on peut voir blinky, le fantôme rouge se diriger tout seul vers le point en bas à droite du labyrinthe en respectant quelques règles comme l'interdiction de traverser les murs ou de faire demi-tour. Il reste évidemment quelques bugs d'affichage, mais le cœur de l'algorithme de déplacement est là.

video

22 mars 2019

Après avoir corrigé les bugs d'affichage d'hier (les yeux qui ne regardaient pas dans la bonne direction et des apparitions de l'autre côté de l'écran de temps en temps, je suis passé au déplacement des autres fantômes. La vidéo ci-dessous montre les quatre fantômes, indépendants, qui vont chacun dans leur coin avant de tourner un peu en rond. C'est l'un des modes de déplacement des fantômes, il faut que je programme les autres : le mode effrayé lorsque Pacman essaie de les boulotter, le mode chasseur, quand ils essaient de dévorer pacman suivant plusieurs algorithmes, et quelques modes mineurs comme la rentrée et la sortie du bercail.

video

Mais avant tout ça, je vais passer un peu de temps à nettoyer le code, refactoriser, etc. La programmation en assembleur peut vite devenir fouillie si l'on y prend garde, et je veux être capable de me relire dans les mois qui viennent.

Et pour ceux qui ne veulent pas télécharger la vidéo, voilà un screenshot de l'état actuel :
Mouvement des fantômes

25 mars 2019

Afin d'explorer d'autres possibilités de la NES, j'ai commencé à implémenter un jeu de plateformes du genre de Super Mario World. Mais j'en reparlerais sûrement bientôt. Il faut que je bosse sur un éditeur de fond d'écran / sprites pour accélérer le développement.

Mais aujourd'hui je reprends un peu le développement de mon Pacman :

30 mars 2019

Je n'ai pas été très actif sur cette page durant cette semaine. Beaucoup de choses se sont passées. Encore beaucoup de séjours dans les hôpitaux et chez le médecin. Et d'autres projets qui demandent eux aussi à avancer.

Mais je n'a pas laissé tomber le développement NES, loin de là !

J'ai créé un éditeur de fond pour plus facilement mettre en place des graphismes.
Il permet de placer des tiles 8x8 sur un décor qui peut aller jusqu'à 1024x240 assez simplement. Sur le screenshot suivant, on peut le voir en action, avec la liste des tiles disponibles en dessous de la zone principale d'édition.
mon editeur de décor
Et avec ça, on peut sauvegarder son travail et exporter dans un format compressé que je supporte maintenant dans mon code assembleur.

Et du coup pour supporter ça, j'ai refondu une bonne partie de mon code assembleur afin de bien séparer la partie logique du jeu et la partie graphique.
La partie graphique a elle-même été coupée en deux, une avec des fonctions "haut niveau" pour afficher un sprite, définir un score, etc. et une pour discuter directement avec le PPU (Pixel Processor Unit) pendant la VBL. Ça permet d'écrire le code plus facilement maintenant, et ça permettra d'implémenter plein d'effets rigolos pour repousser les limites de la NES.

3 avril 2019

Plein de petits développements en ce moment, mais pas grand chose à montrer.

6 avril 2019

Il y a plus de 15 ans, j'avais créé CraftEd, un éditeur de niveaux pour le jeu Warcraft II de Blizzard ou son implémentation libre nommée freecraft. Pour cet éditeur, j'avais développé un petit algo pour rendre l'édition plus facile en ajoutant automatiquement les tuiles autour d'une tuile donnée pour toujous avoir des transitions douces.
(C'est plus facile à comprendre en regardant la vidéo ci-dessous)

Et donc en développant mon éditeur de backgrounds/niveaux de jeux de plateforme pour NES, j'ai repris les idées de cet algo. Rien de vraiment complexe, il faut simplement lister les cas possibles, mais je trouve ça tout de même super sympa :)

video

Pour mieux comprendre l'avantage de l'algo, voici une autre vidéo qui montre une première zone faite "à la main" puis l'algorithme en action :

video

7 avril 2019

Slow day, peu de motivation.

Petit retour sur le développement de mon pacman NES.
J'ai créé le graphime du fantome effrayé (en bleu foncé). Il reste à ajouter un peu de logique pour qu'on puisse enfin les avaler !

Mais avant cela, j'ai envie de réécrire une partie du code qui est bourré de constantes magiques.

8 avril 2019

Le code du pacman est toujours en cours de refonte, mais pour le coup, il devient plus agréable à modifier.
J'en ai donc profité pour tester les graphismes des fantômes effrayés et ajouté un peu de logique pour qu'ils passent dans ce mode quand pacman mange une super pac-gomme (voir vidéo ci-dessous). J'en ai aussi profité pour animer le base des "robes" des fantômes.

Il reste pas mal de petits bugs à régler dans le déplacement des fantômes et leur affichage, mais rien de grave. La partie la plus importante à gérer maintenant seront les tests de collisions entre pacman et les fantômes, soit pour perdre une vie, soit pour gagner plein de points.

pacman fait peur aux fantômes

10 avril 2019

Mon petit jeu de plateforme commence à prendre forme.
Le personnage peut se déplacer dans un décor qui défile automatiquement, décor qui est plus grand que la mémoire écran, il est donc recalculé en permanence. Le petit moteur physique permet de tester les collisions avec le décor, de sauter, de tomber en chute libre.

La vidéo ci-dessous permet de voir tout ça. Après avoir rencontré la grenouille, le héros pourra bientôt sauter plus haut et donc progresser plus loin dans le décor.

L'intrépide à la rencontre de la grenouille

Je commence aussi à regarder les différents mappers qui existent sur NES afin de profiter de plus de mémoire, ce qui pourrait permettre des effets assez sympa. Le MMC3 semble prometteur.

15 avril 2019

Mon petit jeu de plateforme avance bien. Il y a maintenant un écran titre (qui consomme une grande partie des 256 tuiles disponibles, il va falloir trouver plus astucieux dans l'avenir. Le code se structure de mieux en mieux, et un semblant de scénario se dessine : Notre héros ne saute pas bien haut, et est incapable de visiter certaines parties du niveau. C'est seulement lorsqu'il pourra manger la grenouille (pas vraiment difficile à trouver) qu'il sera capable de faire des bonds gigantesques et arriver à la fin du niveau. Comme d'habitude, cela est illustré par la vidéo suivante.

Il faut maintenant que je me concentre sur les animations pour rendre le tout plus attrayant. Un système de particules et des collisions sprites plus efficaces seraient les bienvenus également. À suivre...

L'intrépide déguste une grenouille

25 avril 2019

Il y a longtemps que je n'ai pas mis cette page à jour, mais plein de choses avancent. Notamment, je développe maintenant en direct sur twitch (n'hésitez pas à suivre ma chaîne ).

Notamment, j'ai pu animer l'écran titre, rendu pas mal de choses paramétrables, et j'ai adopté le mapper 004 (MMC3) utilisé par une énorme partie des jeux NES.

Ce mapper va me permettre d'avoir plus de place disponible pour les graphismes et le code. Celà permet des effets rigolos (mais moches pour l'instant je l'avoue) comme le scrolling différentiel qu'on voit sur la vidéo suivante. Cela va libérer aussi de la place pour avoir des effets sonores et de la musique, au prix d'une certaine gymnastique avec les différentes banques de données, mais bon, tout se paie ma bonne dame ! Je commence à regarder comment fonctionne le côté sonore de la NES afin de pouvoir faire plein de bruit à l'avenir.

scrolling différentiel

1er mai 2019

À l'issue du stream du premier mai 2019, l'écran titre du jeu a maintenant un personnage et une petite animation. Le MMC3 aide bien pour cette astuce.

affichage du titre

8 mai 2019

À l'issue du stream du 7 mai 2019, les ennemis font leur apparition. Rien de bien révolutionnaire, chaque ennemi est un sprite de 8x8 qui se déplace avec sa propre vitesse. La précision de la vitesse est inférieure au pixel/frame, ce qui permet d'avoir plein de vitesses relatives différentes.

apparition des ennemis