La Place des Développeurs MSX2 Screen5 test Test en assembleur du VDP en mode SCREEN5
igal
Membre non connecté
Conseiller Municipal
Reprise du message précédent
Désolé si je t'ai induit en erreur..SET SCROLL est une commande réservée au MSX2+ donc au VDP 9958.
Cette commande joue sur le registre VDP(27) qui n'existe pas sur le VDP 9938 (msx2).
La présence du registre VDP(27) permet un scrolling horizontal Hardware et très facile à mettre en oeuvre sur MSX2+.
Tout cela ne t'intéresse pas en définitive puisque tu souhaites te limiter au MSX2 soit le VDP 9938 qui n'a pas ce registre.
(C'était juste pour te mettre au parfum sur ce procédé)
Passons à la chose suivante.
Le VDP 9938 (msx2) à la commande SET ADJUST (je sais pas quel registres cela concerne dans la pratique).
Bref.. Le ou les registres qui sont utilisés lors de la commande SET ADJUST permettent de déplacer l'écran sur l'axe H et/ou V de 16 pixels au total et bien sur en Hardware!
J'avais exploré cette piste de la façon suivante:
1) je valorise SET ADJUST à -7
2) j'affiche une bribe d'image verticale épaisse d'un pixel.
3) je valorise SET ADJUST à -6
4) j'affiche une nouvelle bribe verticale épaisse d'un pixel.
etc etc...
Tu peux faire par tranche de 2 pixels ou plus... c'est selon la fluidité du scroll que tu recherche.
Une fois SET ADJUST à 8, il suffit de déplacer (je me rappel plus comment) la colonne épaisse de 16 pixels que tu as créé par morceaux de bribes.. Il te reste plus qu'à la déplacer d'un cran de 16 pixels d'un coup puis de remettre SET ADJUST à -7...
Tu recommences tout ca en boucle et tu obtiens un scrolling hardware sur VDP 9938.
Il te suffit de chercher quel registre est affecté par SET ADJUST X pour essayer la chose!
Encore une fois, en basic, lors du déplacement du bloc de 16 pixels et le retour à SET ADJUST -7, ca foutait la gerbe.
Par contre, je pense qu'en langage machine, cela devrait passer très facilement
TurboSEB
Membre non connecté
Conseiller Municipal
Ah c'est vraiment BEAU de voir qquun qui maitrise son sujet comme ca
Je le vois d'ici , le p'tit Igal qui trepigne d'impatience , que l'on a reussi par ruse a attaché dans un coins pour le moment , te posé les questions les plus folle
c'est possible des routines exploitable par une simple instruction Basic,a implanter en Ram , lancable par un bload ,R , qui ajouterais donc des instructions basic supplementaire , un peu comme une boucle X-Basic
Je le vois d'ici , le p'tit Igal qui trepigne d'impatience , que l'on a reussi par ruse a attaché dans un coins pour le moment , te posé les questions les plus folle
c'est possible des routines exploitable par une simple instruction Basic,a implanter en Ram , lancable par un bload ,R , qui ajouterais donc des instructions basic supplementaire , un peu comme une boucle X-Basic
MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
igal
Membre non connecté
Conseiller Municipal
sylvain :
Le programme a alors une structure qui ressemble à :
0) INITIALISATIONS
1) INITIALISATION DU HOOK (appel à GESTION_JEU)
2) BOUCLE INFINIE (100 GOTO 100 par exemple)
3) GESTION_JEU (gestion déplacement joueur, gestion scroll, gestion déplacement ennemis, etc...)
0) INITIALISATIONS
1) INITIALISATION DU HOOK (appel à GESTION_JEU)
2) BOUCLE INFINIE (100 GOTO 100 par exemple)
3) GESTION_JEU (gestion déplacement joueur, gestion scroll, gestion déplacement ennemis, etc...)
C'est exactement la structure des jeux de Konami.
J'utilise également cette structure, en me basant sur l'interruption VBLANK. Cela permet ainsi de jouer le rôle d'un métronome dans les routines du jeu. Ma boucle d'attente infinie est celle de la détection des mouvements du joueur. Toutes les x interruptions (et donc tous les x/50e de seconde), il y a un branchement en fonction du besoin (musique, mise à jour du décor, ...).
Il y a 2 contraintes :
- l'ensemble des actions ne peut dépasser la valeur d'une frame (1/50e de seconde, soit environ 72000 unités de temps du Z80 - nommés t-states -, ce qui représente à peu près 12.000 instructions de taille moyenne)
- les actions graphiques ne peuvent dépasser le temps qui s'écoule entre le VBLANK et le redémarrage du traçage de la ligne où elles ont lieu, sous peine de voir des problèmes d'affichage
Tout cela sachant que la gestion par le BIOS des interruptions (passage obligé avant de revenir au code principal) prends un maximum de 10.000 unités de temps du Z80).
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
@Jipe: ca ressemble furieusement à ce que je faisait sur C64 pour réaliser des scroll au pixel près, on décalé le registre de décalage horizontalement ou verticalement ou les deux, grace à une interruption on pouvait réaliser des décalages différents selon la zone écran (le fameux raster interupt), ca me rajeunit pas tout ca
Par contre si on veux décaler qu'une partie de l'écran ca va pas aller ou alors utiliser le registre du vertical interruption du VDP ...
@Sylvain:
Je précise que pour l'instant je ne fait que de tester les commandes internes au VDP, évidemment pour réaliser un jeu il faut optimiser et tenir compte de tous ce que l'on doit traiter en plus du graphisme (son, interaction, score, ...).
@Sylvain:
Je connais pas ce debugger il à l'ai très pratique, je vais tester ....
@Metalion:
De mon avis les interruptions CPU ne sont utilisables que si le total des actions à réaliser n'est pas critique par rapport au temps du Vblank.
D'ailleurs y a t'il un delai connu pour ce Vblank ?
De toutes façons le scroll du décor + incrustation du perso risque d'être trop long pour un VBLANK, à voir ...
@Sylvain et Metalion: si vous avez une expérience du VDP des MSX2 n'hésitez pas à partager, je débute sur ce VDP donc j'apprend et ca j'adore
Je viens de m'amuser à rajouter un parallax scrolling pour les nuages :
Vigi4.zip
Ce n'est pas optimisé mais je voulais voir si "l'image aller décrocher" (saccade et clignotement) mais non c'est juste un peu lent !
Donc je pense que pour faire un scroll il vaut mieux utiliser le registre R18 pour l'écran entier quoi que après 8 pixels de décalages il faut déplacer tout l'écran, pas sur que ca soit pas saccadé !
Edité par 6502man Le 23/07/2018 à 18h01
Par contre si on veux décaler qu'une partie de l'écran ca va pas aller ou alors utiliser le registre du vertical interruption du VDP ...
@Sylvain:
Citation :
Si vous ne voulez pas avoir d'effets indésirables lors des opérations de copies graphiques il faut les réaliser pendant le temps mort d'affichage des lignes en dehors de la zone graphique.
Soit pendant le VBLANK (affichage des lignes en bas et en haut de l'image), soit pendant le HBLANK (parties à gauche et à droite de l'image).
Soit pendant le VBLANK (affichage des lignes en bas et en haut de l'image), soit pendant le HBLANK (parties à gauche et à droite de l'image).
Je précise que pour l'instant je ne fait que de tester les commandes internes au VDP, évidemment pour réaliser un jeu il faut optimiser et tenir compte de tous ce que l'on doit traiter en plus du graphisme (son, interaction, score, ...).
@Sylvain:
Je connais pas ce debugger il à l'ai très pratique, je vais tester ....
@Metalion:
Citation :
Il y a 2 contraintes :
- l'ensemble des actions ne peut dépasser la valeur d'une frame (1/50e de seconde, soit environ 72000 unités de temps du Z80 - nommés t-states -, ce qui représente à peu près 12.000 instructions de taille moyenne)
- les actions graphiques ne peuvent dépasser le temps qui s'écoule entre le VBLANK et le redémarrage du traçage de la ligne où elles ont lieu, sous peine de voir des problèmes d'affichage
Tout cela sachant que la gestion par le BIOS des interruptions (passage obligé avant de revenir au code principal) prends un maximum de 10.000 unités de temps du Z80).
- l'ensemble des actions ne peut dépasser la valeur d'une frame (1/50e de seconde, soit environ 72000 unités de temps du Z80 - nommés t-states -, ce qui représente à peu près 12.000 instructions de taille moyenne)
- les actions graphiques ne peuvent dépasser le temps qui s'écoule entre le VBLANK et le redémarrage du traçage de la ligne où elles ont lieu, sous peine de voir des problèmes d'affichage
Tout cela sachant que la gestion par le BIOS des interruptions (passage obligé avant de revenir au code principal) prends un maximum de 10.000 unités de temps du Z80).
De mon avis les interruptions CPU ne sont utilisables que si le total des actions à réaliser n'est pas critique par rapport au temps du Vblank.
D'ailleurs y a t'il un delai connu pour ce Vblank ?
De toutes façons le scroll du décor + incrustation du perso risque d'être trop long pour un VBLANK, à voir ...
@Sylvain et Metalion: si vous avez une expérience du VDP des MSX2 n'hésitez pas à partager, je débute sur ce VDP donc j'apprend et ca j'adore
Je viens de m'amuser à rajouter un parallax scrolling pour les nuages :
Vigi4.zip
Ce n'est pas optimisé mais je voulais voir si "l'image aller décrocher" (saccade et clignotement) mais non c'est juste un peu lent !
Donc je pense que pour faire un scroll il vaut mieux utiliser le registre R18 pour l'écran entier quoi que après 8 pixels de décalages il faut déplacer tout l'écran, pas sur que ca soit pas saccadé !
Edité par 6502man Le 23/07/2018 à 18h01
6502man :
Donc je pense que pour faire un scroll il vaut mieux utiliser le registre R18 pour l'écran entier quoi que après 8 pixels de décalages il faut déplacer tout l'écran, pas sur que ca soit pas saccadé !
C'est l'astuce qui est généralement utilisée sur MSX2 pour réaliser un scroll horizontal. La seule chose qui reste visible malgré tout étant le clignotement des zones du bord de l'image, que l'on peut parfois masquer avec des sprites.
Space Manbow utilise cette technique pour le scroll horizontal sur MSX2.
On voit le clignotement des bords sur cette vidéo, à partir de 00:29 : https://www.youtube.com/watch?v=ABZiuNpGEHY
6502man :
De mon avis les interruptions CPU ne sont utilisables que si le total des actions à réaliser n'est pas critique par rapport au temps du Vblank.
D'ailleurs y a t'il un delai connu pour ce Vblank ?
D'ailleurs y a t'il un delai connu pour ce Vblank ?
Qu'est-ce que tu veux dire par délai du VBLANK ?
Je préfère l'aborder en terme de nombre d'instructions : le nombre de t-states est égal au temps total d'une frame que multiplie la fréquence Z80 :
. 50Hz : 20000 µsec x 3.579545 MHz = 71590 t-states
. 60Hz : 16667 µsec x 3.579545 MHz = 59659 t-states
Voilà ce que ça donne en pratique :
Edité par Metalion Le 24/07/2018 à 11h02
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
Merci Metalion pour ces précisions techniques
Maintenant reste à savoir si le VDP est assez rapide pour faire tous ce qu'on lui demande en 27675 T-states, et y a t'il un moyen de connaitre le nombre de T-states que demande une commande du VDP par exemple pour HMMM ???
Peut être un émulateur à intégré ca dans son debuggeur ???
Je n'ai pas eu le temps depuis de continuer, si j'arrive à trouver un peu de temps d'ici la fin de la semaine (pas sur) je fait d'autres tests ...
Maintenant reste à savoir si le VDP est assez rapide pour faire tous ce qu'on lui demande en 27675 T-states, et y a t'il un moyen de connaitre le nombre de T-states que demande une commande du VDP par exemple pour HMMM ???
Peut être un émulateur à intégré ca dans son debuggeur ???
Je n'ai pas eu le temps depuis de continuer, si j'arrive à trouver un peu de temps d'ici la fin de la semaine (pas sur) je fait d'autres tests ...
Je viens de réorganiser le code et rajouter un ennemi ainsi que l'attente du Vblank pour réaliser toutes les opérations graphiques ca donne un résultat intéressant
(ne pas tenir compte du carré noir sous l'ennemi, ainsi que la gestion simpliste du déplacement ce n'est qu'un test)
Pour vous faire une idée du résultat :
VigiNEW.zip
(ne pas tenir compte du carré noir sous l'ennemi, ainsi que la gestion simpliste du déplacement ce n'est qu'un test)
Pour vous faire une idée du résultat :
VigiNEW.zip
6502man :
Maintenant reste à savoir si le VDP est assez rapide pour faire tous ce qu'on lui demande en 27675 T-states, et y a t'il un moyen de connaitre le nombre de T-states que demande une commande du VDP par exemple pour HMMM ???
Les T-states, c'est pour pouvoir facilement transformer le temps en nombre d'instructions. Les instructions les plus rapides (AND A, RLA, ...) prennent 4 T-states. Les plus lentes vont jusqu'à 23 T-states (généralement celles qui utilisent les registres à décalage IX et IY).
En ce qui concerne la vitesse des instructions du V9938, une analyse assez poussée a été réalisée par Grauw (membre actif sur MRC) : http://map.grauw.nl/articles/vdp_commands_speed.php . La vitesse est mesurée en octets par frame, c'est à dire en nombre d'octets que le VDP est capable de traiter entre deux interruptions BIOS. La mesure est faite en 192 lignes ou en 212 (Lin), avec ou sans les sprites (Spr), ou écran éteint (Blank).
Code :
LMMM accuracy: 16 HMMM accuracy: 32 YMMM accuracy: 32
Spr / Lin - Speed 50/60Hz Spr / Lin - Speed 50/60Hz Spr / Lin - Speed 50/60Hz
on / 212 - 1232 / 976 on / 212 - 3552 / 2784 on / 212 - 4192 / 3168
on / 192 - 1264 / 1008 on / 192 - 3616 / 2880 on / 192 - 4384 / 3360
off / 212 - 1584 / 1312 off / 212 - 4384 / 3616 off / 212 - 5856 / 4832
off / 192 - 1584 / 1312 off / 192 - 4384 / 3684 off / 192 - 5856 / 4864
--Blank-- - 1600 / 1344 --Blank-- - 4512 / 3776 --Blank-- - 6112 / 5120
Edité par Metalion Le 25/07/2018 à 17h18
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
igal
Membre non connecté
Conseiller Municipal
@6502Man:
Je sais pas si le carré noir sous le PNJ est un sprite mais ca me donne l'occasion d'en parler.
Lors de mes expérimentations passées, j'avais pensé à utiliser des personnages en "faux sprites" (comme tu le fais) combinés a des vrais sprites qui permettent de détecter facilement des collisions par le biais de l'instruction ON SPRITE GOSUB. Je suppose que l'équivalent existe en langage machine
La superposition des deux "genres" Faux sprites (copy x,y) + Vrai Sprite (Put Sprite..) double le nombre d'opérations BASIC à gérer et donc pas rentable..
Par contre, en assembleur, tu devrais pouvoir utiliser les deux méthodes simultanément pour arriver à quelque chose de correct.
Un exemple d'utilisation des vrais sprites avec cette approche dans la vidéo ci dessous:
https://www.youtube.com/watch?v=4Beelx7Rphg
Ici, le sprite Vert permet de simuler [Le Hero] celui qui se déplace.
Les[Les Plateformes] par des sprites alignés .
Il suffit de superposer la couche graphique des [Faux Sprites] par dessus les [vrais sprites] en leurs attribuant les même variables de déplacement et collisions [X, Y] pour que tous les mouvements [Vrais sprites] + [Faux sprites] coïncident.
Bon c'est l'idée générale mais c'est surtout l'occasion d'aborder un sujet qu'on à pas eu le temps d'aborder la dernière fois
Je sais pas si le carré noir sous le PNJ est un sprite mais ca me donne l'occasion d'en parler.
Lors de mes expérimentations passées, j'avais pensé à utiliser des personnages en "faux sprites" (comme tu le fais) combinés a des vrais sprites qui permettent de détecter facilement des collisions par le biais de l'instruction ON SPRITE GOSUB. Je suppose que l'équivalent existe en langage machine
La superposition des deux "genres" Faux sprites (copy x,y) + Vrai Sprite (Put Sprite..) double le nombre d'opérations BASIC à gérer et donc pas rentable..
Par contre, en assembleur, tu devrais pouvoir utiliser les deux méthodes simultanément pour arriver à quelque chose de correct.
Un exemple d'utilisation des vrais sprites avec cette approche dans la vidéo ci dessous:
https://www.youtube.com/watch?v=4Beelx7Rphg
Ici, le sprite Vert permet de simuler [Le Hero] celui qui se déplace.
Les[Les Plateformes] par des sprites alignés .
Il suffit de superposer la couche graphique des [Faux Sprites] par dessus les [vrais sprites] en leurs attribuant les même variables de déplacement et collisions [X, Y] pour que tous les mouvements [Vrais sprites] + [Faux sprites] coïncident.
Bon c'est l'idée générale mais c'est surtout l'occasion d'aborder un sujet qu'on à pas eu le temps d'aborder la dernière fois
Visiteur
Vagabond
Message : 0
@Igal
Tout existe en langage machine, puisque le BASIC et tout autre langage qui puisse exister, de toutes façons, doit être interprété en langage machine
Quelques commentaires au sujet de l'utilisation de la détection de collisions avec les "vrais" sprites :
- un indicateur d'un registre du VDP permet de savoir s'il y a collision entre 2 sprites mais ne dit pas lesquels, il faut lire la position des sprites au moment de la collision pour savoir quel sprite superspoe tel autre (ce qui n'est pas important si on a seulement un héro et un ennemi)
- si on active la détection de collision des sprites, on ne peut pas utiliser la technique de coloration par "ou" à la superposition de sprites (en utilisant 2 sprites on peut avoir 3 couleurs par ligne horizontale voire 5 ou plus en superposant 3 sprites...), mais ce n'est pas important dans le cas exposé ici
- il faudrait que les vrais sprites recouvrent exactement la surface des faux sprites, là ça commence à coincer.
Et le problème principal ; la détection de collision des sprites est réalisées lorsque 1 pixel "allumé" (à 1) superpose un pixel "allumé" d'un autre sprite. Or les vrais sprites seront toujours affichés par dessus les "faux sprites" et cacheraient dont les faux sprites que l'on voudraient voir uniquement. Il faudrait utiliser une couleur transparente pour les vrais sprites et je ne pense pas que cela soit possible.
Tout existe en langage machine, puisque le BASIC et tout autre langage qui puisse exister, de toutes façons, doit être interprété en langage machine
Quelques commentaires au sujet de l'utilisation de la détection de collisions avec les "vrais" sprites :
- un indicateur d'un registre du VDP permet de savoir s'il y a collision entre 2 sprites mais ne dit pas lesquels, il faut lire la position des sprites au moment de la collision pour savoir quel sprite superspoe tel autre (ce qui n'est pas important si on a seulement un héro et un ennemi)
- si on active la détection de collision des sprites, on ne peut pas utiliser la technique de coloration par "ou" à la superposition de sprites (en utilisant 2 sprites on peut avoir 3 couleurs par ligne horizontale voire 5 ou plus en superposant 3 sprites...), mais ce n'est pas important dans le cas exposé ici
- il faudrait que les vrais sprites recouvrent exactement la surface des faux sprites, là ça commence à coincer.
Et le problème principal ; la détection de collision des sprites est réalisées lorsque 1 pixel "allumé" (à 1) superpose un pixel "allumé" d'un autre sprite. Or les vrais sprites seront toujours affichés par dessus les "faux sprites" et cacheraient dont les faux sprites que l'on voudraient voir uniquement. Il faudrait utiliser une couleur transparente pour les vrais sprites et je ne pense pas que cela soit possible.
igal :
La superposition des deux "genres" Faux sprites (copy x,y) + Vrai Sprite (Put Sprite..) double le nombre d'opérations BASIC à gérer et donc pas rentable... Par contre, en assembleur, tu devrais pouvoir utiliser les deux méthodes simultanément pour arriver à quelque chose de correct.
Non, l'assembleur ne change pas absolument pas l'ordre des opérations. Tout reste linéaire.
C'est pareil qu'en BASIC, sauf que c'est nettement plus rapide.
MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie