[ST MAG] Programmation avancée en gfa (III) Sprites
GFA :: Programmation :: Graphismes
Page 1 sur 1
[ST MAG] Programmation avancée en gfa (III) Sprites
...............................................................
PROGRAMMATION AVANCEE EN GFA-BASIC (III)
Par Deneb of Fantasy et Jedi of Sector One from THK
Nous allons ce mois-ci étudier les sprites. Voyons tout d'abord
les principes de base puis nous approfondirons le sujet le mois
prochain en vous proposant d'autres types d'applications. Sortez
vos GfAs, on y va...
LE DEBUT
Après avoir abordé les 'big sprites', nous allons maintenant
attaquer les blocs de taille plus modeste, qui permettent entre
autre de conserver le fond et de gèrer les plans. La technique
sera totalement différente de celle que nous avons vue le mois
dernier. En effet, nous n'utiliserons plus l'instruction BMOVE,
qui affichait le sprite dans son intégralité, mais une série
d'instructions destinées à l'afficher par petits blocs.
L'affichage du motif étant fragmenté, il sera plus lent et plus
complexe à gèrer qu' à l'aide de l'instruction BMOVE, mais plus
souple d'utilisation. Il ne faut cependant pas ésperer manipuler
des blocs de taille aussi imposante que ceux du mois précédent.
LES INSTRUCTIONS
Occupons nous d'abord du moyen d'afficher les sprites. Nous avons
à notre disposition plusieurs instructions pour réaliser cette
noble tâche. Nous avons bien entendu PEEK et POKE qui servent
respectivement à lire et à écrire en mémoire, mais nous y
préfèrerons les variantes CARD ( qui opère sur un mot ) et LONG (
qui lit ou écrit un mot long ). Leur syntaxe est la suivante:
-pour lire une valeur ( exemple : A% ), il faut utiliser :
A%=LONG{adresse mémoire à lire}
-pour écrire, la syntaxe devient :
LONG{adresse cible}=A%
CARD s'utilise de façon analogue et prend exactement le même
temps machine.
LE PREMIER LISTING
Celui-ci reprend le bien connu principe des 'programmes génèrant
des programmes' faisant maintenant partie de la routine lorsqu'on
essaye de programmer en GfA. Le premier qui, je le rappelle est
destiné à creer des fichiers externes, .INL et .LST doit etre
executé avant le second qui necessite ces fameux fichiers. Ce
listing, malgré son apparente longueur, a le mérite d'etre
universel, c'est-à-dire qu'il est compatible avec des sprites
d'une taille et d'un nombre de plans quelconques. La première
partie charge une image Degas ou Neochrome et vous permet de
selectionner à la souris le bloc qui vous interesse. Suit alors
la demande du nombre de plans. Notez bien que ces derniers sont
pris successivement. En pratique, si votre sprite n'utilise que
la première couleur de la palette ainsi que la couleur de fond,
entrez la valeur 1. Un nombre de plans égal à 2 prendra en compte
les quatre premières couleurs ( fond compris ), un nombre égal à
3 les huit premières et à 4, toute la palette. L'interet de
se limiter à certains plans est d'une part de gagner du temps
machine, et d'autre part de limiter la taille du source. Une fois
la valeur entrée, les plans inutiles seront effacés, ce qui vous
permettra de confirmer votre évaluation. Le programme va ensuite
creer le fichier contenant la routine d'effacage du sprite. En
effet, nous n' allons pas recourir à l'auto-effacage comme avec
les 'big sprites'. Etant donné la relative étroitesse de nos
motifs, il est beaucoup plus judicieux de l'effacer dans son
integralité que de le contourner. Cela présente de plus
l'avantage de pouvoir affecter nos sprites d'une courbe
totalement libre, sans riquer des traces en cas de vitesse trop
élevée. Cette technique ressemble fort à celle que nous avions
employée à l'insue des champs étoilés dans le numéro 56. C'est
pourquoi vous retrouverez aussi la fameuse routine 'magique'
permettant de retrouver l'adresse ou les motifs ont été affichés
deux VBLs avant. Vient alors le problème de l'affichage de nos
zoulis dessins. Nous n'utiliserons plus un buffer contenant le
sprite prédécalé comme le mois précédent. En effet, étant donné
la taille des sprites que nous traitons, nous pouvons nous
permettre de créer un code contenant directement les données.
L'affichage se fera donc avec une ligne du type :
LONG{adresse_ecran%+offset}=valeur
offset et valeur étant des entiers relatifs.
Cependant, il ne faut pas négliger le prédécalage; les valeurs ne
seront donc pas des constantes. Nous allons résoudre sans
problèmes ce problème problèmatique qui nous pose problème en créant
seize routines, qui correspondent aux différentes phases. Nous
placerons chacune d'entre elles dans des procédures qui porteront
respectivement les doux noms Sprite0, Sprite1, Sprite2,... Nous
pourrons par la suite appeller celle qui nous interesse à l'aide
de l'instruction ON...GOSUB, en ayant préalablement pris le soin
d'initialiser la variable Jedi% en fonction de l'adresse où le
sprite devra s'afficher. Notez que les espaces vides ne seront
pas pris en compte, car il est totalement inutile de les
afficher... Le listing s'occupe aussi du calcul de la trajectoire
qu'il suivra ( 360 positions avant le bouclage ). Les formules
employées ici sont relativement simples, mais rien ne vous
empêche de rajouter des arcs cotangentes hyperboliques inverses
ou d'autres horreurs mathématiques... Le fichier sera au format
.INL, ce qui signifie qu'il pourra directement être inclu dans le
programme principal grâce à l'instruction INLINE. Pour charger ce
fichier, il vous suffira de vous placer sur cette ligne et
d'écraser sauvagement les touches 'Help' et 'L'. Le format
utilisé est le suivant :
-Un mot : L'offset par rapport à l'origine de l'écran
-Un autre mot : Le décalage ( pour le ON...GOSUB )
Question: pourquoi utiliser un mot pour le décalage alors que les
valeurs ne vont s'étaler que sur un intervalle compris entre zero
et quinze ? Réponse: Il est impossible de lire un mot ou un mot
long sur une adresse impaire. L'offset suivant ne serait donc
pas pair et quelques menacantes bombinettes risqueraient de
faire leur apparition. Ceci fait, il ne faut pas oublier de
sauvegarder la palette, sans laquelle le sprite prendrait des
couleurs plutôt étranges. Nous allons utiliser le principe
d'INLINE pour la seconde fois.
LE SECOND LISTING
Tout d'abord, n'oubliez pas de charger les deux INLINEs e t de
'merger' la routine d'effacage ainsi que les procédures destinées
à l'affichage du sprite. Ne paniquez pas face à la longueur
impressionnante que risque d'atteindre votre listing si votre
sprite est un peu trop gros ( Evitez tout de même le 128 par 128
en quatre plans,à moins de possèder un 16 mégas de RAM et un
disque dur 200 mégas ! ) . D'autre part, ce programme doit être
compilé pour s'éxécuter à une vitesse raisonnable. Une petite
remarque concernant l'instruction RESERVE: elle permet de
'diminuer' l'espace alloué au GfA. En clair, un RESERVE 40000 ne
vous laissera que 40000 octets disponibles et une erreur
surviendra après deux malheureux SGETs. Où est l'interêt me
diriez-vous ? La mémoire perdue peut être cependant réutilisée
grâce à l'instruction MALLOC qui réservera un petit coin de
mémoire dans lequel vous pourrez inscrire absolument tout ce qui
vous passera par la tête. Afin de se limiter à la place dont
vous avez besoin pour les MALLOCs, il faudra utiliser quelque
chose de la forme :
RESERVE FRE(0)-nombre total d'octets nécessaires pour les MALLOCs
à la fin du programme, mieux vaut ne pas laisser de traces en
effectuant un second RESERVE avec la taille mémoire dont on
disposait au début en guise de paramètre. C'est pourquoi nous
sauvegardons préalablement FRE(0) dans la variable Megatizer%.
La boucle principale de ce programme a une structure fort
similaire à celle employée pour les champs étoilés et ne devrait
donc pas vous poser de problèmes majeurs.
LA FIN DU DEBUT
Nous vous conseillons d'examiner attentivement ces programmes car
nous poursuivrons l'étude des sprites le mois prochain afin
d'étudier le problème des superpositions. Nous vous proposerons
éventuellement d'autres techniques. Pour toute remarque à propos
de cet article vous pouvez nous laisser un gentil message sur le
3615 STMAG en Bal DZC.
- Code:
.
.D‚coupage d'un sprite dans une image Neo ou Degas,
.recodage du motif selon le nombre de plans souhait‚s,
.creation de la routine d'effacage,
.mise en place de la routine d'affichage,
.calcul d'une courbe parametrable bien centr‚e,
.et sauvegarde de celle-ci ainsi que de la palette !
.Code : Jedi of Sector One from The Heavy Killers
.Bon courage pour taper tout ‡a...
.
VSYNC !Soon coming:
CLS !The Bee Forol Megademo
VSYNC !Avec la participation de:
SETCOLOR 0,0 !ODC,T32,KCB,DBA,Zap Crtn,
SETCOLOR 15,1911 !et surtout de Sector One!
ALERT 2," | | Charger une image | ",0," Degas | Neo | Quit ",format%
SELECT format% !JakkaronhŠmlakrŠm2maron
CASE 3 !antubb2soasanndizuigram
EDIT !Quit ?!?
CASE 1 !Image au format Degas
FILESELECT "\*.PI1","",nfile$
nfile$=nfile$+".PI1" !Extension par d‚faut .PI1
IF EXIST(nfile$) !Ca existe au moins ?!
OPEN "I",#1,nfile$ !On ouvre
SEEK #1,2 !On saute
pal$=INPUT$(32,#1) !On lit
img$=INPUT$(32000,#1) !On lit la suite
CLOSE #1 !Et on referme
ELSE !Ca existe pas ???
RUN !C'est reparti pour un tour
ENDIF !Salut Klaus !
CASE 2 !Image Neochrome
FILESELECT "\*.NEO","",nfile$
nfile$=nfile$+".NEO" !Je recherche un gentil
IF EXIST(nfile$) !‚diteur qui accepterait
OPEN "I",#1,nfile$ !de commercialiser mon bel
SEEK #1,4 !utilitaire de musique
pal$=INPUT$(32,#1) !'soundchip'...
SEEK #1,128 !Contactez-moi vite !
img$=INPUT$(32000,#1) !Merci d'avance...
CLOSE #1 !Utilisation simple,
ELSE !routine hyper-rapide,
RUN !gestion de samples,
ENDIF !ripping d'instruments,
ENDSELECT !effets sp‚ciaux,
VSYNC !et j'en passe...
GRAPHMODE 3 !Pour voir les contours
FOR a%=0 TO 15 !Met toutes les couleurs
SETCOLOR a%,0 !En noir avant l'affichage
NEXT a% !de l'image charg‚e.
SPUT img$ !Et zou !
~XBIOS(6,L:V:pal$) !La palette...
VSYNC !Attend qu'elle s'installe
.
.Si la couleur de fond est confondue avec celle
.utilis‚e en particulier pour l'affichage du texte et
.de la souris, on change un peu la palette histoire
.de voir quelque chose...
.
IF DPEEK(&HFFFF8240)=DPEEK(&HFFFF825E)
SDPOKE &HFFFF825E,NOT DPEEK(&HFFFF8240)
ENDIF
WHILE MOUSEK !On se calme et on cesse
WEND !d'appuyer sur la souris
HIDEM !C'est malin, vous lui
xol%=512 !avez fait peur et
yol%=512 !maintenant elle se cache!
REPEAT !Ca, ce sont des
MOUSE x1%,y1%,z% !instructions trŠs
IF x1%<>xol% OR y1%<>yol% !sympathiques, mais qui
VSYNC !n'ont rien de trŠs
SPUT img$ !technique.
LINE x1%,0,x1%,199 !Alors on passe...
LINE 0,y1%,319,y1% !Trace le viseur
xol%=x1% !Pour ‚viter le
yol%=y1% !clignottement
ENDIF !Sector One est compos‚ de
UNTIL z% !-Ace ( codeur )
xol%=512 !-Eclipse ( grafixx )
yol%=512 !-Thunderboy ( code, gfx )
WHILE z% !-Shame ( muzaxx )
MOUSE x2%,y2%,z% !-Spinders ( codeur )
IF x2%<>xol% OR y2%<>yol% !-White Ninja ( gfx, zax )
VSYNC !-Virgil ( soundtraxx )
SPUT img$ !-Maverick ( codeur )
BOX x1%,y1%,x2%,y2% !-Jedi ( codeur, muzaxx )
xol%=x2% !Dum...dum...dum...
yol%=y2% !Rien de special
ENDIF !L… non plus...
WEND !Bac
VSYNC !Bec
SPUT img$ !Bic
GRAPHMODE 1 !Boc
GET x1%,y1%,x2%,y2%,bloc$ !Buc
VSYNC !Byc
CLS !Efface
PUT 0,0,bloc$ !Le bloc selectionn‚
sizex%=SUCC(ABS(x1%-x2%)) !Largeur du sprite
sizey%=SUCC(ABS(y1%-y2%)) !Hauteur du sprite
sizex%=ADD(sizex%,15) AND &HFFF0
PRINT AT(1,22);"Taille en X: ";sizex%''"Taille en Y: ";sizey%
PRINT "Soit ";sizex%*sizey%/16;" blocs de 16 pixels."
INPUT "Nombre de plans: ",nplan%
nplan%=MAX(1,MOD(nplan%,5)) !de 1 … 4 plans seulement
ace%=SHR(sizex%,1) !Ce qu'il faut prendre...
DEC sizey% !Admettons...
IF nplan%<>4 !En 4 plans, on garde tout
FOR ligne%=0 TO sizey%
FOR col%=0 TO ace% STEP 8
adresse%=XBIOS(2)+col%+ligne%*160
SELECT nplan%
CASE 1 !1 plan
CARD{adresse%+2}=0 !=> Vire plan 2
LONG{adresse%+4}=0 !et plans 3&4
CASE 2 !2 plans
LONG{adresse%+4}=0 !=> Vire plans 3&4
CASE 3 !3 plans
CARD{adresse%+6}=0 !=> Vire plan 4
ENDSELECT
NEXT col%
NEXT ligne%
ENDIF
PRINT "Ok pour le sprite ? ( O/N )";
REPEAT
key$=UPPER$(INPUT$(1))
IF key$="N"
RUN
ENDIF
UNTIL key$="O"
GET 0,0,319,167,sprite$
CLS
PRINT "Entrez le nom du fichier .LST"
PRINT "destin‚ … l'effacage du motif"
FILESELECT "\*.LST","",nfile$
nfile$=nfile$+".LST"
IF nfile$=""
EDIT
ENDIF
OPEN "o",#1,nfile$ !Effacage du sprite
FOR ligne%=0 TO sizey% !Ligne
FOR col%=0 TO ace% STEP 8 !Colonne
offset%=col%+ligne%*160 !Offset
SELECT nplan% !Suivant les plans
CASE 1 !Vire juste le 1er
PRINT #1,"CARD{jedi%+";offset%;"}=0"
CASE 2 !Vire 1 et 2
PRINT #1,"LONG{jedi%+";offset%;"}=0"
CASE 3 !Vire 1,2 et 3
PRINT #1,"LONG{jedi%+";offset%;"}=0"
PRINT #1,"CARD{jedi%+";offset%+4;"}=0"
CASE 4 !Vire tout
PRINT #1,"LONG{jedi%+";offset%;"}=0"
PRINT #1,"LONG{jedi%+";offset%+4;"}=0"
ENDSELECT
NEXT col%
NEXT ligne%
CLOSE #1
CLS
PRINT "Entrez le nom du fichier .LST"
PRINT "destin‚ … l'affichage du sprite"
FILESELECT "\*.LST","",nfile$
nfile$=nfile$+".LST"
IF nfile$=""
EDIT
ENDIF
OPEN "o",#1,nfile$
FOR phase%=0 TO 15
CLS
PUT phase%,0,sprite$ !Pr‚decalage du motif
PRINT AT(1,25);"Phase nø";phase%;"/15";
PRINT #1,"PROCEDURE sprite";phase%
FOR ligne%=0 TO sizey%
FOR col%=0 TO ace% STEP 8
offset%=col%+ligne%*160
alpha%=ADD(XBIOS(2),offset%)
SELECT nplan% !Comme l'effacage...
CASE 1
IF CARD{alpha%}
PRINT #1,"CARD{jedi%+";offset%;"}=";
PRINT #1,CARD{alpha%}
ENDIF
CASE 2
IF LONG{alpha%}
PRINT #1,"LONG{jedi%+";offset%;"}=";
PRINT #1,LONG{alpha%}
ENDIF
CASE 3
IF LONG{alpha%}
PRINT #1,"LONG{jedi%+";offset%;"}=";
PRINT #1,LONG{alpha%}
ENDIF
IF CARD{alpha%+4}
PRINT #1,"CARD{jedi%+";offset%+4;"}=";
PRINT #1,CARD{alpha%+4}
ENDIF
CASE 4
IF LONG{alpha%}
PRINT #1,"LONG{jedi%+";offset%;"}=";
PRINT #1,LONG{alpha%}
ENDIF
IF LONG{alpha%+4}
PRINT #1,"LONG{jedi%+";offset%+4;"}=";
PRINT #1,LONG{alpha%+4}
ENDIF
ENDSELECT
NEXT col%
NEXT ligne%
PRINT #1,"RETURN"
NEXT phase%
CLOSE #1
sector_one:
CLS
extreme_x%=SUB(320,sizex%)
extreme_y%=SUB(200,sizey%)
middle_x=extreme_x%/2 !Centrage de la courbe
middle_y=extreme_y%/2
PRINT "Parametres relatifs a la courbe"
INPUT "Coefficient 1 ";c1%
INPUT "Coefficient 2 ";c2%
INPUT "Coefficient 3 ";c3%
INPUT "Coefficient 4 ";c4%
CLS
FOR angle%=0 TO 359
x=middle_x
x=x+middle_x*COSQ(angle%*c1%)*SINQ(angle%*c2%)
y=middle_y
y=y+middle_y*COSQ(angle%*c3%)*SINQ(angle%*c4%)
VSYNC
PSET ROUND(x),ROUND(y),15 ! Repr‚sentation
NEXT angle%
PRINT AT(1,25);"C'est bon ? ( O/N )";
REPEAT
key$=UPPER$(INPUT$(1))
UNTIL key$="O" OR key$="N"
IF key$="N"
GOTO sector_one !Non ? => on refait
ENDIF
PRINT AT(1,1);"Entrez le nom du fichier"
PRINT AT(1,2);"destin‚ … recevoir la courbe"
FILESELECT "\*.INL","COURBE.INL",nfile$
nfile$=nfile$+".INL"
IF nfile$=""
EDIT
ENDIF
OPEN "o",#1,nfile$
FOR angle%=0 TO 359
PRINT AT(1,3);"Traitement position #";angle%;"/359";
x=middle_x
x=x+middle_x*COSQ(angle%*c1%)*SINQ(angle%*c2%)
y=middle_y
y=y+middle_y*COSQ(angle%*c3%)*SINQ(angle%*c4%)
adrx%=AND(SHR(ROUND(x),1),65528)
adry%=MUL(160,ROUND(y))
adresse%=ADD(adrx%,adry%) !L'offset,en fait
deca%=AND(ROUND(x),15) !Le d‚calage
PRINT #1,MKI$(adresse%); !On ‚crit tout ‡a
PRINT #1,MKI$(SUCC(deca%));
NEXT angle%
CLOSE #1
CLS
PRINT "Entrez le nom du petit fichier"
PRINT "contenant la palette"
FILESELECT "\*.INL","PALETTE.INL",nfile$
nfile$=nfile$+".INL"
IF nfile$=""
EDIT
ENDIF
BSAVE nfile$,V:pal$,32 !Sauve pal$, les couleurs
EDIT !et ciao !
- Code:
.
.Programme principal destin‚ …
.l'animation de sprites en GfA-Basic
.par Jedi of Sector One
.from The Heavy Killers
.
.Rappel: Ce listing doit etre compil‚
.
.
.L…, il faut charger la courbe...
INLINE courbe%,1440
.
....Et l…, la palette !
INLINE pal%,32
.
.Initialisations
.
debut_courbe%=courbe% !Pour le bouclage
fin_courbe%=courbe%+1440 !la fin de la courbe...
pointeur%=debut_courbe% !Pointeur sur la courbe
OUT 4,&H12 !Paralyse la souris...
HIDEM !...et l'extermine !
CLS !Allo la terre ?
~XBIOS(6,L:pal%) !C'est + bo en couleur !
VSYNC !Jacques Caron aime la
origine%=XBIOS(2) !crŠme de marron en tube
megatizer%=FRE(0) !de 78 grammes...
RESERVE megatizer%-32256 !On a besoin de 32 Ko
ON BREAK GOSUB bye !Beau temps, non ?
ecran1%=XBIOS(2) !Quoiqu'un peu frais...
nouveau%=MALLOC(32256) !Le second ‚cran
ecran2%=AND(ADD(nouveau%,255),&HFFFFFF00)
BMOVE ecran1%,ecran2%,32000 !Efface celui-ci
old%=ecran2% !Voir ST-Magazine
old2%=ecran1% !nø56, pages 64 … 66
.
.Boucle principale
.
DO !Tout doux, tout doux
SWAP ecran1%,ecran2% !Intervertit...
~XBIOS(5,L:ecran1%,L:ecran2%,-1)
VSYNC !Synchronisation
jedi%=old% !C'est l… qu'on efface !
.
.[ MERGEZ ICI LA ROUTINE D'EFFACAGE ]
.
jedi%=ADD(ecran1%,CARD{pointeur%})
deca%=CARD{ADD(pointeur%,2)}!C'est ‡a qu'on affiche !
.
.Affichage du sprite (d‚calage=deca% ; adresse=jedi%)
.
ON deca% GOSUB sprite0,sprite1,sprite2,sprite3,sprite4,sprite5,sprite6,sprite7,sprite8,sprite9,sprite10,sprite11,sprite12,sprite13,sprite14,sprite15
old%=old2% !La routine 'magique'
old2%=jedi% !( cf ST-MAG 56 )
ADD pointeur%,4 !Position suivante
IF pointeur%=fin_courbe% !D‚j… … la fin ?
pointeur%=debut_courbe% !->On boucle
ENDIF !!!???!??!?!?!!!?!???!??!?
LOOP UNTIL INP?(2) !Touche ?
bye !Fini
.
.[ MERGEZ ICI LA ROUTINE D'AFFICHAGE ]
.
PROCEDURE bye !Comme son nom l'indique
~MFREE(nouveau%) !LibŠre les prisonniers
RESERVE megatizer% !Restitue la m‚moire
~XBIOS(5,L:origine%,L:origine%,0)
VSYNC !Remet l'‚cran initial
OUT 4,8 !Damned ! La souris !!!
EDIT !Aaaaaaaaarrrrrrrrrrgh !!!
RETURN !Glibatu makabo ritujakipu
tomchi- Messages : 52
Date d'inscription : 15/09/2018
Age : 49
Sujets similaires
» [ST MAG] Programmation avancée en gfa (IV) Sprites
» TUTO Amateur 02 les SPRITES
» [e-anim] Blitter sprites
» Débutant 00 Début de programmation
» Programmation du BLITTER par ses registres
» TUTO Amateur 02 les SPRITES
» [e-anim] Blitter sprites
» Débutant 00 Début de programmation
» Programmation du BLITTER par ses registres
GFA :: Programmation :: Graphismes
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum