[SHARP MZ-700] BRICK BUSTER

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

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 11 mai 2020 15:23

Aujourd'hui je vais parler de la raquette.

La raquette c'est 5 ou 7 caractères contigus à afficher. Il en sort une propriété intéressante : je n'ai pas besoin de coordonnées X et Y. En effet, la position m'est donnée directement par son adresse en VRAM (qui commence en $D000) et comme la ligne 23 (40 caractères en largeur) est comprise ente $D398 et $D3C0, je peux me limiter à considérer l'octet de poids faible de cette adresse pour confiner la raquette dans une intervalle légèrement plus petite en magnitude que ]$98, $B6[ (la magnitude est de 30 et non 40 caractères lors du jeu).

Pour bouger il me suffit d'incrémenter ou de décrémenter le poids faible de son adresse en restant dans l'intervalle adaptée à la dimension de la raquette. Pour gérer le rebond de la balle, je teste d'abord si la position Y de la balle est 23 et si c'est le cas, je vérifie que le poids faible de l'adresse calculée de la balle est dans l'intervalle des poids faibles min et max de l'adresse de la raquette.

Ça fonctionne bien mais il y a un hic : il y a 50 images par seconde, donc 50 déplacements de la raquette par seconde ! j'ai beau appuyé et relâché le plus court possible, ma raquette bouge pas moins de deux caractères.

Pour m'assurer que la boucle de jeu reste simple, j'ai décidé de rajouter une "vitesse" et une "accélération" à la raquette. A 50 FPS, n'espérez pas quelque chose de fluide à cause de la représentation en caractère : il s'agit de permettre faire le mouvement de 1 caractère immédiat avec une accélération exponentielle pour embrayer sur un déplacement rapide en touche continue.

Comment ? je procède comme si j'avais un nombre fixe 16.8 au lieu de 16.0 initialement. La partie fractionnaire ne sert pas de position mais de valeur initiale de "vitesse". Il sera toujours 128 sans déplacement, de 0 à l'amorce de déplacement à gauche et de 255 à droite. L'accélération est également initialisée au changement de direction à une valeur arbitraire (actuellement 00011111b - plus elle est petite, plus la raquette mettra du temps à rentrer en vitesse optimale après le déplacement initial).

Voici comment j'incrémente/décrémente la position de la raquette avec une pseudo vitesse et une pseudo accélération :

Code : Tout sélectionner

RACKET_ACCEL	EQU 00011111b ; valeur la plus grande qui me permet un déplacement de 1 caractère sans artefacts par la suite 
...
@1:		JR		Z,@0f ; direction positive, on saute car c'est déplacement à gauche là
		LD		A,(DE) ; DE contient l'adresse de l'octet "vitesse" de la raquette
move_racket_laccel: ; accélération à gauche
		SUB		RACKET_ACCEL ; ici, on devrait avoir un nombre de type -((2^n)-1)
		DEC		A ; mais on veut faire -(2^n)  !
		LD		(DE),A ; mise à jour de la vitesse
		LD		BC,0 ; joie du Z80 avec ses limitations en 16-bit
		SBC		HL,BC ; met à jour l'addrese de position de la raquette
		LD		A,L ; mais à ce niveau seul le poids faible compte
move_racket_posmin:
		CP		RACKET_POSITION_MIN+3 ; "leftmost" position?
		JR		Z,@2b
		LD		(racket_new_position),HL	; Met à jour la position à raquette
		LD		HL,move_racket_laccel+1 ; accélère "exponentiellement" la vitesse à gauche
		SLL		(HL) ; multiplie par 2 et rajoute 1 en bit 0 et cape la valeur à 255 ! 
		RET ; c'est fini
@0:		LD		A,(DE)
move_racket_raccel: ; même chose mais à droite !
		ADD		A,RACKET_ACCEL ; ici, on devrait avoir un nombre de type +(2^n)-1
		INC		A ; mais on veut faire +(2^n)  !
		LD		(DE),A
		LD		BC,0
		ADC		HL,BC
		LD		A,L
move_racket_posmax:
		CP		RACKET_POSITION_MAX-2		; "rightmost" position?
		JR		Z,@2b
		LD		(racket_new_position),HL
		LD		HL,move_racket_raccel+1 ; accélère "exponentiellement" la vitesse à droite
		SLL		(HL) ; multiplie par 2 et rajoute 1 en bit 0 et cape la valeur à 255 !
		RET
En faisant varier RACKET_ACCEL, j'obtiens un résultat plus ou moins bien. L'accélération exponentielle est bien trop rapide pour l'apercevoir et espérer une accélération harmonieuse (déplacement par caractère). Le but est essentiellement de conserver la vitesse tout en permettant de se déplacer par pas de 1 quand c'est souhaitable.
Modifié en dernier par hlide le 11 mai 2020 23:19, modifié 1 fois.

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 11 mai 2020 23:09

Mise à jour du poste initial avec des images GIF en lieu et place des images statiques pour mieux rendre compte de la cinématique actuelle (en fin sur du 25 FPS au lieu de 50 FPS, c'est moins évident).

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 23 mai 2020 00:10

Dernière réalisation en date en vidéo avec plus d'effet visuel :

ricco59
Messages : 55
Enregistré le : 23 mai 2007 22:13
Localisation : Près d'Arras

Re: [SHARP MZ-700] BRICK BUSTER

Message par ricco59 » 24 mai 2020 11:40

EXcellent boulot et belle maitrise du mode caractère ainsi que de la machine :)

Je vais suivre les evolutions

Bon dimanche

Eric
Dev en cours
* StepFive > Atari Falcon030 (en pause)
* W.I.I (Where Is It ?) > Colecovision (en cours)

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 24 mai 2020 22:01

Merci Eric !

En pensant à cette histoire de compteur de lignes dans le jeu VG5000 Lode Runner, je me suis dit que je devais regarder du côté de mon jeu.

En fait, j'avais entièrement désactivé les interruptions par un DI en début du programme, car je n'en avais pas besoin et j'avais rapidement créé ma routine de scrutation des touches qui permet de connaître l'état pressé d'un touche indépendamment d'une autre. Du coup je n'utilisais plus la ROM monitor qui devient inutile. Je peux passer la zone de la ROM en DRAM pour installer directement mon RET à l'adresse $0038.

Mais je me suis dit que ce serait bien de "compter" les lignes en utilisant cette interruption qui servait à compter le passage en matin/après-midi avec correction de la date en seconde par le monitor. Là, je n'ai aucun intérêt avec cette fonctionnalité. Deux compteurs du PIT8253 entrent en jeu :
mz8253bl.gif
mz8253bl.gif (3.78 Kio) Vu 54 fois
On voit que le compteur 1 sert à compter des secondes et que le compteur 2 déclenche au bout d'une demi-journée une interruption qui va servir à modifier l'indicateur AM/PM du monitor et à réajuster le compteur 1 pour corriger une dérive des secondes.

Je me suis dit que je pourrais utiliser cette paire pour recréer le compte de /VSYNC indirectement. Normalement le PAL a 312 lignes. Pour ce faire, je fais en sorte que le compteur 1 (toujours mode 2) compte non plus les secondes mais les BLNK et je mets le compteur 2 à 312 BLNK avant qu'il ne déclenche l'interruption.

Code : Tout sélectionner

CNT1					EQU	1
CNT2					EQU 312
_main:	DI
		LD		SP,$C000
		OUT		($E0),A					; set area $0000-$0FFF as DRAM
		LD		A,$C9					; put RET at $0039 (RST $38)
		LD		($0038),A

		LD		HL,$E007				; $E007 - counter control
		LD		(HL),$74				; counter #1 - MODE 2 - set LSB counter then MSB counter
		LD		(HL),$B0				; counter #2 - MODE 0 - set LSB counter then MSB counter
		LD		L,$05					; $E005 - counter #1
		LD		(HL),(CNT1>>0)&255
		LD		(HL),(CNT1>>8)&255
		INC		L						; $E006 - counter #2
		LD		(HL),(CNT2>>0)&255
		LD		(HL),(CNT2>>8)&255
Maintenant ma routine d'attente de la vsync va faire trois choses : faire un HALT puis attendre la /VSYNC puis remettre les compteurs (réajustement par rapport au vsync) :

Code : Tout sélectionner

@4:		LD		HL,$E002
		EI
		HALT
		DI
		LD		A,$7F
@0:		CP		(HL)
		JP		NC,@0b
@0:		CP		(HL)
		JP		C,@0b
		LD		L,$05
		LD		(HL),(CNT1>>0)&255
		LD		(HL),(CNT1>>8)&255
		INC		L
		LD		(HL),(CNT2>>0)&255
		LD		(HL),(CNT2>>8)&255
		RET
Je note qu'avec un CNT2 supérieur à 312, on perd une frame sur deux donc je suis en bonne voie pour avoir un détecteur de dépassement pour le débogage.
Modifié en dernier par hlide le 24 mai 2020 23:12, modifié 3 fois.

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 24 mai 2020 23:06

En regardant de plus près la routine de détection de /VBLNK, j'ai tiqué un peu pour deux raisons. La première : le signal dure un peu plus que 7 ms, ce qui veut dire que cette routine (piquée d'une démo) va attendre que le signal passe de 1 à 0 puis de 0 à 1. Ça m'ennuie car j'aimerais récupérer ces 7 ms. Deuxième raison : pour détecter le bit 7 à 1, elle fait "si $7F >= (hl) boucler" alors que $80 >= (hl) me semblerait plus approprié ici.
J'ai donc corriger ces deux aspects et je note un effet : si le CNT2 est légèrement supérieur à 312, j'ai toujours un semblant de 50 fps au lieu de 25 fps sans la "correction" de la routine mais on peut voir un tearing lent sur la raquette qui alterne ses couleurs entre chaque frame. A 312, elle est impeccable. Je pense que je vais garder cette "correction" couplée au compteur à 312 pour gagner 7 ms à l'intention du CPU.

Avatar du membre
6502man
Messages : 9965
Enregistré le : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [SHARP MZ-700] BRICK BUSTER

Message par 6502man » 28 mai 2020 21:58

Super ce développement sur MZ-700 :D

C'est déjà pas mal du tout pour la machine :wink:
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.

hlide
Messages : 1432
Enregistré le : 29 nov. 2017 10:23

Re: [SHARP MZ-700] BRICK BUSTER

Message par hlide » 28 mai 2020 22:26

Merci 6502man.

Petit bonus - rien à avoir avec le jeu : on connaissait les dessins de PETscii, voici deux variations version SHARP que j'ai faites pour illustrer une cassette (qui sait pour un loader).
100906633_10223248310864386_3037524867437035520_n.jpg
100906633_10223248310864386_3037524867437035520_n.jpg (16.96 Kio) Vu 9 fois
99425364_10223247493083942_4846114606277459968_n.jpg
99425364_10223247493083942_4846114606277459968_n.jpg (16.97 Kio) Vu 9 fois

Avatar du membre
6502man
Messages : 9965
Enregistré le : 12 avr. 2007 22:46
Localisation : VAR
Contact :

Re: [SHARP MZ-700] BRICK BUSTER

Message par 6502man » 28 mai 2020 22:47

:D

Sympa les K7 en ASCII ART
Phil.

www.6502man.com

To bit or not to bit.
1 or 0.

Répondre