MSX Village forum

L'école Comment contourner la limitation de l'instruction COPY

GDX Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 17/01/2011 à 08h52

Messages: 3004

Le 22/08/2013 à 07h45
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 à :

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
   
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5566

Le 22/08/2013 à 08h05
:top :top


banniere-ericb59e
Site web    
Fabf Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 24/08/2010 à 20h55

Messages: 4833

Le 22/08/2013 à 08h17
Très intéressant et clair, merci :top
Franck Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 22h54

Messages: 3345

Le 22/08/2013 à 08h59
Merci mille fois GDX pour ce cours extrêmement clair ! :top
   
igal Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 29/07/2010 à 17h19

Messages: 5492

Le 04/06/2017 à 14h18
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 :D
Merci de votre aide :tchin


Tiens... voila du boudin, voila du boudin, voila du boudin... :siffle
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5566

Le 05/06/2017 à 09h32
Oui j'ai utilisé sa méthode... Et ca fonctionne.

essaie comme ça :

Code ASM :
 
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
 
Edité par ericb59 Le 05/06/2017 à 09h33


banniere-ericb59e
Site web    
igal Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 29/07/2010 à 17h19

Messages: 5492

Le 06/06/2017 à 18h52
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 :D
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 :tchin


Tiens... voila du boudin, voila du boudin, voila du boudin... :siffle
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie