L'école Comment contourner la limitation de l'instruction COPY
Bienvenue au cours d'été !
Si vous avez déjà fait un jeu en Basic dans un mode graphique pour MSX2 ou plus récent, vous avez sans doute été confronté à la limitation de l'instruction COPY. Elle ne peut pas copier depuis ou vers une zone invisible.
Chaque mode de SCREEN5 à SCREEN12 a une résolution réelle de 256 x 256 ou 512 x 256 mais la résolution visible est de 256 x 212 ou 512 x 212.
Par défaut, les lignes non-visibles de la page 0 contiennent toutes les données nécessaires pour afficher les Sprites donc si vous faites une copie d'une image sur cette zone, vous allez écraser leur données.
C'est sans doute pour ne pas écraser cette zone que l'instruction COPY du Basic a été bridée. Cependant, cela fait perdre 44 lignes aux autres pages qui peuvent être précieuses pour ajouter des graphismes supplémentaires à votre jeu.
Voici donc une méthode simple pour utiliser ces zones mortes sous Basic :
A partir du MSX2, le processeur vidéo (le VDP) a été doté de commandes pour tracer une ligne, un point, etc et effectuer diverses types de copie.
Pour exécuter une commande, il suffit d'écrire les paramètres dans les registres de 32 à 45 du VDP puis d'écrire le type d'instruction à effectuer dans le registre 46.
À chaque fois que l'on écrit une valeur dans le registre 46, le VDP exécute l'instruction correspondante à la valeur indiquée en tenant compte des paramètres.
Attention :
En Basic, VDP(0 à 7) = registre de commandes 0 à 7 mais VDP(9 à 47) = registre de commandes 8 à 46.
VDP(8) = registre de statut 0 et VDP(-1 à -9) = registre de statut 1 à 9.
Exemple :
Pour effectuer l'équivalent de l'instruction COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
il faut entrer les instructions VDP suivantes.
VDP(33)=XS: VDP(34)=XS\256: VDP(35)=YS: VDP(36)=PS:VDP(37)=XD: VDP(38)=XD\256: VDP(39)=YD: VDP(40)=PD: VDP(41)=0:VDP(42)=LX: VDP(43)=0: VDP(44)=LY: VDP(46)=0: VDP(47)=&HD0
&HD0 correspond à un COPY direct VRAM vers VRAM. Pour connaitre les autres commandes veuillez vous référer au livre Pratique du MSX2 au chapitre 5.8 LES COMMANDES INTERNES DU V9938.
Laisser VDP(46) à zéro tant que vous ne serez pas familiarisé avec ces commandes.
Important :
L'exécution d'une instruction prend un certain temps. Le VDP n'est pas multitâche, il ne peut exécuter qu'une instruction à la fois. Lorsqu'une commande est en cours, le bit 0 du registre de statut 2 se met à 1. Donc il faut attendre que ce bit passe à 0 pour pouvoir exécuter une nouvelle commande du registre 46.
Donc avant d'entrer ces instructions VDP, il est nécessaire d'ajouter la ligne suivante auparavant.
10 IF VDP(-2) and 1 THEN 10
La routine de votre programme doit donc ressembler à :
Note : Les MSX japonais utilisent ¥ au lieu de . Edité par GDX Le 10/12/2016 à 02h43
Si vous avez déjà fait un jeu en Basic dans un mode graphique pour MSX2 ou plus récent, vous avez sans doute été confronté à la limitation de l'instruction COPY. Elle ne peut pas copier depuis ou vers une zone invisible.
Chaque mode de SCREEN5 à SCREEN12 a une résolution réelle de 256 x 256 ou 512 x 256 mais la résolution visible est de 256 x 212 ou 512 x 212.
Par défaut, les lignes non-visibles de la page 0 contiennent toutes les données nécessaires pour afficher les Sprites donc si vous faites une copie d'une image sur cette zone, vous allez écraser leur données.
C'est sans doute pour ne pas écraser cette zone que l'instruction COPY du Basic a été bridée. Cependant, cela fait perdre 44 lignes aux autres pages qui peuvent être précieuses pour ajouter des graphismes supplémentaires à votre jeu.
Voici donc une méthode simple pour utiliser ces zones mortes sous Basic :
A partir du MSX2, le processeur vidéo (le VDP) a été doté de commandes pour tracer une ligne, un point, etc et effectuer diverses types de copie.
Pour exécuter une commande, il suffit d'écrire les paramètres dans les registres de 32 à 45 du VDP puis d'écrire le type d'instruction à effectuer dans le registre 46.
À chaque fois que l'on écrit une valeur dans le registre 46, le VDP exécute l'instruction correspondante à la valeur indiquée en tenant compte des paramètres.
Attention :
En Basic, VDP(0 à 7) = registre de commandes 0 à 7 mais VDP(9 à 47) = registre de commandes 8 à 46.
VDP(8) = registre de statut 0 et VDP(-1 à -9) = registre de statut 1 à 9.
Exemple :
Pour effectuer l'équivalent de l'instruction COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
il faut entrer les instructions VDP suivantes.
VDP(33)=XS: VDP(34)=XS\256: VDP(35)=YS: VDP(36)=PS:VDP(37)=XD: VDP(38)=XD\256: VDP(39)=YD: VDP(40)=PD: VDP(41)=0:VDP(42)=LX: VDP(43)=0: VDP(44)=LY: VDP(46)=0: VDP(47)=&HD0
&HD0 correspond à un COPY direct VRAM vers VRAM. Pour connaitre les autres commandes veuillez vous référer au livre Pratique du MSX2 au chapitre 5.8 LES COMMANDES INTERNES DU V9938.
Laisser VDP(46) à zéro tant que vous ne serez pas familiarisé avec ces commandes.
Important :
L'exécution d'une instruction prend un certain temps. Le VDP n'est pas multitâche, il ne peut exécuter qu'une instruction à la fois. Lorsqu'une commande est en cours, le bit 0 du registre de statut 2 se met à 1. Donc il faut attendre que ce bit passe à 0 pour pouvoir exécuter une nouvelle commande du registre 46.
Donc avant d'entrer ces instructions VDP, il est nécessaire d'ajouter la ligne suivante auparavant.
10 IF VDP(-2) and 1 THEN 10
La routine de votre programme doit donc ressembler à :
Code TEXT :
1000 IF VDP(-2) and 1 THEN 1000 1010 VDP(33)=XS: VDP(34)=XS\256: VDP(35)=YS: VDP(36)=PS: VDP(37)=XD: VDP(38)=XD\256: VDP(39)=YD: VDP(40)=PD: VDP(41)=0:VDP(42)=LX: VDP(43)=0: VDP(44)=LY: VDP(46)=0: VDP(47)=&HD0 :RETURN
Note : Les MSX japonais utilisent ¥ au lieu de . Edité par GDX Le 10/12/2016 à 02h43
Fabf
Membre non connecté
Conseiller Municipal
igal
Membre non connecté
Conseiller Municipal
Salut à tous.
Est ce l'un d'entre vous à tester avec succès la méthode de GDX?
Ca fait quelques jours que j'essais de mettre en oeuvre sa méthode mais il semble que les coordonnées (LX-1,LY-1) ne "prennent pas"!
Alors que les coordonnées (XS,YS) semblent être bien prises en compte.
Au cas ou, voici ce que j'ai compris de ses explications:
Afin de copier "SOUS BASIC" n'importe quelles zones sans restrictions dans une matrice 256X256, GDX nous propose ceci:
COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
Pour cela, il suffit d'introduire les valeurs adéquates aux commandes VDP suivantes:
VDP SOURCE DÉBUTS ET FINS DE COORDONNÉES:
VDP(33)=XS:' Correspond à la coordonnée horizontale de DEBUT de copie
VDP(42)=LX:' Correspond à la coordonnée horizontale de FIN de copie
VDP(34)=XS\256:' Correspond à la coordonnée horizontale de DEBUT de copie divisé par 256
VDP(??)=LX\256 ne faut il pas une commande de ce type divisée par 256 pour que tout soit ok ????
VDP(35)=YS:' Correspond à la coordonnée verticale de DEBUT de copie
VDP(44)=LY:' Correspond à la coordonnée verticale de FIN de copie
VDP PAGE SOURCE:
VDP(36)=PS:' Correspond à la page source à copier
VDP DESTINATION:
VDP(37)=XD:' Correspond à la coordonnée horizontale ou coller l'image copiée.
VDP(38)=XD\256:' Correspond à la coordonnée horizontale ou coller l'image copiée divisé par 256
VDP(39)=YD:' Correspond à la coordonnée verticale ou coller l'image copiée
VDP(40)=PD: Correspond à la page source à copier
VDP(41)=0: ???
VDP(43)=0: ???
VDP(46)=0: ???
EXECUTION DE LA COMMANDE COPY:
VDP(47)=&HD0
En suivant ces indications, si je souhaite imiter la commande BASIC suivante:
COPY (0,192)-(127,255),1 TO (50,100),0
En reprenant les explications suivantes de GDX:
COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
Il suffit de valoriser les variables susnommées pour selon l'exemple que je donne juste au dessus tel que:
Variables de la source:
XS=0
YS=192
LX=127 -1
LY=255 -1
PS=1
Variables de la destination:
XD=50
YD=100
PD=0
Pour tester, voici un petit programme:
10 SCREEN 8 ***************************************************************** Mode graphique.
20 SETPAGE1,1:BLOAD"BSPRITE.SC8",S,0+256************************** Chargement d'une partie d'image sur la page 1 couvrant les lignes 192 à 256
30 SETPAGE0,0:BLOAD"balpha.sc8",S,0+256 **************************** Chargement d'une partie d'image sur la page 0 de 192 à 256
40 BLOAD"halpha.sc8",S **************************************************** Chargement d'une partie d'image sur la page 0 de 1 à 191.
50 XS=0: YS=192: LX=127-1:LY=255-1:PS=1******************************* Variables de la source.
60 XD=50:YD=100:PD=0 ***************************************************** Variable de la destination.
70 VDP(27)=&HD0 ************************************************************ Execute la commande équivalente à COPY en BASIC.
80 GOTO 80
Malgré tous mes testes, les résulta reste toujours le même à savoir:
Les coordonnées de DEBUT de COPY sont correctes.
Les coortonnées de destination de COPY sont correctes.
Les coordonnées de FIN de COPY semble ne jamais être prises en comptes.
LX et LY semblent ne pas être appliquées ce qui signifie que l'intégralité des pixels se trouvant "à droite de XS" et "en bas de YS" sont toutes copiées!
Pouvez vous me donner un exemple concret que vous avez testé avec succès s'il vous plait
Merci de votre aide
Est ce l'un d'entre vous à tester avec succès la méthode de GDX?
Ca fait quelques jours que j'essais de mettre en oeuvre sa méthode mais il semble que les coordonnées (LX-1,LY-1) ne "prennent pas"!
Alors que les coordonnées (XS,YS) semblent être bien prises en compte.
Au cas ou, voici ce que j'ai compris de ses explications:
Afin de copier "SOUS BASIC" n'importe quelles zones sans restrictions dans une matrice 256X256, GDX nous propose ceci:
COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
Pour cela, il suffit d'introduire les valeurs adéquates aux commandes VDP suivantes:
VDP SOURCE DÉBUTS ET FINS DE COORDONNÉES:
VDP(33)=XS:' Correspond à la coordonnée horizontale de DEBUT de copie
VDP(42)=LX:' Correspond à la coordonnée horizontale de FIN de copie
VDP(34)=XS\256:' Correspond à la coordonnée horizontale de DEBUT de copie divisé par 256
VDP(??)=LX\256 ne faut il pas une commande de ce type divisée par 256 pour que tout soit ok ????
VDP(35)=YS:' Correspond à la coordonnée verticale de DEBUT de copie
VDP(44)=LY:' Correspond à la coordonnée verticale de FIN de copie
VDP PAGE SOURCE:
VDP(36)=PS:' Correspond à la page source à copier
VDP DESTINATION:
VDP(37)=XD:' Correspond à la coordonnée horizontale ou coller l'image copiée.
VDP(38)=XD\256:' Correspond à la coordonnée horizontale ou coller l'image copiée divisé par 256
VDP(39)=YD:' Correspond à la coordonnée verticale ou coller l'image copiée
VDP(40)=PD: Correspond à la page source à copier
VDP(41)=0: ???
VDP(43)=0: ???
VDP(46)=0: ???
EXECUTION DE LA COMMANDE COPY:
VDP(47)=&HD0
En suivant ces indications, si je souhaite imiter la commande BASIC suivante:
COPY (0,192)-(127,255),1 TO (50,100),0
En reprenant les explications suivantes de GDX:
COPY(XS,YS)-step(LX-1,LY-1),PS TO (XD,YD),PD
Il suffit de valoriser les variables susnommées pour selon l'exemple que je donne juste au dessus tel que:
Variables de la source:
XS=0
YS=192
LX=127 -1
LY=255 -1
PS=1
Variables de la destination:
XD=50
YD=100
PD=0
Pour tester, voici un petit programme:
10 SCREEN 8 ***************************************************************** Mode graphique.
20 SETPAGE1,1:BLOAD"BSPRITE.SC8",S,0+256************************** Chargement d'une partie d'image sur la page 1 couvrant les lignes 192 à 256
30 SETPAGE0,0:BLOAD"balpha.sc8",S,0+256 **************************** Chargement d'une partie d'image sur la page 0 de 192 à 256
40 BLOAD"halpha.sc8",S **************************************************** Chargement d'une partie d'image sur la page 0 de 1 à 191.
50 XS=0: YS=192: LX=127-1:LY=255-1:PS=1******************************* Variables de la source.
60 XD=50:YD=100:PD=0 ***************************************************** Variable de la destination.
70 VDP(27)=&HD0 ************************************************************ Execute la commande équivalente à COPY en BASIC.
80 GOTO 80
Malgré tous mes testes, les résulta reste toujours le même à savoir:
Les coordonnées de DEBUT de COPY sont correctes.
Les coortonnées de destination de COPY sont correctes.
Les coordonnées de FIN de COPY semble ne jamais être prises en comptes.
LX et LY semblent ne pas être appliquées ce qui signifie que l'intégralité des pixels se trouvant "à droite de XS" et "en bas de YS" sont toutes copiées!
Pouvez vous me donner un exemple concret que vous avez testé avec succès s'il vous plait
Merci de votre aide
ericb59
Membre non connecté
Conseiller Municipal
Oui j'ai utilisé sa méthode... Et ca fonctionne.
essaie comme ça :
essaie comme ça :
Code ASM :
Edité par
ericb59
Le 05/06/2017 à 09h33
0 SCREEN 8 20 SETPAGE1,1:BLOAD"BSPRITE.SC8",S,0+256 30 SETPAGE0,0:BLOAD"balpha.sc8",S,0+256 40 BLOAD"halpha.sc8",S 50 XS=0: YS=192: LX=127-1:LY=255-1:PS=1 60 XD=50:YD=100:PD=0 70 GOSUB 100 80 GOTO 80 90 REM 100 IF VDP(-2) and 1 THEN 100 110 VDP(33)=XS: VDP(34)=XS\256: VDP(35)=YS: VDP(36)=PS: VDP(37)=XD: VDP(38)=XD\256: VDP(39)=YD: VDP(40)=PD: VDP(41)=0:VDP(42)=LX: VDP(43)=0: VDP(44)=LY: VDP(46)=0: VDP(47)=&HD0 :RETURN
igal
Membre non connecté
Conseiller Municipal
Arf...Pas moyen, ca s'affiche de façon incohérente
Voici en vidéo:
voici le disque dur:
DOUBLE DRAGON.zip
Pour le fun, voici les scroll sur lesquels je travaille depuis un moment et auxquels je voudrais intégrer des "faux sprites" stockés hors zone sur la page 1 et que je voudrais afficher en page 0. (pour le moment, je n'ai pas intégré cela puisque j'arrive pas à faire fonctionner la méthode de GDX correctement )
Pour le moment, absolument rien n'est optimisé puisqu'il s'agit juste démontrer que le concept est réalisable
@Eric: Peux tu utiliser mon disque dur et lancer le programme LOAD"ERIC001.ASC
En fait, je voudrais afficher "un bloc" de 16X16 provenant de la page 1 et situé dans les lignes allant de 212 à 256.
Il s'agit de l'animation de Métroïd lorsqu'il est en boule
Quels que soient les paramètres que j'entre, a chaque fois, j'ai l'entièreté des PIXELS situés à la droite de XS et YS
Merci de ton aide
Voici en vidéo:
voici le disque dur:
DOUBLE DRAGON.zip
Pour le fun, voici les scroll sur lesquels je travaille depuis un moment et auxquels je voudrais intégrer des "faux sprites" stockés hors zone sur la page 1 et que je voudrais afficher en page 0. (pour le moment, je n'ai pas intégré cela puisque j'arrive pas à faire fonctionner la méthode de GDX correctement )
Pour le moment, absolument rien n'est optimisé puisqu'il s'agit juste démontrer que le concept est réalisable
@Eric: Peux tu utiliser mon disque dur et lancer le programme LOAD"ERIC001.ASC
En fait, je voudrais afficher "un bloc" de 16X16 provenant de la page 1 et situé dans les lignes allant de 212 à 256.
Il s'agit de l'animation de Métroïd lorsqu'il est en boule
Quels que soient les paramètres que j'entre, a chaque fois, j'ai l'entièreté des PIXELS situés à la droite de XS et YS
Merci de ton aide
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie