Astéroric — fonctionnalités détaillées
Clone d'étude d'Asteroids pour Oric-1 48 Ko · C + assembleur 6502 (cc65) · licence EUPL 1.2
Cette page recense les fonctionnalités d'Astéroric avec, pour chacune, ce qu'elle fait et comment. Le dépôt GitHub (README, ROADMAP, CHANGELOG) reste la référence à jour ; le manuel décrit l'usage.
Sommaire
1. Rendu vectoriel HIRES
Astéroric dessine tout — vaisseau, astéroïdes, soucoupes, torpilles, lettres, chiffres — avec des segments, comme la borne d'arcade à écran vectoriel, mais sur l'écran HIRES bitmap de l'Oric.
Mode HIRES monochrome
240 × 200 pixels, PAPER 0 / INK 7. Le jeu de caractères est copié de $B400 vers $9800 et les trois lignes texte du bas sont nettoyées. L'attribut vidéo posé à l'init est $1E (HIRES 50 Hz, PAL) : avec $1C (60 Hz) un RGB2HDMI ne verrouillait pas le signal sur Oric-1 réel.
Bresenham en XOR
Chaque segment est tracé en XOR : le retracer l'efface, sans sauvegarde du fond. La routine draw_line_xor (src/asm/line.s) est en assembleur auto-modifiant, avec un chemin dédié aux verticales pures et un traitement par octet sur l'axe horizontal. Les sommets partagés entre segments ne sont tracés qu'une fois (Bresenham semi-ouvert), sinon le XOR les annulerait.
Sprites pré-rendus
Les formes qui ne tournent pas (astéroïdes, soucoupes, chiffres) sont pré-rendues et blittées en XOR au lieu d'être retracées segment par segment — c'est la phase 26, qui a fait passer le temps CPU libre à 39,8 %.
Anti-scintillement
Effacement et retracé de chaque entité sont resserrés dans la boucle (erase → tick → draw par entité, positions précédentes mémorisées) pour réduire la fenêtre pendant laquelle un objet est absent de l'écran.
Mouvement sub-pixel
Vaisseau et astéroïdes en virgule fixe 8.8 : vitesses fractionnaires et trajectoires lisses malgré la grille de 240 × 200. Le vaisseau tourne sur 32 angles (11,25°) avec des tables précalculées.
2. Fidélité à l'arcade
La logique de jeu est transposée du désassemblage de la ROM arcade rev 4 (6502disassembly.com) : même CPU que l'Oric, les noms de variables d'origine sont conservés pour la traçabilité.
Astéroïdes authentiques
Quatre formes × trois tailles, sommets extraits de la ROM (travaux de Nick Mikstas), 11 à 13 sommets par forme sans décimation. Jusqu'à six astéroïdes simultanés (limite de performance).
Vagues et fragmentation
Apparition progressive des vagues avec positions et vitesses tirées du générateur pseudo-aléatoire de l'arcade ; un gros astéroïde touché donne trois fragments, le parent réduit ; vitesse des fragments retouchée (phase 29) et vitesse générale réduite (phase 37) après essais.
Cylindre et tore
Le passage d'un bord à l'autre se fait par duplication d'instance (un objet à cheval sur le bord est dessiné des deux côtés), les collisions sont calculées en topologie torique.
Vaisseau, tirs, hyperespace
Vaisseau arcade-fidèle à 5 segments (barre de cockpit, encoches), flamme de poussée, torpilles 2 × 2 px à portée et wraparound arcade, tir en rafale sur SPACE maintenu, hyperespace avec 25 % de risque de mort. Vie supplémentaire tous les 10 000 points, plafonnée à 60 000 ; au plus quatre icônes de vies affichées.
Explosions
Destruction du vaisseau en cinq débris (tables ShipExpVelTbl/ShipExpPtrTbl de la rev 4), explosion des astéroïdes en points éphémères avec le motif de shrapnel exact de l'arcade.
Game over et scores
Séquence en trois temps (explosion → GAME OVER → tableau HIGH SCORES), verrou de 5 s, cinq meilleurs scores conservés en RAM pour la session.
3. Soucoupes
Grande et petite
Deux soucoupes avec IA de tir transposée de l'arcade : tir sur 8 directions ou visée du vaisseau, précision indexée sur le score, la petite seule au-delà de 35 000 points.
Pression de fin de vague
ScrSpeedup : la soucoupe revient plus vite quand il ne reste que quelques astéroïdes ; AstBreakTimer bloque son apparition juste après un astéroïde touché.
4. Son AY-3-8912
L'arcade d'origine utilisait des oscillateurs analogiques discrets ; les effets d'Astéroric sont une recréation originale sur le PSG de l'Oric (aucune donnée audio d'Atari réutilisée).
Player sous interruption
Le son est joué par une routine sous IRQ Timer 1 du VIA à 50 Hz (une mise à jour sur deux à 25 Hz), ce qui libère la boucle principale. L'accès au PSG est protégé (sei, scratch dédié) — deux bugs de corruption sous IRQ ont été trouvés et corrigés.
Trois canaux indépendants
Canal A : effets (tir, explosions S/M/L, poussée, hyperespace, vie supplémentaire) ; canal B : le battement thump-thump qui s'accélère avec le nombre d'astéroïdes ; canal C : le bip-bip continu de la soucoupe. Enveloppes matérielles (R11-R13) pour les décroissances naturelles.
Jingle de titre
À l'entrée de l'écran titre, « Dans l'antre du roi de la montagne » (Grieg, domaine public), en accelerando, legato, avec doublure d'octave sur le canal B.
5. Écran titre et affichage
Police vectorielle A-Z
Depuis la phase 40, une police vectorielle complète (src/font.c) rend « ASTERORIC », « GAME OVER », « PRESS SPACE », « HIGH SCORES », « WAVE » et l'écran CONTROLS par une fonction générique text_draw.
Démo passive
Comme sur la borne, des astéroïdes dérivent derrière le titre ; « PRESS SPACE » clignote ; le jeu attend réellement SPACE (pas de départ sur temporisation).
HUD
Score à chiffres 7 segments, icônes de vies, numéro de vague sur deux chiffres.
6. Clavier et joystick
Scan clavier direct
Le clavier est lu par le VIA et le registre 14 du PSG, colonne par colonne, sans le tampon clavier de la ROM — le jeu ne dépend pas de la ROM Atmos $0265. La matrice complète des 64 positions (src/keys_tab.h) est documentée d'après les tables ROM et validée sur matériel.
Touches configurables
Sur l'écran titre, K ouvre CONTROLS : LEFT, RIGHT, THRUST, FIRE, HYPER sont saisis à tour de rôle, doublons et positions inconnues refusés, ESC annule et restaure. Le mapping vit en RAM (défauts au rechargement).
Joystick IJK
Lecture de l'interface IJK sur le port imprimante (port A du VIA en direct, strobe PB4) avec bit de présence : sans interface, la lecture est ignorée. Le premier protocole (lecture via le PSG) reproduisait un modèle d'émulateur erroné et a été corrigé après retour sur interface physique ; Phosphoric a été corrigé en parallèle. Non remappable.
7. Performance
Le budget est d'environ 40 000 cycles par image à 25 Hz sur un 6502 à 1 MHz.
Ordonnanceur à pas fixe
Phase 28 : pas fixe avec rattrapage, cadencé par le Timer 1 du VIA (20 ms) — fin des à-coups de 60 ms, 25 Hz constants. Un mode 50 Hz adaptatif a été essayé et rejeté.
Mesures
Tracé initial à ~97 cycles/pixel (phase 2), depuis réduit par l'auto-modification, le batch par octet et les sprites pré-rendus ; temps CPU libre en jeu passé de 17,9 % à 39,8 % (phases 24-26). Profil make bench sur 25 millions de cycles.
Synchronisation vidéo
La ligne CB1 (VSync) n'est pas câblée sur l'Oric-1 réel : la cadence vient du Timer 1 en libre-cours, pas du signal vidéo.
8. Spécifications
| Élément | Valeur |
|---|---|
| Machine cible | Oric-1 48 Ko, ROM BASIC 1.0 |
| Écran | HIRES 240 × 200 monochrome, 50 Hz (attribut $1E) |
| Cadence | 25 Hz constants (Timer 1 du VIA, 20 ms) |
| Son | AY-3-8912, 3 canaux, player sous IRQ 50 Hz |
| Entrées | Clavier (scan VIA direct, remappable), joystick IJK (port imprimante) |
| Chargement | asteroric.tap (~23 Ko) avec drapeau autorun, code en $0500 |
| Langages | C (cc65) + assembleur 6502 (ca65) |
| Licence | EUPL 1.2 (code original) ; éléments dérivés d'Atari non couverts |
9. Compilation et tests
Prérequis
cc65 ≥ 2.19 (cc65, ca65, ld65), Python 3 pour les générateurs de tables (ship_verts.s, shapes.s), et Phosphoric pour lancer, capturer et profiler (chemin à ajuster dans le Makefile).
Cibles make
make produit build/asteroric.tap ; make run / make run-joy lancent sous Phosphoric (clavier / IJK émulé) ; make test capture l'écran en headless ; make check compare bit à bit à la capture de référence versionnée ; make host-test compile et exécute les tests hôte x86 ; make bench profile 25 M cycles.
Tests
Tests hôte portables sur le générateur pseudo-aléatoire et sur la table clavier partagée (8 assertions), capture de référence de l'écran titre comparée bit à bit, scénarios de tir scriptés sous Phosphoric (--type-keys) pour la non-régression clavier/joystick.
10. Limites connues
Oric Atmos
Le .tap ne fonctionne pas avec la ROM Atmos (BASIC 1.1), sous Phosphoric comme sous Oricutron. La cible nominale reste l'Oric-1 ; la compatibilité Atmos est un sprint à part.
Meilleurs scores non persistants
Les cinq meilleurs scores et le mapping des touches vivent en RAM : tout est perdu au rechargement. Sauvegarde cassette/disquette en feuille de route.
Six astéroïdes au plus
Limite fixée pour tenir les 25 Hz ; l'arcade en affiche davantage.
Torpilles
Sur matériel réel, les torpilles restent peu visibles à haute vitesse malgré le passage en 2 × 2 px.