1 points par GN⁺ 2023-10-09 | 1 commentaires | Partager sur WhatsApp
  • Code source de Elite pour NES, par Ian Bell et David Braben, documenté ligne par ligne, avec des explications pour la plupart des lignes, et reconstruit manuellement à partir du désassemblage du binaire original du jeu
  • Permet de compiler, depuis le source sur des ordinateurs modernes, un jeu entièrement fonctionnel et de générer une image ROM iNES chargeable sur une vraie NES ou dans un émulateur
  • Les variantes prises en charge sont la variante PAL d’Imagineer et la variante NTSC du site personnel d’Ian Bell ; la compilation par défaut utilise la variante PAL
  • Pour explorer le source, on peut le consulter sous une forme lisible sur elite.bbcelite.com ou ouvrir le source annoté dans un IDE ; le contenu du site web et des fichiers source est identique
  • Les prérequis de compilation sont BeebAsm, Python et make sur Mac/Linux ; la compilation Python n’a été testée qu’avec Python 3.x, et Windows inclut make.exe
    • Sous Windows, la compilation se fait avec make.bat, et sous Mac/Linux avec make ; la sortie par défaut est elite-pal.NES dans le dossier 5-compiled-rom-images
    • variant=ntsc permet de générer elite-ntsc.NES
  • Les options de compilation contrôlent notamment le choix de la variante, l’utilisation d’un commander de test proche du maximum, l’omission de la correspondance avec le binaire original et la désactivation de la vérification crc32
    • Exemple représentatif : make variant=ntsc commander=max match=no verify=no
    • crc32.py compare côte à côte les checksums et tailles de fichier du fichier généré et du fichier de référence extrait des sources originales
  • Les variantes PAL et NTSC diffèrent notamment par le nombre de cycles du gestionnaire NMI, l’en-tête Imagineer/Nintendo de l’écran de démarrage, le temps d’attente de l’auto-play de la démo de combat, l’algorithme de checksum des emplacements de sauvegarde, le numéro de version interne, le message de copyright caché, le texte défilant et des constantes de coordonnée y
  • La variante NTSC ne fonctionne pas sur du matériel NTSC réel ; il s’agit d’une émulation NTSC dont le timing NMI a été modifié pour correspondre au mode NTSC de certains émulateurs
  • Aucun fichier de licence n’est fourni ; le droit d’auteur par défaut s’applique, ce qui n’autorise que la lecture et le fork, tandis que la reproduction, la distribution et la création d’œuvres dérivées ne sont pas autorisées

1 commentaires

 
GN⁺ 2023-10-09
Avis de Hacker News
  • Il y a longtemps, quand je travaillais chez Frontier, David Braben m’a raconté une anecdote intéressante à propos de NES Elite. Dans mon souvenir, au départ, le jeu utilisait le timer matériel de la NES pour suivre le temps réel, afin que la physique avance de façon constante même si le framerate variait.
    Lors des contrôles de pré-lancement de Nintendo, certaines premières NES auraient été jugées incompatibles parce que ce timer ne fonctionnait pas correctement ; on m’a dit que Bell/Braben avaient alors fait en sorte que chaque fonction conserve sa propre estimation du nombre de cycles d’horloge utilisés pendant la frame, puis que ces valeurs soient additionnées en fin de frame pour estimer le temps écoulé.
    Mais en regardant le code source sur GitHub, il semble que je me sois mal souvenu, ou que je n’aie pas bien compris ce que Braben disait. Dans elite-source-bank-7.asm, un commentaire indique : « met à jour le timer NMI utilisable à la place du timer matériel que la NES ne prend pas en charge », et il semble qu’ils aient implémenté une sorte d’horloge temps réel en comptant les interruptions non masquables.

    • Tes souvenirs se sont probablement mélangés. Aucune révision de la NES commercialisée n’a jamais eu de timer matériel.
      Les premières puces CPU de la NES contenaient les vestiges bogués et désactivés d’un timer à intervalle programmable : https://www.nesdev.org/wiki/RP2A03_Programmable_Interval_Tim...
      Il a été complètement supprimé dans les révisions ultérieures, et il est possible qu’il ait été activé uniquement dans des environnements comme les kits de développement. Si un jeu dépendait d’une fonctionnalité qui ne marchait pas sur les machines grand public, il était logique qu’il soit refusé aux tests de Nintendo.
      Même si les consoles commercialisées avaient eu un timer à intervalle programmable, il n’aurait vraiment été utile que pour des mesures sous-frame, comme des effets raster précis. Pour mesurer le temps réel, le comptage des NMI est beaucoup plus pertinent. Une NMI se produit au début de chaque frame vidéo, à une fréquence très stable de 60,0988 Hz, et même si le moteur du jeu ralentit et que le framerate varie, le traitement côté CPU ne peut pas affecter le timing du signal vidéo.
      À noter que le matériel audio peut aussi générer des interruptions de timer, et que beaucoup de puces d’extension disposent de compteurs de scanlines pour synchroniser le rendu. Les façons de mesurer le temps ne manquent pas sur NES.
    • Andrew Davie, de BEAM Software (Melbourne House), m’a raconté quelque chose de similaire. Il a développé Super Glove Ball, et disait que Nintendo fournissait très peu de documentation utile, si bien qu’il fallait recourir à divers hacks pour des choses comme le calcul du framerate.
      Lorsqu’ils essayaient de faire approuver un jeu par Nintendo, on leur aurait dit qu’il ne fonctionnait pas sur une version particulière de la NES américaine, ou qu’il provoquait une surchauffe du système. Le calendrier de sortie était serré, donc il avait dû prendre l’avion jusqu’au siège de Nintendo pour résoudre le problème ; dans mon souvenir, cette version particulière avait été distribuée à moins de 100 exemplaires.
      J’ai retrouvé plus tard des notes pour un livre non publié, et en réalité c’était un peu différent. Les tests des jeux ne se limitaient pas au gameplay : il fallait les tester sur toutes les variantes de consoles NES capables de les exécuter. Andrew Davie, de Beam Software, se souvenait s’être rendu en personne dans les bureaux de Nintendo à Washington parce que “The Three Stooges” posait problème sur une NES utilisée pour les tests.
      Il disait qu’il y avait « environ 23 variantes de machines » à valider, avec différentes combinaisons de fabricants de puces, et qu’en raison du manque de documentation officielle, il avait fait en sorte que les données de sprites soient écrites directement toutes les 2 secondes au lieu de les écrire en RAM comme officiellement recommandé, ce qui faisait trop chauffer la NES et provoquait du clignotement de sprites dans tout le jeu. Après correction, le jeu a été approuvé pour sortie ; on lui aurait dit que la combinaison de NES en question n’existait qu’à environ 5 exemplaires dans tous les États-Unis, et qu’elle avait été retirée de la batterie de tests de Nintendo.
  • J’ai récemment commencé la suite, Elite: Dangerous. Elle n’est pas sans défauts, mais c’est une expérience assez incroyable.
    Voir des éléments de jeu hérités de la version de 1984 m’a étrangement ému. Les vaisseaux, et surtout les stations Coriolis, que l’on voyait à l’époque en graphismes vectoriels sur un écran à mappage mémoire de 16 Ko dernier cri, transformés en rendu 3D complet en 4K/60 fps : c’était plus touchant que je ne m’y attendais.
    Découvrir enfin l’intérieur détaillé d’une Coriolis, avec panneaux publicitaires, plantes et équipement d’amarrage, m’a honnêtement presque mis les larmes aux yeux. Malgré ses difficultés actuelles, ce jeu est un héritage précieux, et j’espère qu’il continuera d’exister sous une forme ou une autre.

    • J’ai vraiment aimé Elite Dangerous. Je n’y joue plus depuis l’arrêt du support des consoles, mais malgré le grind et le contenu parfois superficiel, les moments passés à piloter des vaisseaux avec des amis me manquent.
      S’amarrer manuellement à une station en écoutant Blue Danube a toujours été une expérience apaisante.
      Je me demande pourquoi les simulateurs et jeux spatiaux finissent toujours avec autant de problèmes. Elite Dangerous donne l’impression de ne plus aller nulle part, Star Citizen ressemble à une bêta éternelle, et KSP2 a aussi été décevant.
    • J’ai beaucoup joué à Elite: Dangerous depuis l’open beta. C’est un jeu magnifique, avec un sound design extraordinaire.
      Mes réflexions écrites il y a 9 ans : https://hypertexthero.com/elite-dangerous-education/
      L’extension Odyssey est aussi amusante, et j’aimerais qu’un jour ils ajoutent des sorties extravéhiculaires dans l’espace et des missions en apesanteur.
  • Il existe aussi Elite - The New Kind, une version en C presque fidèle à l’original : https://github.com/fesh0r/newkind
    Créée par Christian Pinder : https://www.christianpinder.com/games/
    La page d’accueil Elite d’Ian Bell vaut aussi le détour, avec plusieurs versions originales : http://www.ianbellelite.com/

    • Ian Bell et son site méritent clairement d’être mentionnés. C’est là qu’on peut trouver le code source original de la version BBC Micro, et ces disquettes originales sont la base de tout mon travail d’annotation d’Elite, y compris le projet NES
      Le cœur de la version NES de 1991, soit environ 30 % de la ROM de 128K, est essentiellement la version BBC Master de 1986, elle-même une évolution de la version BBC Micro originale de 1984. Les versions Commodore 64 et Apple II appartiennent à la même lignée, et le développement s’est aussi fait sur BBC Micro
      La majeure partie du code des banques 0, 1 et 2 vient directement de la version BBC originale, avec quelques morceaux supplémentaires dans la banque 7. De nouvelles routines graphiques, sonores et de contrôleur ont été greffées devant, mais le cœur qui bat reste la version Beeb
  • Ian Bell, l’auteur d’Elite, a dit que la version NES était sa version 8 bits d’Elite préférée
    Globalement, il aurait préféré le portage 32 bits sur Archimedes

    • La citation originale est la suivante : « Techniquement, mes plus grandes réussites publiées sont d’avoir fait tenir la version cassette BBC d’Elite, écran compris, dans 32K de RAM, et la conversion d’Elite pour Nintendo Entertainment System, avec affichage par mappage de caractères et une seule manette NES. La NES est ma conversion publiée préférée, et elle n’était pas considérée comme techniquement possible avant que nous y parvenions. »
      L’interview complète se trouve ici : http://www.elitehomepage.org/archive/b5081501.htm
      J’interprète cela comme voulant dire que sa version préférée est la version cassette BBC Micro, et que sa conversion préférée est la version NES. Mais je suis peut-être un fanboy de la BBC et j’interprète ça de manière optimiste
    • Mais ils ont quand même retiré le commerce d’esclaves et de drogue :)
    • Arch Elite est clairement le sommet
    • Le récent portage amateur sur Oric Atmos est aussi plutôt bon : https://www.youtube.com/watch?v=kC1cJGLGlxo
  • J’aime bien le fait qu’il y ait ce genre de shim de changement de banque au début de chaque banque
    SEI / INC $C006 / JMP BEGIN
    L’explication détaille que c’est fait pour économiser de l’espace, mais à mes yeux la seule raison pour laquelle le JMP est nécessaire tient au pipeline d’instructions, et il me semble qu’un simple NOP pourrait suffire à le vider
    Donc mon optimisation de 2 octets serait : SEI / INC $FFFD ; utilise à la place le C0 dans le vecteur d’instruction / NOP

    • Dire que « la seule raison pour laquelle le JMP est nécessaire tient au pipeline d’instructions » est juste, mais cela a aussi du sens pour un humain. L’exécution commence dans la banque 7, donc on saute vers la banque 7
      À côté de ça, sur Game Boy, le point d’entrée se trouve dans ROM0, la banque fixe, donc au moins avec les MBC courants ce problème ne se pose pas dès le départ
  • Comme point de comparaison, il y a le code source d’Oolite, un clone open source d’Elite écrit en Objective-C : https://github.com/OoliteProject/oolite
    https://oolite.space
    https://news.ycombinator.com/item?id=7894145

  • J’y ai joué sur C64 quand j’avais 8 ans. Trente ans plus tard, je ne comprends toujours pas ce code

  • Rien que la banque 0 compte 18 305 lignes d’assembleur ; je n’arrive même pas à imaginer comment on pouvait garder tout ça en tête

    • À l’époque du 6502, on ne gardait pas tout dans sa tête : on conservait ça dans des liasses de papier listing pour imprimante matricielle à entraînement par tracteur. Il y avait généralement aussi plein de notes et de corrections au crayon
    • J’ai fait un peu de développement embarqué pour machines 8 bits à l’époque moderne, et j’ai un profond respect pour les ingénieurs qui faisaient ça dans les années 80.
      Même avec des outils de tout premier ordre, suivre le code devait demander une organisation et une discipline énormes. J’ai étudié des assembleurs du début des années 80 pour Hitachi 6303[0]/Motorola 6800[1], et ce que les gens ont accompli avec de telles contraintes d’outillage est impressionnant.
      Par exemple, les deux assembleurs ci-dessous limitaient les labels à 6 caractères seulement, et n’avaient pas non plus de labels locaux réservés à l’intérieur d’une sous-routine. Dans mon travail, j’avais limité les labels à 40 caractères pour qu’ils restent descriptifs, et c’était déjà le cas.
      Cela dit, la relative simplicité de ces architectures est vraiment rafraîchissante par rapport au travail embarqué sur les systèmes modernes. Pouvoir garder à peu près tout l’état du système en tête est clairement un avantage.
      0: http://www.bitsavers.org/components/hitachi/_dataBooks/U24_H...
      1: http://www.bitsavers.org/components/motorola/6800/exorciser/...
    • Nous étions meilleurs à l’époque. Plus sérieusement, tout projet d’une certaine taille exigeait presque forcément d’écrire ou d’imprimer beaucoup de code sur papier. Il fallait vraiment beaucoup de papier
    • Ce code est extrêmement bien organisé et bien documenté. Je ne sais pas quel était le niveau de documentation du code original, mais j’imagine qu’il y avait beaucoup de notes manuscrites sur les listings.
      Globalement, la programmation en assembleur n’est pas si différente des langages de haut niveau. On organise le code en fonctions, en blocs, etc. Écrire un immense mur de code avec des sauts entremêlés, c’est s’attirer de sérieux problèmes
    • Du point de vue d’un ingénieur moderne, je ne vois pas bien pourquoi il faudrait garder tout ça en tête
  • Dommage que ce ne soit pas du logiciel libre. Si j’avais été le créateur d’Elite, j’aurais publié tous les portages du jeu sous licence libre.
    Quoi qu’il en soit, aujourd’hui on peut jouer à Oolite sur un netbook bon marché et, grâce à l’immense liste d’extensions, y prendre autant, voire plus de plaisir

    • C’est parce que Braben a été pointilleux sur les questions de copyright. Bell, en revanche, était quelqu’un de bien et a publié la plupart de ce qu’il avait écrit lui-même
    • L’histoire autour de cette publication remonte à plusieurs décennies.
      Côté Braben, il semble qu’il ne voulait pas affaiblir ses droits d’auteur, puisqu’il travaillait sur Elite 4/Elite: Dangerous
  • Tout code source devrait être documenté à ce niveau