Une animation en 2 lignes de Basic

Une animation en 2 lignes de Basic

Le site Amstrad.eu a organisé, à l'occasion de ses 20 ans, un concours de programmation de "deulignes" en Basic. Je me suis prêté au jeu, en apportant ma contribution parmi une vingtaines de productions fort sympathiques. Il s'agit d'une courte animation accompagnée de quelques notes de musique.

1 MODE 1: PRINT"Decrunch":DEG:DIM s(360):FOR i=0 to 360:s(i)=SIN(i):NEXT:FOR i=0 to 9: READ n(i):o(i)=i+1: INK i,1:NEXT:o(3)=2:o(4)=1:c=10:6 WHILE 1:c=c+1/16:b=2-cç10:q=(q+8) AND 127:t=(t+11) MOD 360:g=(g+1) MOD 3:if c "sup" 18 THEN c=c-18:INK 1,26:INK 2,23:INK 3,10:
2 PRINT:d=(c+0.5) AND 3:p=s((c*b*180)MOD 360)*b*8:a=t and 1:SOUND g+1,(1+a)*n(((s(q)+2)*c) MOD 5+5*b-5),14-a,10+2*b-g*2:MOVE 60*(s(t)+2*s(c*20)+240,20:DRAWR q,p,o(d+1):DRAWR 128-q,-p,o(d):WEND:DATA 213,179,142,119,95,239,201,159,134,106

Je vous propose ici de la décortiquer. Pour cela, voici le listing réécrit sur plusieurs lignes:

1 MODE 1: PRINT"Decrunch"
2 DEG:DIM s(360):FOR i=0 to 360:s(i)=SIN(i):NEXT
3 FOR i=0 to 9: READ n(i):o(i)=i+1: INK i,1:NEXT
4 o(3)=2:o(4)=1
5 c=10
6 WHILE 1
7 c=c+1/16
8 b=2-cç10
9 q=(q+8) AND 127
10 t=(t+11) MOD 360
11 g=(g+1) MOD 3
12 if c>18 THEN c=c-18:INK 1,26:INK 2,23:INK 3,10
13 PRINT
14 d=(c+0.5) AND 3
15 p=s((c*b*180)MOD 360)*b*8
16 a=t and 1
17 SOUND g+1,(1+a)*n(((s(q)+2)*c) MOD 5+5*b-5),14-a,10+2*b-g*2
18 MOVE 60*(s(t)+2*s(c*20)+240,20
19 DRAWR q,p,o(d+1)
20 DRAWR 128-q,-p,o(d)
21 WEND
22 DATA 213,179,142,119,95,239,201,159,134,106

Première ligne (1-12)

La ligne 1 n’a rien de particulier, un simple effacement de l’écran en passage en mode 1 et un message pour nous inviter a patienter, le temps de pré-remplir une table sinus, de 360 valeurs, ligne 2, pour que l’animation ne soit pas trop lente.

La ligne 3 permet de remplir le tableau n avec les 10 valeurs stockées à la ligne 22. Ce tableau n contiendra les notes de la musique. Un petit détail, ici il n’est pas nécessaire de dimensionner le tableau, car par défaut, en basic amstrad, les tableaux ont une taille de 10. Petit économie de code.

On profite de la boucle pour initialiser toutes les encres avec la meme couleurs (1 = bleu). Non seulement cela permet de faire démarrer la musique avant l’apparition de l’effet, mais comme on le verra plus loin, cela nos évitera de déplacer le curseur texte en bas de l’écran.

Par ailleurs, aux lignes 3 et 4, on remplit le tableau o avec les valeurs suivantes:

o = [ 1, 2, 3, 2, 1, 6, 7, 8, 9, 10 ]

En réalité, seule les 5 premières valeurs vont nous intéresser. Elles vont nous servir pour choisir les encres pour dessiner les faces de notre pseudo rubber bar.

Ensuite, ligne 5, on initialise notre compteur principal ‘c’ a 10 avant de commencer la boucle principale (ligne 6). Ce compteur ira de 0 à 18, par pas de 1/16 (ligne 7), et pilote la plupart des effets: tous les 16 boucles, la barre fait un quart de tour.

A la ligne 8, on calcule la valeur de b, qui nous permettra d’avoir 2 parties dans notre animation. b est calculé par une division entière, de façon à ce que b vaille 2 lorsque c est entre 0 et 10, et 1 lorsque c est supérieur à 10.

Ensuite on calcule 3 autres compteurs, q (de 0 a 128), t (de 0 a 360) et g (de 0 à 3). Les deux premières serviront respectivement au dessin de la rubber bar (position de la brisure de la ligne, et position horizontale). Le dernier servira à moduler le son (choix du canal audio et modulation de la vélocité).

Enfin, et c’est la fin de la première ligne, nous avons un test, qui nous permet de réinitialiser le compteur principal dès qu’il dépasse 18.La fin de ligne est le seul endroit ou il est possible de placer un test. Lors de cette réinitialisation, on affecte les 3 encres de façon à rendre visible ce qui a été dessiné. Comme c est initialisé à 10, il y aura 8*16 tours de boucle pendant lesquels rien n’est visible à l’écran.

Deuxième ligne (13-23)

La ligne commence par l’instruction PRINT pour que l’écran scrolle de 8 lignes verticalement à chaque boucle (a l’exception des 25 premières boucles, ce qui ne se voit pas, puisque les encres ont été initialisées de la même couleur que le fond – on évite ainsi de devoir placer le curseur en bas de l’écran avec LOCATE 1,25)

Encore quelques variables sont calculées: d, qui permet de changer la couleur à chaque rotation d’un quart de tour de la barre, a qui permet de jouer une note sur deux une octave au dessus

Maintenant que nous avons calculé toutes nos variables, il est temps de s’en servir, à la ligne 17 pour jouer la musique, et aux lignes 18,19,20 pour réaliser le dessin, avant de fermer la boucle WHILE, à la ligne 21.

Le son consiste essentiellement à alterner deux accords, Ré mineur 9 et Do mineur 9, dont les notes sont stockées ligne 23: les 5 premières correspondent au Ré mineur ( Ré Fa La Do Mi ), les 5 suivantes au Do mineur 9 (Do Mib Sol Sib Ré), comme on peut le vérifier avec la table de correspondance suivante (issue du manuel du CPC).

Le choix de la note est calculé par cette formule:

(1+a) * n [ ((s(q)+2) * c) MOD 5+5*b-5]
  • Un note sur deux est jouée a l’octave supérieure, 1+a vaut 1 ou 2 , une fois sur deux
  • Selon b, on choisira une notre parmi les 5 premières (b==1), ou les 5 suivantes (b==2)

Concernant le dessin, on commence par se positionner horizontalement ligne 18, en sommant deux fonctions sinusoïdales, l’une de faible amplitude qui fait un tour toutes les 16 boucles, et l’autre, plus lente et de plus grande amplitude, pour tout déplacer à gauche et à droite de l’écran.

Variante Musicale

Une autre version se trouve sur le disque, et contient essentiellement une variation sur la musique. La boucle principale est plus longue (c va de 0 à 36), et cette fois ci les notes sont piochées parmi 10 notes.

5 c= 30
8 b=b ç 28
12 if c>36 THEN c=c-36:INK 1,26:INK 2,23:INK 3,10
16 a = t MOD b
17 SOUND g+1,(1+a)*n(((s(q)+2)*c) MOD 10),14-a,6+4*b-g*2
23 DATA 239,190,159,127,106,84,169,213,253,95

Le volume est modulé de façon plus flagrante entre la première et le seconde partie.