Obligement - L'Amiga au maximum

Mercredi 06 mai 2026 - 08:42  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur Mastodon




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Assembleur - Desire "ONE" : la programmation d'une BBS-intro sur Amiga
(Article écrit par Yragael et extrait de www.stashofcode.fr - août 2019)


Enfin, la dernière ! Au terme de quelques années de retour dans le passé pour revisiter la programmation du matériel de l'Amiga, voici Desire "ONE", la dernière des productions d'une série dont l'idée était de rendre hommages aux grandes figures de ce que fut la scène. Après avoir successivement salué le mérite des graphistes dans Scoopex "TWO", des codeurs dans Scoopex "ONE", des déplombeurs dans Scoopex "THREE", c'est donc sur une salutation aux administrateurs système (alias "sysops") que le rideau tombe définitivement.

Assembleur
Desire "ONE" : une BBS-intro sur Amiga

Sans doute, il resterait encore bien assez d'aspects du matériel à explorer pour trouver l'occasion de produire des hommages à bien d'autres figures : musiciens, échangeurs, fournisseurs, diffuseurs, éditeurs et qui sais-je encore. Toutefois, il faut rester au diapason du progrès technique, et sans qu'il s'agisse de prétendre en devenir un spécialiste, mais juste savoir un peu de quoi on parle, cela impose actuellement de se former à de sujets denses et divers comme jamais : info-nuage ("cloud"), apprentissage automatique ("machine learning"), piratage éthique ("ethical hacking"), lancer de rayons ("ray-tracing"), etc. Le temps étant compté - le développement n'est pas mon métier -, cette mise à l'heure m'apparaît prioritaire.

La production dont il sera question ici est une BBS-intro. Autrement dit, c'est une intro consacrée à la promotion d'un Bulletin Board System (BBS). Elle est le fruit d'une collaboration avec le groupe Desire, qui reste très actif sur plusieurs scènes, notamment la scène Amiga.

Comme toujours : code, données et explications dans tout ce qui suit...
  • Mise à jour du 15/09/2019 : la BBS-intro a été distribuée lors de la Function 2019 qui s'est tenue à Budapest, et l'archive contenant l'ADF ainsi que le source et les données est donc maintenant proposée au téléchargement.
A écouter en lisant l'article : Nightscape - Stellardrone.

Cliquez ici pour télécharger l'archive contenant l'ADF, le code et les données de la BBS-intro.

La petite histoire

Une fois n'est pas coutume, commençons par la petite histoire. Il est vrai qu'elle permet d'éclairer les raisons pour lesquelles les explications techniques qui vont suivre, partie par partie, sont parfois succinctes.

Début 2019, le programme que je m'étais donné - produire une intro par rôle de la scène Amiga auquel rendre hommage : codeur, graphiste, etc. - n'est pas achevé. Toutefois, j'ai encore quelques effets en stock, programmés durant le très productif été 2017, quand je m'étais remis à programmer sur Amiga pour écrire des articles destinés à la rubrique "Vintage" de Programmez!. Par ailleurs, je trouve qu'il était temps de passer à autre chose, ayant commencé à travailler sur d'autres sujets assez conséquents, dont l'apprentissage automatique ("machine learning") en Python.

Tout cela me pousse à rassembler au plus vite ces effets sous la forme d'une ultime production.

Cette fois, c'est vers le groupe Desire que je me retourne, plus particulièrement Ramon B5, qui m'a bien aidé en me permettant de changer de graphiste en catastrophe pour sortir Scoopex "TWO" dans les délais. En retour, je m'étais engagé à produire une BBS-intro pour le groupe.

Après avoir fait le tour des effets que je pourrais utiliser, je propose début juin 2019 le scénario suivant à Ramon B5, qui l'adopte - enfin, ce n'est pas comme si je lui laissais le choix, car je n'entends pas du tout me lancer dans de nouveaux effets... :
Hi Ramon

As told before, the intro is a tribute to sysops and you mentionned Fastline, which is (or was?) one of your BBS. So this may be a BBS intro for Fastline.

The first part is the signal made of particles, the second part is the wall of scrolls and the last part is the wired mesh.

We may use those FX to tell a little story about the way data exchange on wire evolved in time. First, there was nothing (text screen). Then a carrier to connect people (particles). So people can chat (wall of scrolls) on the BBS. Then come the Web (wired mesh), if ever Fastline moved to the Web. This is a little bit far fetched, but we do with whatever FX is available.

So we would need to tell the story with text screens between the FX. The texts must be short. They are:

1/ Opening, to tell that the carrier is going to be heard
2/ After the carrier, tell that people from all over Europe connected to the Fastline BBS and start talking(texts will be in several language, provided they use the A...Z characters)
3/ After people talked, tell that the BBS era is over and now is the WWW era
4/ Closing, tell people that they can connect to whatever Desire web site to keep talking
Je dois alors dire que c'est une bonne surprise, car Ramon B5 se montre particulièrement efficace pour dénicher un graphiste et un musicien. Sans doute, l'affaire traîne durant l'été, du fait que ces artistes sont en vacances. Toutefois, c'est ma très grande faute, car je n'ai pas voulu leur demander de produire quoi que ce soit tant que le code n'était pas terminé.

Au total, la petite histoire s'est donc révélée nettement moins chaotique que celle que j'ai narrée dans le cas de Scoopex "TWO". Ce qu'il convient de retenir, c'est que pour ce qui me concerne, à savoir le code, je me suis surtout contenté de rassembler, ce qui m'a permis de soigner assez les transitions entre les différentes parties de la BBS-intro. Ainsi, les particules disparaissent, les textes défilants s'arrêtent, le maillage se dissout, les carrés se stabilisent progressivement, et tout cela est conjugué à des fondus de palette qui viennent en rajouter à l'impression que tout s'enchaîne calmement.

Le signal : un système de particules

Dans cette partie, un générateur de particules circule le long d'une courbe. A intervalles réguliers, il génère une particule qui s'éloigne dans une direction corrélée à celle du générateur. Tandis que le temps passe, la particule ralentit et s'assombrit, jusqu'à disparaître. D'ici là, si elle atteint un bord de l'écran, la particule rebondit dessus.

Assembleur
Le signal : une utilisation du système de particules

L'effet s'appuie sur le même système de particules que celui de Scoopex "ONE", et a donc déjà été amplement décrit. La seule différence est dans le calcul des coordonnées du vecteur directeur de la trajectoire d'une particule à sa génération.

Dans le cas précédent, ce vecteur directeur était une approximation de la tangente à la trajectoire, des plus grossières parce que réduite à la variation (DX, DY) des coordonnées du générateur entre la trame précédente et la trame courante. Dans le cas présent, ce vecteur est légèrement perturbé de manière pseudo-aléatoire en rajoutant des quantités aux valeurs absolues de DX et DY :

	btst #0,VHPOSR+1(a5)			;Randomize (|DX| += n * bit #1 of raster X position)
	beq _sngNewParticleNoRandomnessX
	addq.w #6,d0				;n set to 6
_sngNewParticleNoRandomnessX:
	btst #0,VHPOSR(a5)			;Randomize (|DY| += n * bit #0 of raster Y position)
	beq _sngNewParticleNoRandomnessY
	addq.w #2,d1				;n set to 2
_sngNewParticleNoRandomnessY:

Comme il est possible de le constater, l'aléatoire réside dans la position du raster au moment où le calcul est effectué. Ça ne va pas chercher loin, mais cela suffit pour parvenir au résultat escompté, à savoir que les particules forment une traîne ni trop prévisible ni trop imprévisible du générateur, une queue de comète pour ainsi dire. Pour cela, il était notamment indispensable que les trajectoires de particules générées à haute fréquence adoptent des vecteurs directeurs distincts.

Quant à la trajectoire du générateur, nul besoin était de la calculer en temps réel. Elle a été sagement précalculée dans Excel, sous la forme d'une composition de sinus et cosinus qui pourrait servir d'introduction à un cours sur la décomposition en série de Fourier :

Assembleur
Précalcul de la trajectoire de la particule dans Excel

Le BBS : un mur de textes défilants au Blitter

Dans cette partie, l'écran est découpé en textes défilants horizontaux et verticaux. Du texte y défile à différentes vitesses, affiché à l'aide de polices à largeur variable de différentes tailles.

Assembleur
Un mur de textes défilants en polices à espace variable

Formalisé sous Excel, le découpage est le suivant - les numéros indiquent l'ordre dans lequel les textes défilants sont démarrés :

Assembleur
Composition du mur de textes défilants

Il ne s'agissait certainement pas de rentrer dans le détail des formats de police à largeur variable du système pour afficher le texte. A la place, des polices de ce type ont été converties de leur format vectoriel au format bitmap sur PC, à l'aide d'un outil certainement apprécié par tous ceux qui programment en 3D : Codehead's Bitmap Font Generator :

Assembleur
Codehead's Bitmap Font Generator

Toutefois, cet outil ne produit qu'un bitmap. Il fallait le travailler pour en extraire des informations nécessaires, notamment la largeur de chaque caractère et l'abscisse de son premier pixel utilisé, et plus généralement ordonner les pixels sous une forme plus facilement exploitable pour afficher un texte défilant. La transformation du bitmap a été effectuée à l'aide d'un outil programmé par l'occasion en JavaScript :

Assembleur
Le convertisseur de police à largeur variable

Au final, un bitmap est converti dans un fichier ".vfnt", dont le format est sur mesure :
  • 0 : nombre de caractères.
  • 1 : code ASCII du premier caractère.
  • 2 : largeur d'un caractère (N pour 2N pixels).
  • 3 : hauteur d'un caractère (N pour 2N pixels).
  • 4 : marge à droite.
  • 5 : largeur de l'espacement entre deux caractères.
La marge ("padding") à droite est un espace vide ménagé sur la droite du caractère pour que le suivant n'y colle pas immédiatement, quand bien même l'espacement entre les caractères est nul. A vrai dire, je ne me souviens même plus pourquoi j'avais prévu cela...

Suit une table d'informations relatives aux caractères. Pour chacun, on trouve simplement :
  • 0 : abscisse où le caractère commence dans son plan de bits.
  • 1 : abscisse où le caractère se termine dans son plan de bits, plus la marge à droite.
Suivent les données proprement dites des caractères, c'est-à-dire les unes après les autres, les lignes du plan de bits de chacun.

L'affichage d'un texte défilant ne présente aucune subtilité. A chaque étape, la partie qui doit rester visible est recopiée avec le Blitter en étant décalée dans le sens du défilé, et une nouvelle partie du dernier caractère et/ou du caractère suivant est affichée dans la partie libérée. La seule subtilité est que cette nouvelle partie est affichée différemment selon que le texte défilant est horizontal ou vertical :
  • Si le texte défilant est horizontal, le Blitter est utilisé pour tracer des droites dont le motif correspond à une colonne de seize pixels d'un caractère - ce qui peut requérir plusieurs tracés de droite si la hauteur du caractère est de plus de seize pixels. Cette technique a déjà été décrite ici, où elle sert à tracer les colonnes de seize pixels des caractères d'un défilement sinusoïdal. Pourquoi utiliser le Blitter ? Car cela permet de se dispenser d'opérations compliquées de masquage et de décalage pour positionner ou effacer des bits dans colonnes de bits traversant le même mot de lignes successives de l'écran.

  • A l'inverse, si le texte défilant est vertical, c'est le processeur qui est utilisé pour faire exactement la même chose. Pourquoi le processeur ? Car il n'est jamais ici question que d'écrire un ou plusieurs mots composant une colonne de pixels d'un caractère. Pas besoin d'opérations compliquées de masquage et de décalage, donc pas besoin de Blitter pour se simplifier la vie.
Pour optimiser tout cela, on voit qu'il était nécessaire que la hauteur d'un caractère soit toujours multiple de 16. C'est pourquoi le mur n'est composé que de textes défilants de 16, 32 ou 64 pixels de hauteur quand ils sont horizontaux, de largeur quand ils sont verticaux.

Le web : un maillage 2D déformé par un attracteur

Dans cette partie, un maillage semble s'avancer et reculer périodiquement, tandis qu'il subit une déformation localisée, certains de ses points semblant attirés par un attracteur invisible en mouvement. De plus, le maillage est coloré, comme s'il disposait d'un relatif relief.

Assembleur
Un maillage déformé par un attracteur invisible

La mécanique de base est reprise d'un bref programme JavaScript présenté ici, que j'ai écrit il y a bien longtemps, quand je m'initiais à la programmation de nuanceurs de vertex pour WebGL.

Le maillage n'est donc pas en 3D, mais en 2D. Il est composé de MESH_DX sur MESH_DY points. A chaque trame, un point est déplacé le long du vecteur joignant l'attracteur à ce point, selon une amplitude qui dépend du rapport entre la "distance" du point à l'attracteur et la force qu'exerce ce dernier. La distance est évoquée entre guillemets, car on s'en remet à une approximation :

d = max (|dx|, |dy|) + (min (|dx|, |dy|) >> 2) + (min (|dx|, |dy|) >> 3)

Cette approximation est d'ailleurs sans doute déjà d'une précision superflue, car comme toujours dans un effet, seul le résultat compte. Autrement dit, la rigueur des calculs importe peu, il suffit qu'à l'écran, "ça passe" bien.

L'attracteur est en rotation sur un cercle centré à l'écran, de rayon MSH_RADIUS. Sa force varie selon une interpolation linéaire entre un minimum MSH_STRENGTH_START et un maximum MSH_STRENGTH_END en MSH_STRENGTH_STEPS étapes, le minimum et le maximum étant inversés quand la force atteint une de ces bornes.

Ainsi, la force que l'attracteur exerce sur un point varie indépendamment de ce point - elle oscille entre deux bornes -, et elle varie aussi en fonction de ce dernier - elle décroît tandis que la distance du point à l'attracteur s'accroît. Comme toujours, c'est donc la conjugaison de transformations élémentaires qui permet de produire une transformation en apparence complexe, puisque le maillage semble comme en 3D.

Le seul point un tant soit peu délicat est le découpage. En effet, la déformation du maillage peut faire sortir de points de la surface de l'écran. Une solution aurait consisté à se donner de la marge à l'aide d'une surface de rendu plus grande que celle affichée. Il aurait ainsi été possible de tracer des droites débordant de l'écran, dans une certaine limite, sans se préoccuper d'avoir à les découper. Pour s'amuser, c'est une solution moins confortable qui a été adoptée, qui consiste donc à découper.

Le découpage d'une droite n'est pas une opération compliquée - ce n'est pas comme découper un polygone. La première étape consiste à tirer les extrémités de la droite à découper, pour commencer toujours par le point le plus haut. S'ensuit un découpage vertical, qui s'appuie tout simplement sur le théorème de Thalès. Les points sont alors triés pour commencer toujours par le plus à gauche, avant de procéder au découpage horizontal. Trier les points permet de limiter les opérations visant à tester le signe.

Enfin, la coloration du maillage est très simplement produite par rémanence. A chaque trame, le plan de bits 2 devient le 3, le 3 devient le 4, et le 4 est retiré de la vue pour servir de tapon arrière à la trame suivante. Quant au plan de bits 2, il est remplacé par le tampon arrière de la trame courante, c'est-à-dire le plan de bits qui n'est pas affiché, où la nouvelle image de l'animation du maillage vient d'être rendue. Dans ces conditions, les bits utilisés dans les plans de bits se superposent d'autant plus que le maillage a peu bougé d'une image à une autre. Cela de mettre plus ou moins en relation l'amplitude du mouvement avec des couleurs via une palette dont les couleurs tirent sur le violet là où le maillage bouge peu, et sur le bleu là où il bouge beaucoup.

Au terme de la partie, le maillage disparaît progressivement. Toutes les droites étant tracées au Blitter - abusivement d'ailleurs, car il ne faudrait recourir au coprocesseur que si cela en vaut la peine -, l'effet est simple à produire. En effet, comme dans le cas de l'affichage de textes défilants verticaux décrit plus tôt, il s'agit de jouer sur la valeur de BLTBDAT, qui correspond au motif que le Blitter répète lorsqu'il trace une droite. Partant donc d'une valeur de $FFFFcorrespondant à un trait plein, il s'agit d'effacer progressivement des bits de cette valeur pour effacer progressivement la droite. Quant au choix du nouveau bit à effacer à chaque étape, il doit être dicté par l'esthétique. Ici, l'idée est de répartir au mieux les bits effacés le long de la droite :

Assembleur
Animation du motif d'une ligne du maillage

Consummatum est...

Et voilà ! Comme d'habitude, il convient de conclure par les inévitables salutations. Je remercie donc tout particulièrement :
Et je salue ceux qui sont allés jusqu'à présenter la BBS-intro à la Function 2019, sur du vrai matériel :

Assembleur
Desire "ONE" à la Function 2019

Comme indiqué au début de cet article, cette fois, c'est vraiment la dernière. WinUAE ne demeurera sur mon PC que pour me permettre de voyager dans le passé l'espace d'un instant, et non plus pour programmer quoi que ce soit.

Rétrospectivement, je trouve assez amusant d'avoir sans doute plus produit sur celle qui restera ma machine préférée l'espace de ces quelques années - de l'été 2017 au printemps 2019, mais surtout en 2018 - que durant la décennie 1990. Mais il faut dire qu'à l'époque, je découvrais la programmation, sans bénéficier par ailleurs de la possibilité de pouvoir créer aussi facilement des outils pour m'aider que celle qu'un navigateur Web peut offrir. Et finalement, je n'ai passé guère plus de temps à sortir des cracktros, si j'en juge d'après les dates rapportées sur Janeway. Tout de même, je ne faisais alors presque que cela, ce qui n'a certainement pas été le cas en cette fin de décennie, comme chacun peut en juger par la variété des sujets abordés sur ce blog...

Il faut mesurer la chance que le Web peut offrir de remonter ainsi dans le temps pour se replacer dans le contexte d'une époque dont des passionnés s'échinent à préserver ce qui en fit pour eux le principal attrait. Ils ne luttent pas contre le flot général du temps qui s'écoule inexorablement, emportant tout vers l'oubli - qui le pourrait ? Au prix d'efforts considérables, ils ont creusé un canal pour en divertir ce qu'il pouvait charrier à leurs yeux d'important, qui débouche sur un bassin de rétention où tout est préservé, véritable fontaine de Jouvence pour celui qui, comme eux, a connu l'époque, s'il se décide à y tremper le pied.

Le défi n'est plus que de passer la main. Mais qui, aujourd'hui, parmi ceux qui ne l'ont pas connu alors, s'intéresse à l'Amiga ? Je doute qu'ils soient bien nombreux. Tout de même, puisqu'après tout, il ne suffit jamais que d'un seul pour sauver une ville, la tâche doit être de susciter des vocations en répandant la bonne parole. Si Scoopex "ONE", Scoopex "TWO", Scoopex "THREE" et Desire "ONE", ainsi que tous les articles publiés sur ce blog et dans Programmez! peuvent un jour y aider, mon heure de gloire sera celle-là.


[Retour en haut] / [Retour aux articles]