GFA
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment : -28%
-28% Machine à café avec broyeur ...
Voir le deal
229.99 €

[ST MAG] Programmation avancée en gfa (III) Sprites

Aller en bas

[ST MAG] Programmation avancée en gfa (III) Sprites Empty [ST MAG] Programmation avancée en gfa (III) Sprites

Message par tomchi Ven 23 Oct - 9:12


...............................................................

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
tomchi

Messages : 52
Date d'inscription : 15/09/2018
Age : 49

Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum