Petite boule qui rebondit

un pet, un vic, un 64...

Modérateur : Politburo

Répondre
Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Petite boule qui rebondit

Message par Ben » 08 juil. 2019 18:12

Salut à tous,

Je ne sais pas très où je dois poster, comme j'ai fait le programme sur C-128, je poste ici.

Voici un programme qui simule une balle (qui laisse sa trace) qui rebondit sur le bord de l'écran. Rien de bien extraordinaire , c'est sûrement un des premier programme qu'on code pour tester le mode graphique.
Ball1.png
Ball1.png (15.43 Kio) Consulté 2018 fois

Code : Tout sélectionner

10 graphic 1,1
20 x=1:y=1:dx=1:dy=1
30 if x=0 or x=319 then dx=-dx
40 if y=0 or y=199 then dy=-dy
50 x=x+dx:y=y+dy
60 draw 1,x,y
70 goto 30
Comment faire pour obtenir le même résultat, mais sans les "IF" :-)

Ben

PS: J'espère que je ne recycle pas une vielle question :-/

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2030
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Petite boule qui rebondit

Message par C.Ret » 08 juil. 2019 19:31

Bien sympa ce petit problème.

Il doit y avoir moyen de faire disparaitre les IF en utilisant une formule du style:
DX = DX * (-1)^ABS( (X=0) OR (X=319) ) et DY= DY * (-1)^ABS( (Y=0) OR (Y=319) )

Comme (-1)^0 fait 1, et que (-1)^1 fait -1 les signes respectifs ne changeront qu'aux valeurs indiquées.
Mais je ne suis pas sûr que cela soit plus rapide qu'un IF.

Code : Tout sélectionner

10 graphic 1,1
20 draw 1,1,1 : dx=1:dy=1
30 do
40 :  dx=dx*(-1)^abs( (rdot(0)=0) or (rdot(0)=319) )
50 :  dy=dy*(-1)^abs( (rdot(1)=0) or (rdot(1)=199) )
60 :  draw 1,+dx,+dy
70 loop
où RDOT(0) et RDOT(1) donnent respectivement les coordonnées x et y du curseur graphique (dernier pixel dessiné)
et les deux signes + dans la commande DRAW indiquent l'amplitude du déplacement du curseur graphique selon les axes x et y.

En effet, la commande DRAW du Commodore C128 connait plusieurs types d'adressage des pixels :
DRAW 1 , X , Y ou DRAW 1 TO X,Y respectivement allume ou trace jusqu'au point de coordonnées absolues X et Y
DRAW 1 ,+X,+Y ou DRAW 1,-X,+Y ou DRAW 1 TO -X,-Y , etc allume un point ou trace un trait vers les coordonnées relatives dans le sens indiqué (+ ou -)
DRAW 1 , L;D ou DRAW 1 TO L;D allume un point ou trace jusqu'au point distant de D pixels dans la direction indiquée par l'angle D (en degrés)



En fait, le plus rapide et de considérer que l'on a affaire ici à une machine à quatre états.
Chacun de ces états correspond au sens de déplacements selon l'axe X et l'axe Y.
Dans le code ci-dessous, les lignes 10 20 30 et 40 correspondent respectivement aux déplacements (dx;dy) = { (+1;+1) (+1,-1) (-1,+1) (-1;-1) }

Chacune de ces lignes indiquent le changement d'état à prendre en considération selon le sens de déplacement et surtout le reste à parcourir. Les restes à parcourir sont pour chaque état calculés dans les variables A et B.
Bien évidemment, c'est le plus petit déplacement qui limite le tracé suivant. Et c'est donc lui qui donne le nouvel état pour la traversée suivante.

La ligne 90 trace le déplacement pour chaque état. Dans l'exemple donné, et pour aller plus vite, je trace toute la traversée à l'aide d'un DRAW 1 TO X,Y.
Comme cela va très vite, j'ai inséré un GETKEYB$ , il faut donc appuyer sur une touche pour avancer d'une traversée à l'autre.
La ligne 90 aurait pu contenir une animation ou une boucle traçant lentement ou déplaçant un SPRITE. Remplacer le GETKEY B$ par un SLEEP 1 est aussi une solution recommandable.

Le code est écrit pour faciliter la lecture, on peut encore le réduire.

Code : Tout sélectionner

 5 x=1:y=1: graphic 1,1 : draw 0,x,y
10 gosub 90 : a=319-x : b=199-y : if a<b then x=x+a : y=y+a : goto 30 : else x=x+b : y=y+b : goto 20
20 gosub 90 : a=319-x : b=    y : if a<b then x=x+a : y=y-a : goto 40 : else x=x+b : y=y-b : goto 10
30 gosub 90 : a=    x : b=199-y : if a<b then x=x-a : y=y+a : goto 10 : else x=x-b : y=y+b : goto 40
40 gosub 90 : a=    x : b=    y : if a<b then x=x-a : y=y-a : goto 20 : else x=x-b : y=y-b : goto 30
90 draw 1 to x,y : getkeyb$ : return   

La ligne 5 initialise le tracé comme le code donné par ben et on commence dans l'état 1 (ligne 10) c'est à dire (d;dy)=(+1;+1).
On peut modifier le tracé original en modifiant les coordonnées initiales X=1:Y=1 et en insérant un GOTO vers l'état, c'est à dire la direction initiale.

PetiteBoule C128D (CRT Thomson).gif
PetiteBoule C128D (CRT Thomson).gif (42.87 Kio) Consulté 1987 fois
Dernière édition par C.Ret le 08 juil. 2019 21:57, édité 5 fois.
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator | HP-15C | CASIO fx-602p + FA-1. .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 08 juil. 2019 20:57

Mais dans ton programme, il y a des "IF", le but est de ne plus en avoir du tout. :-)

Il y a de l'idée dans ta première proposition.

Par contre, mon programme (sans les IF) est plus lent que celui avec. Il y a sûrement moyen d'optimiser les formules de calcul de X et Y.

Avatar de l’utilisateur
jojo
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 294
Inscription : 28 juin 2006 21:28
Localisation : Entre la France, la Suisse et l'Italie ... au pays du bien décolleté.

Re: Petite boule qui rebondit

Message par jojo » 08 juil. 2019 21:07

Merci pour cet exercice !
J'ai ressorti mon vieux HP200LX et le GWBASIC !
Voici ma version modifiée et qui utilise les opérateurs logiques AND / OR et 2 drapeaux
Je ne trace pas les lignes, je me contente d'afficher les valeurs calculées.
Après avoir lu la remarque de C.Ret, je ne sais pas si c'est plus ou moins rapide, le but étant de relever le "défi" de Ben ! Il n'y a pas de 'IF' ! :wink:

Code : Tout sélectionner

10 REM J'utilise 2 drapeaux dx1 et dx2 et deux limites minx et maxx (pour m'éviter d'afficher trop de lignes !)
20 REM Il faudra faire la même chose pour y ...  
30 x=0:dx1=0:dx2=0:maxx=319:minx=0:y=0:dy1=0:dy2=0:maxy=199:miny=0
35 REM Je commence par afficher le 1er point à 0,0 (en fait les valeurs de x, dx1 et dx2 pour contrôler)
40 print "x=";x, "dx1=";dx1,"dx2=";dx2
50 dx1=((x<maxx) and (dx2=0) or (x=minx))
60 dx2=((x>minx) and (dx1=0))
70 x=x-dx1+dx2
80 goto 40

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 08 juil. 2019 21:22

C'est une excellente idée avec les opérateurs logiques :-)

J'ai adapté le code de jojo pour le Commodore. Mais il me semble être un peu plus lent.

Code : Tout sélectionner

10 graphic 1,1
30 x=0:x1=0:x2=0:mx=319:nx=0:y=0:y1=0:y2=0:my=199:ny=0
40 draw 1,x,y
50 x1=((x<mx) and (x2=0) or (x=nx))
60 x2=((x>nx) and (x1=0))
70 x=x-x1+x2
80 y1=((y<my) and (y2=0) or (y=ny))
90 y2=((y>ny) and (y1=0))
100 y=y-y1+y2
110 goto 40

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2030
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Petite boule qui rebondit

Message par C.Ret » 08 juil. 2019 22:00

Ben a écrit :
08 juil. 2019 20:57
Mais dans ton programme, il y a des "IF", le but est de ne plus en avoir du tout. :-)
Je viens d'éditer mon premier message : j'ai supprimé tous les IF et aussi le GOTO : mais surtout les variables X et Y inutiles:

Code : Tout sélectionner

10 graphic 1,1
20 draw 1,1,1 : dx=1:dy=1
30 do
40 :  dx=dx*(-1)^abs( (rdot(0)=0) or (rdot(0)=319) )
50 :  dy=dy*(-1)^abs( (rdot(1)=0) or (rdot(1)=199) )
60 :  draw 1,+dx,+dy
70 loop
La version 7.0 du BASIC permet de faire bien des choses :)
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator | HP-15C | CASIO fx-602p + FA-1. .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2030
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Petite boule qui rebondit

Message par C.Ret » 08 juil. 2019 23:14

Ben a écrit :
08 juil. 2019 20:57
Par contre, mon programme (sans les IF) est plus lent que celui avec. Il y a sûrement moyen d'optimiser les formules de calcul de X et Y.
C'est moins la façon dont les calculs sont fait que le nombre de tests et de calculs inutilement répétés. traverser l'écran prend plusieurs centaines d'itérations. Pour faire vite, il faut répéter? établir les états et limiter le nombre de tests nécessaires pour passer d'un état à l'autre.

Dans mon programme qui trace la figure tronçons par tronçons en coupant à chaque fois tout l'écran, les tests sont plus nombreux dans le listing, mais ne sont réalisés qu'une fois par traversée. Ce qui sera bien plus rapide qu'un calcul (ou qu'un test) effectué à chaque pixel de l'écran.

Je voyais quatre états, il y en a en réalité le double. Aux quatre directions, s'ajoute le fait que soit X, soit Y limite la traversée de l'écran.

Dans la première diagonale, on descend vers la droite de l'écran. Comme on descend, tous les tests du type Y=0 sont inutiles ainsi que les tests X=0 car on va vers la droite. Parmi les tests X=319 et Y=199, seul le dernier est utile. En effet, on sait dès le début de cette traversée que X est plus grand que Y et que donc c'est la valeur de Y qui indiquera la fin de l'écran.

Je propose donc le code suivant où pour chaque traversée un seul test est réalisée dans les boucles DO: … : LOOP selon X ou Y. Les branchements sont réalisés en comparant les valeurs de X et Y afin d'aller vers la ligne testant le paramètre limitant.
On remarquera que lorsque l'abscisse X atteint une des deux extrémités de l'écran, à la traversée suivante c'est nécessairement Y qui sera limitant car l'écran est plus large que haut.

Code : Tout sélectionner

0 graphic 1,1:draw 1,1,1:w=319:h=199:d=w-h:goto 4

1 do:draw 1,+1,-1:loop until rdot(0)=w
2 do:draw 1,-1,-1:loop while rdot(1):if rdot(0)>h goto 8
3 do:draw 1,-1,+1:loop while rdot(0)
4 do:draw 1,+1,+1:loop until rdot(1)=h:if rdot(0)<d goto 6:else 1

5 do:draw 1,-1,-1:loop while rdot(0)
6 do:draw 1,+1,-1:loop while rdot(1):if rdot(0)<d goto 4
7 do:draw 1,+1,+1:loop until rdot(0)=w
8 do:draw 1,-1,+1:loop until rdot(1)=h:if rdot(0)>h goto 2:else 5
C'est d'après moi la version la plus rapide, car pour chacune des traversées, aucun calcul ou aucun test inutile n'est effectué. Le tracé se fait à chaque fois dans une boucle DO:...:LOOP à l'aide de l'astuce de la fonction DRAW relative.
Le test de sortie de la boucle ne scrute que X ( RDOT(0) ) ou Y ( RDOT(1) ).
Les traversées limitées par les valeurs de X (lignes impaires) enchainent directement par la traversée suivante limitée par la valeur de Y (lignes paires).
A la fin de ces dernières traversées, la valeur de X est testée afin d'enchainer sur la traversée suivante de même direction mais limitée soit par X soit par Y.

Le test de boucle utilisant des LOOP WHILE X ou LOOP WHILE Y sont des raccourcis pour réaliser un LOOP UNTIL x=0 ou un LOOP UNTIL Y=0

Voci un tableau qui donne la relation entre le sens des traversées, les lignes du programme et les variables limitantes:

Code : Tout sélectionner

Diagonales:    Limitée par X     Limitée par Y     
 Dx    Dy      ligne puis        ligne   puis (lim/Y) ou (lim/X) 
 +1    +1       7     8           4       6 (x petit)        1   
 +1    -1       1     2           6       4 (x petit)        7
 -1    +1       3     4           8       2 (x grand)        5
 -1    -1       5     6           2       8 (x grand)        3
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator | HP-15C | CASIO fx-602p + FA-1. .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Avatar de l’utilisateur
zpalm
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 2499
Inscription : 03 mai 2008 15:33
Localisation : Grenoble

Re: Petite boule qui rebondit

Message par zpalm » 09 juil. 2019 00:56

Ben a écrit :
08 juil. 2019 18:12
Comment faire pour obtenir le même résultat, mais sans les "IF" :-)
Sur HP Prime voici un programme avec des formules sans IF ni test.
On passe les coordonnées du point de départ en paramètres et la dimension de l'écran en pixels est définie par L et H:

Code : Tout sélectionner

EXPORT PBQR(X,Y)
BEGIN
 L:=320;H:=240;
 RECT_P();
 WHILE 1 DO
  PIXON_P(L-ABS(L-X),H-ABS(H-Y)); 
  X:=(X+1) MOD (2*L); Y:=(Y+1) MOD (2*H);
  WAIT(0.005);
 END;
END;
Je vous laisse découvrir la logique des formules :wink:

Je crois qu'il n'y a pas de fonction MOD dans le BASIC du C128, on pourra alors remplacer :
X:=(X+1) MOD (2*L); Y:=(Y+1) MOD (2*H);
par :
X:=X+1; X:=X-IP(X/(2*L))*2*L;
Y:=Y+1; Y:=Y-IP(Y/(2*H))*2*H;

La fonction WAIT est là pour ralentir l'émulateur de la HP Prime, je ne pense pas que ce soit nécessaire sur le C128, avec tous les calculs ce ne doit pas être très rapide...

EDIT: une version plus compacte pour la HP Prime uniquement, en utilisant les listes:

Code : Tout sélectionner

EXPORT PBQR(X,Y)
BEGIN
 L1:={X,Y}; L2:={320,240};
 RECT_P();
 WHILE 1 DO
  PIXON_P(L2-ABS(L2-L1));
  L1:= (L1+1) MOD (2*L2);
  WAIT(0.005);
 END;
END;

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 09 juil. 2019 11:38

Voici ma petite version sans les "IF"

Code : Tout sélectionner

1000 bx=319:by=199:xx=bx*2:yy=by*2:i=0
1010 graphic 1,1
1020 x=abs(bx-(i-int(i/xx)*xx))
1030 y=abs(by-(i-int(i/yy)*yy))
1040 draw 1,x,y
1050 i=i+1:goto 1020
Comme ZPALM le propose, je fais un MOD sur les bornes.

Avatar de l’utilisateur
jojo
Fonctionne à 300 bauds
Fonctionne à 300 bauds
Messages : 294
Inscription : 28 juin 2006 21:28
Localisation : Entre la France, la Suisse et l'Italie ... au pays du bien décolleté.

Re: Petite boule qui rebondit

Message par jojo » 09 juil. 2019 15:57

Pour tester la validité de vos programmes ainsi que pour éviter de ressortir les vieux machins (mon HP200LX par exemple), les piles, les disquettes et autres antiquités, j'ai trouvé un émulateur GW-BASIC qui fonctionne très bien sous WIndows: PC-BASIC
Désolé si ça déjà été posté ...

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 09 juil. 2019 17:46

jojo a écrit :
09 juil. 2019 15:57
Pour tester la validité de vos programmes ainsi que pour éviter de ressortir les vieux machins (mon HP200LX par exemple), les piles, les disquettes et autres antiquités, j'ai trouvé un émulateur GW-BASIC qui fonctionne très bien sous WIndows: PC-BASIC
Désolé si ça déjà été posté ...
Sinon, tu peux toujours installer un émulateur d'une machine des années 80. Tu auras les mêmes contraintes qu'à l'époque. ;-)

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 09 juil. 2019 19:31

Mais, je pense à une chose, on pourrait imaginer un programme qui pré calcule les positions X et Y, les enregistre dans un fichier.

Le programme qui affiche les points à l'écran doit juste relire le fichier, pas besoin de "if" 😊 Ce serait tout aussi valide.

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2030
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Petite boule qui rebondit

Message par C.Ret » 09 juil. 2019 19:47

J'aime bien l'astuce de représenter en valeur absolue les coordonnées congrues au le double de l'amplitude !

L'idée d'un fichier va nécessiter de trouver une disquette vierge, voir une boite si l'on veut pouvoir remplir l'écran !

Mais tous ces codes sont complètement hors sujet: heureusement avec votre émulateur préféré, un copy/paste bien mené vous permettra d'enfin la voir (et de l'entendre):

Code : Tout sélectionner

10 fast:graphic 1,1:circle 1,2,2,2:paint 1,2,2:sshape a$,0,0,23,20:sprsav a$,1:slow:graphic 0
20 y=50:vy=1:sprite 1,1,2:movspr 1,0#0:print tab(11)"press a key":getkeyb$:print
30 for x=24 to 344:y=y+vy:vy=1+vy:if y>245 then y=245:vy=-.8*vy:sound 1,16000,4,2
40 movspr 1,x,y:next x:goto 20
A défaut , vous pouvez aussi saisir ce programme à l'aide des touches de votre C128 !
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator | HP-15C | CASIO fx-602p + FA-1. .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Ben
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1457
Inscription : 21 août 2016 19:04

Re: Petite boule qui rebondit

Message par Ben » 11 juil. 2019 13:55

C.Ret a écrit :
09 juil. 2019 19:47
L'idée d'un fichier va nécessiter de trouver une disquette vierge, voir une boite si l'on veut pouvoir remplir l'écran !
Par curiosité, j'ai fait l'exercice. Pour remplir l'écran de points, il suffit d'un fichier de 944 blocks. La première partie du programme rempli le fichier, la deuxième lis le fichier et affiche les points.

Code : Tout sélectionner

5 dopen #1,"balldata,w",u9
10 graphic 1,1
20 x=0:y=0:dx=1:dy=1
30 draw 1,x,y
40 x=x+dx:y=y+dy
45 print#1,x:print#1,y
50 if x<0 or x>319 then dx=-dx
60 if y<0 or y>199 then dy=-dy
70 goto 30
999 rem --------------------------
1000 dopen #1,"balldata",u9
1005 graphic 1,1
1010 input#1,x
1020 do while(st<>66)
1030 input#1,y
1040 draw 1,x,y
1050 input#1,x
1060 loop
1070 dclose#1
Concernant la vitesse, on ne gagne pas grand chose.

Par contre, on peut aussi ne retenir que les points qui viennent "cogner" sur le bord de l'écran et de tracer une droite avec les points. Evidemment, on gagne beaucoup en vitesse et en place sur le disque.

Code : Tout sélectionner

5 dopen #1,"balldata1,w",u9
10 graphic 1,1
20 x=0:y=0:dx=1:dy=1
30 draw 1,x,y
40 x=x+dx:y=y+dy
50 if x<0 or x>319 then dx=-dx:print#1,x:print#1,y
60 if y<0 or y>199 then dy=-dy:print#1,x:print#1,y
70 goto 30
999 rem --------------------------
1000 dopen #1,"balldata1",u9:xs=0:ys=0
1005 graphic 1,1
1010 input#1,x,y
1020 do while(st<>66)
1030 draw 1,xs,ys to x,y
1040 xs=x:ys=y
1050 input#1,x,y
1060 loop
1070 dclose#1
Ben

Avatar de l’utilisateur
C.Ret
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 2030
Inscription : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Petite boule qui rebondit

Message par C.Ret » 11 juil. 2019 19:07

Ben a écrit :
11 juil. 2019 13:55
[…] Pour remplir l'écran de points, il suffit d'un fichier de 944 blocks. […]
Ben
Intéressant, 944 blocks cela fait presque 72% d'une disquette. Et encore, d'une disquette double face formatée sur un C=1571.
Parce qu'en mode C=1541, la limite c'est seulement 664 blocks par disquette.

Bon, c'est vrai qu'en utilisant un fichier séquentiel de type "texte" où les nombres sont écris avec PRINT#1, x:PRINT #1,y le DOS Commodore perd beaucoup d'espace disque en insérant pas mal d'espaces et autres séparateurs entre les nombres écrits chiffre par chiffre.

Il doit y avoir moyen de compresser cela en convertissant les nombre en chaine de caractères ( style PRINT#1,MID$(STR$(x),2)+CHR$(44)+MID$(STR$(y),2)+CHR£(13); ), en chaine de caractères codées hexadécimale, ou tout autre astuce qui devrai permettre de diviser significativement la taille du fichier séquentiel.
Le plus courts aurait été de directement enregistrer les valeurs binaires (sous forme de code ASCii) mais cela n'est pas possible à cause des zéros et autres caractères de contrôle (type CR LF, EOF, etc) qui vont nécessairement faire planter la relecture même avec un GET#1.


Pour compresser, j'aurai bien utilisé ici les instructions DEC() et HEX$() qui permettent d'enregistrer chaque couple de coordonnées (x,y) sur seulement cinq caractères :
* Pour y qui varie de 0 à 199, il suffirai d'enregistrer RIGHT$(HEX$(y),2) soit deux caractères ( "00" à "C7")
* Pour x qui varie de 0 à 319, il faut un petit peu plus d'espace disque en utilisant RIGHT$(HEX$(x),3) soit trois caractères ("000" à "13F")

L'enregistrement se fera alors avec une instruction PRINT #1,RIGHT$(HEX$(x),3)+RIGHT$(HEX$(y),2);
Il ne faut pas oublier le ; sinon, l'on va perdre un caractère par couple de coordonnées (x,y) et surtout rendre impossible la lecture avec un GET :
GET#1,x1$,x2$,x3$,y1$,y2$ : x=DEC(x1$+x2$+x3$) : y=DEC(y1$+y2$)

Sans le ; on insère un retour de ligne entre chaque codon. La relecture pourra alors se faire avec INPUT#1,xy$ : x=DEC(LEFT$(xy$,3)) : y=DEC(RIGHT$(xy$,2))

En enregistrant la petite balle de cette façon:

Code : Tout sélectionner

10 dopen#1,"data bal,s",w : if ds then stop
20 graphic 1,1:x=1:y=1:dx=1:dy=1
30 do
40 :draw 1,x,y
50 :print#1,right$(hex$(x),3)+right$(hex$(y),2);
60 :x=x+dx:if x=0 or x=319 then dx=-dx
70 :y=y+dy:if y=0 or y=199 then dy=-dy
80 loop while x or y
90 dclose#1:if ds then stop
J'obtiens un fichier de 1250 block (94% d'une disquette double face sur un C=1571 ):

Code : Tout sélectionner

diR "*=seq"
0 "cret2           " 2b 2a
1250  "data bal"         seq
56 blocks free.

ready.

Ainsi qu'un écran HD moitié-allumé:
GR1 Full Half Dot.gif
GR1 Full Half Dot.gif (211.91 Kio) Consulté 1791 fois
Qui peut être redessiné à l'aide du programme suivant :

Code : Tout sélectionner

10 dopen#1,"data bal" : if ds then stop
20 graphic 1,1
30 do
40 :get#1,x1$,x2$,x3$,y1$,y2$
50 :draw 1,dec(x1$+x2$+x3$) , dec(y1$+y2$)
60 loop until st and 64
70 dclose#1
Mais c'est bien moins rapide qu'un simple BLOAD.



Quand au second programme, je suis heureux de voir que ben rejoint ma façon de dessiner d'un bord à l'autre au lieu de pixels par pixels.

Par contre, je ne suis pas sûr que les variables x,y , sx et sy soient nécessaires. Ni d'ailleurs le fichier séquentiel.

Les valeurs des coordonnées (x,y) aux bords de l'écran sont directement déductibles à l'aide du "reste à parcourir" car on incrémente ou décrémente à chaque fois ensemble les deux coordonnées de la même valeur.

En utilisant le principe d'une machine à état on obtient le code le plus concis et le plus rapide suivant :

Code : Tout sélectionner

0 graphic 1,1 : w=319 : h=199 : d=w-h : locate 1,1:goto 4

1 r=w-rdot(0) : draw 1 to +r,-r
2 r=  rdot(1) : draw 1 to -r,-r : if rdot(0)>h goto 8
3 r=  rdot(0) : draw 1 to -r,+r
4 r=h-rdot(1) : draw 1 to +r,+r : if rdot(0)<d goto 6:else 1

5 r=  rdot(0) : draw 1 to -r,-r
6 r=  rdot(1) : draw 1 to +r,-r : if rdot(0)<d goto 4
7 r=w-rdot(0) : draw 1 to +r,+r
8 r=h-rdot(1) : draw 1 to -r,+r : if rdot(0)>h goto 2:else 5
Qui permet de dessiner de la même façon l'écran HD half-dot ci-dessus mais en moins de 2 min (au lieu des presque 3 heures nécessaires à l'enregistrement et à la relecture du fichier séquentiel).

Un BLOAD étant toujours plus rapide.


P.S.: Je tiens à rassurer la Communauté, aucun Commodore C128 ou C=1571 réel n'a été maltraité pour réaliser cet article. Ni aucune archéo-technologie C-MOS. Tout a été émulé sur de l'Intel contemporain.
SHARP PC-1211 + CE-121 + CE-122. | VIC 20 Commodore 128D + Printer P-803 + SD2iec. | TI-57 LCD | TI-74 BasiCalc | TI-92 II | HP-28S + HP82240A | HP-41C + (2 memory + stat + IR) modules. | HP Prime Wireless Graphing Calculator | HP-15C | CASIO fx-602p + FA-1. .Sommaire des M.P.O.. . Sommaire du P.C.T.M. .

Répondre

Revenir vers « Commodore 8bits »