[MZ-700] Space Rally

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

[MZ-700] Space Rally

Message par hlide »

Space Rally se veut sans prétention. Il s'agira d'un jeu où il faut conduire un vaisseau au travers de dédales le plus longtemps possible.

C'est avant tout un projet technique :

1) utilisation de la RAM $0000-1FFF comme tampon de dessin virtuel de 32 lignes de 256 octets. H désigne la ligne et L la colonne. Cependant, la ligne est découpé en deux pour contenir deux tampons entrelacés : l'un contiendra l'image décalé d'un dot vers le bas pour éviter de faire le décalage de toute l'image lors d'un scroll vertical.

Pour passer à la ligne suivante, on fait :

Code : Tout sélectionner

		INC		H 		; passe à la ligne suivante
		RES		7,H		; effectue le wrapping dans le tampon si nécessaire
Pour calculer l'adresse d'une position exprimée en dot dans le tampon et afficher cette partie à l'écran :

Code : Tout sélectionner

		LD		A,H		; récupère la position Y
		AND		63		; "wrap" le si nécessaire
		SRL		A		; convertis le ligne d'écran en le divisant par deux
		RR		L		; choisi la bonne image dans la ligne selon la parité de cette dernière
						; tout en  divisant la colonne par deux 
		LD		H,A		; HL contient l'adresse source du tampon à afficher à l'écran
2) Qu'est-ce qu'un dot ? c'est ceci :
dots.png
dots.png (57.88 Kio) Consulté 6248 fois
Vous voyez l'encadré en vert ? ça correspond aux codes $F0-$FF d'affichage. Le dot haut-gauche a le bit 0 à 1, le dot haut-droit le bit 1 à 1, le dot bas-gauche le bit 2 à 1 et le dot bas-droit le bit 3 à 1. Ça permet de faire du pseudo-graphisme de résolution 80x50. Au niveau couleur, le mixage reste à 40x25.

3) Le scrolling se fait simplement en affichant une zone de 28x25 caractères puis d'attribut. Ça correspond à du 56x50 en terme de dots. Il s'effectue en dot grâce à l'entrelacement de deux images par ligne (on permute l'image à chaque scroll). L'affichage est ce qui prend le plus de temps du fait que l'accès à la VRAM n'est possible que durant les blancs horizontaux. 14 octets par blanc. Comme on a 28x25 que l'on double du fait que l'on doit afficher et le caractère et la couleur, ça nous fait donc 100 lignes sur les 312 de la résolution PAL en sortie. On a donc encore plus de la moitié des ressources CPU pour le reste comme dessiner dans le tampon virtuel via un "rolling pointer", la logique du jeu, etc. Il n'y a donc pas de décalage physique pour faire le scrolling.
2021-05-09_15-03-33.png
2021-05-09_15-03-33.png (17.01 Kio) Consulté 6245 fois
Et enfin une vidéo :
Dernière modification par hlide le 10 mai 2021 16:41, modifié 1 fois.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Alors, je vais faire un léger "off topic" ici pour expliquer une problématique et une possible solution que je n'appliquerais pas ici.

J'aurais voulu que les murs soient un peu plus coloré, alors j'ai fait une ébauche :
184860610_10226601619775013_2500871497500509202_n.jpg
184860610_10226601619775013_2500871497500509202_n.jpg (29.63 Kio) Consulté 6223 fois
Vous voyez là une tuile qui fait 16x16 dots ou 8x8 caractères que j'ai colorié. La deuxième tuile est la première avec un décalage de 1 dot vers le bas. Et là, c'est un peu le drame : la couleur ne suit pas le décalage et ne peut pas suivre du fait qu'elle suit la même contrainte de résolution 40x25 et non 80x50.

Là vient l"oeuf-tau pic" : comment faire pour que le bloc 4x4 pixels et la couleur suivent bien la résolution 80x50 ?

Supposons que je ne travaille qu'avec un seul symbole dans l'espace de dessin à point. Je prendrais celui-ci : [▐]. Si j'applique la couleur de fond (attribute bits 3..0, bit 3 toujours à 0) à la partie gauche du symbol et la couleur de texte (attribute bits 7..4, bit 7 toujours à 0) à la partie droite, j'obtiens un graphisme "parfait" en résolution 80x25 et 8 couleurs par point. Bon le point n'est pas très carré.

Bon imaginons maintenant que je me sers du comptage des signaux BLNK (blanc horizontal) pour faire en sorte de changer la couleur tous les 4 lignes de pixel (en somme tous les 4 BLNK), je pourrais donc découper ce symbole en quatre gros points jusqu'à quatre couleurs. J'aurais effectivement un graphisme "parfait" de résolution 80x50 et 8 couleurs par point ! et là un scrolling un peu plus coloré.

Et bien sûr, plus d'effet de grille non plus.

Bon, ce n'est absolument pas trivial à faire et ça s'écarte de ce qui était prévu de faire ici.
80x50x8.png
80x50x8.png (3.14 Kio) Consulté 6223 fois
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: [MZ-700] Space Rally

Message par Mokona »

Ah sympa ça un petit jeu pour le MZ-700 !

Merci pour les explications.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Bon une petite progression du jeu qui consiste à faire bouger les trois dédales (en fait deux sur trois car l'un reste droit pour que le vaisseau n'aille pas traverser le mur). Cette histoire de couleur est quand même un plaie à gérer en 80x50. Pour l'instant, je me contente juste de changer la couleur pour créer la dédale. Ça fait quelques artéfacts mais j'ai bien peur que je touche à la limite. L'autre possibilité c'est que la dédale garde la même couleur et que c'est les carrées blancs qui font la matière concrète à ne pas toucher sous peine de dommage.

Voici une vidéo des trois dédales (avancer un peu au début pour passer le chargement) :

Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [MZ-700] Space Rally

Message par 6502man »

Excellent le scrolling en mode texte :wink:

J'aime bien la démarche technique :D
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Merci @Mokona et @6502man ! :)

J'ai ajouté le mouvement du vaisseau. Alors sachez qu'il peut être rapide avec un dot à 50 fps mais j'ai dû le réduire à un dot par 25 fps. Il se déplace avec les touches [<-] et [->]. C'est chaud quand même. J'ai choisi trois dédales mais je me demande si je ne devrais pas pas passer à deux dédales un peu plus larges.

Pour voir un peu l'effet, j'ai ajouté un auto-pilote au vaisseau. Au départ, je le faisais suivre la dédale n°2 mais je trouvais ses mouvements un peu ennuyeux et pas humain pour ainsi dire. Comme j'ai 64 octets par ligne et que je n'en utilise que 28, j'historise la position de chaque dédale dans la même ligne à partir de l'octet 26. Je rajoute deux autres octets pour la position et la taille de la dédale n°2 fusionné ou non avec les deux autres dédales. Du coup je peux calculer le centre à quelques lignes devant le vaisseau pour que celui-ci se dirige vers ce point. Avec la fusion des dédales (qui contient a minima la dédale n°2), j'obtiens un mouvement plus frénétique.

Messieurs, à vous la vidéo :
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [MZ-700] Space Rally

Message par 6502man »

Excellent :wink:

Il manque le son et la tu va réaliser le top de l'année sur MZ-700 :wink:
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Bon je recherche un musicien et bruiteur pour ce jeu sur AT2. Quelqu'un m'a conseillé de demander à T&J de http://tj.gpa.free.fr/ qui est aussi dans ce site mais je ne trouve pas son pseudo d'ici depuis son site.

EDIT: Markerror, non ?
Avatar de l’utilisateur
fneck
Site Admin
Messages : 17423
Inscription : 01 avr. 2007 12:03
Localisation : Drôme Provençale (26)
Contact :

Re: [MZ-700] Space Rally

Message par fneck »

Markerror, oui !
Fabien https://www.system-cfg.com
Les bonnes pratiques de l'utilisateur du forum viewtopic.php?f=14&t=3
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Bon ce n'est pas gagné.

Quand le programme se lance, il commence avec un DI et jamais il repasse en EI. La zone $0000-$0FFF est une sorte de code de BIOS et $1000-$1FFF sa RAM système. Je n'en ai pas besoin car je gère moi-même les I/O. Du coup, je transforme $0000-1FFF en DRAM et plus précisément en un tampon vidéo virtuel de 8 Ko (256 octets x32 lignes).

L'ajout d'une interruption activée tous les 3 /HBLANK demande du coup une adaptation. Techniquement, je peux encore utiliser l'adresse $0038 car cela tape dans une endroit non utilisé par la gestion vidéo virtuelle mais je en trouve pas ça très propre si on décide d'utiliser ces zones inutilisées un de ces jours. J'ai donc opté pour la solution IM2 à la Spectrum : je remplis la table de vecteur d'interruption placée dans $CE00-$CF00 de valeur $CF pour placer l'ISR en $CFCF.

Seulement il y a un truc que j'ai oublié : le Z80 PUSH-e l'adresse de retour dans la pile contrairement à d'autres architectures qui ont un registre à ce effet. Si donc j'utilise la pile pour pointer des données de source (en l'occurrence le tampon de vidéo) pour faire des POP puis je place la pile dans la VRAM pour rendre sur l'écran via des PUSH, je vais créer une corruption dans ces piles si jamais l'interruption se passait. Et c'est même assez systématique. Accepter de protéger par une paire de DI/EI ces portions de code manipulant l'adresse de pile n'est pas une option car ça casserait le rythme (et apparemment les interruptions durant ces parties de code sont purement ignorés, 1 sur 3 sont réalisées durant le rendu).

Donc deux solutions :

1) J'abandonne le timer à 5200 Hz mais je peux le faire à 100 Hz car je peux faire que l'interruption n'ai jamais lieu durant le rendu (100 HBLANK pour le rendu, 156 HBLANK pour le timer sur 312 HBLANK de frame). Au niveau son, ce ne sera pas de la folie. Pour rappel, je peux transférer au maximum 14 octets dans la VRAM par HBLANK.

2) Je persévère mais je dois changer d'optique : découper le rendu en autant de routine ISR qui vont faire leur séquence de POP/PUSH par /HSYNC. Le timer serait à 15600 Hz. Hors rendu, on aurait un ISR qui s'occupe du son et durant le rendu de la vidéo et du son. Vu les instructions à réaliser dans l'interruption avant de transférer les octets à la VRAM, il faudra sans doute 6 HBANK ou plus au lieu des 4 HBLANK pour dessiner une ligne complète parce que j'aurais pas la possibilité de transférer 14 octets par HBLANK.

Le 2) est vraiment "touchy" et plutôt hasardeux à coder.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Ouah, je crois que je viens de trouver la solution !

En fait, l'interruption a lieu tous les trois HBLANK, il en faut deux pour dessiner une ligne : je place un HALT avant le transfert de la ligne en VRAM puis met un LD SP,$CFF0 à la fin du transfert. De cette façon le rendu est synchronisé sur le timer et il n'y a pas de débordement ni de corruption de la pile.

Résultat, je retrouve l'image fluide, sans corruption et il m'affiche bien 150 HBLANK pour le rendu au lieu de 100 comme prévu (on a donc bien nos interruptions tous les 3 HBLANK !) et un frame qui prend 171 HBLANK sur 312, on a donc de la marge !

je ne sais pas si je vais utiliser AT2 ou faire un tracker. Je pense que le mieux ce serait que le "tracker" soit appelé par frame pour remplir un buffer de 312 échantillons qui seront joués un par un par l'interruption.

Tout un programme que je ne maîtrise pas.
Patrick
Messages : 2019
Inscription : 16 mai 2009 09:30
Localisation : Clermont-Ferrand

Re: [MZ-700] Space Rally

Message par Patrick »

C'est très intéressant.
A la vision de ta dernière vidéo, j'avais une très nette impression de 3D, entre le fond du ravin et la surface.

J'attends les ennemis et l'attaque de l'Etoile noire :D
Patrick
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

@Patrick

En fait, au début, je voulais dessiner un autre fond dans les dédales (toujours bleu sur fond noir) mais qui défilerait deux moins vite.

https://lmfwg.csb.app/
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Space Rally

Message par hlide »

Donc suite de mon aventure "noise"-ique.

Alors j'ai eu quelques difficultés à faire fonctionner cette interruption.

1) Je dois relancer la programmation du compteur PIT CTC2 à chaque interruption,

2) Je ne dois surtout pas mettre à 1 le compteur PIT CTC1 mais plutôt à 3 et du coup mettre à 1 plutôt le compteur PIT CTC2,

3) Me servir de HALT devant chaque ligne vidéo pour avoir le temps de manipuler la pile pour lire le buffer "graphique" et écrire dans la VRAM sans que l'interruption vienne corrompre la pile (elle est "restauré" à temps avant qu'une nouvelle interruption se déclenche).

J'ai pris la musique "cantslowdown" pour la faire jouer avec Beepola puis générer un fichier WAV. Avec Audacity, j'ai joué avec "Amplify" à l'extrême après l'avoir rééchantillonné à 5023 Hz. Après j'ai utilisé pcm2pwm qui génère un fichier qui peut s'apparenter à du LEP simplifié. Malheureusement, le fichier faisait quand même plus de 100 Ko. Je l'ai donc tronqué à 32 Ko que j'ai inséré dans mon programme de jeu. L'ISR a été adapté.

Et voilà l'effet :



Alors non ce n'est pas parfait. La fluidité en prend un coup et j'ai pu le vérifier en supprimant la synchronisation verticale : la vitesse ne change pas donc je pense que la combinaison à haute fréquence et la longueur de l'interruption est vraiment très limite. Je vais donc sûrement opter pour une faible résolution : 4 ou 6 /HSYNC au lieu de 3 /SYNC.
Avatar de l’utilisateur
6502man
Messages : 12286
Inscription : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [MZ-700] Space Rally

Message par 6502man »

C'est déjà sympa :wink:

Après du 1 bit ca reste limité.
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.
Répondre