MSX Village forum

La Place des Développeurs Assembleur et gestion de la souris

MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 774

Le 01/04/2010 à 09h26

Reprise du message précédent

En basic c'est plus facile car on utilise une variable (entière) limitée de -32768 à +32767, contrairement à notre pauvre accumulateur qui lui "s'étend" de -127 à 128 (0-255) en fait on est comme sur un cylindre (dans les deux sens x et y ) autant l'empêcher de rouler, c'est quasi injouable.

Il faudrait jouer sur un double registre avant l'affichage pour que ce soit jouable. Petit rappel un call DCOMPR (0020 h) permet de comparer HL et DE et renvoie 1 dans Z siHL=DE et 1 dans carry si HL<DE. C'est une piste à explorer je pense!

SOS: Quelqu'un a des nouvelles de Metalion :lol


Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 01/04/2010 à 09h38
Ca peut être aussi une piste à explorer. Il faudrait faire des essais (encore et toujours :p) !

C'est vrai que Metalion pourrait peut-être éclairer notre lanterne pour le coup !


MSX un jour, MSX toujours ! :D
Site web    
BibiZen Membre non connecté

Maire-adjoint

Rang

Avatar

Inscrit le : 03/10/2009 à 18h34

Messages: 1455

Le 01/04/2010 à 13h36
Il y a un exemple de programmation souris chez retro8bits (à traduire avec google)

Les fichiers (mouse.asc & mouse.bin) se trouvent dans Sunrise Special #1 Sunrise The Netherlands 1992

[EDIT: liens morts corrigés]
E-mail    
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 01/04/2010 à 13h47
Argh, c'est du dur là, ils passent par les ports du PSG et les registres ! Encore plus compliqué en fait pour les débutants que nous sommes :|


MSX un jour, MSX toujours ! :D
Site web    
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 01/04/2010 à 15h36
Ca y est j'ai trouvé comment faire !!!! :D






























Non... Poisson d'avril :oups


MSX un jour, MSX toujours ! :D
Site web    
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 774

Le 01/04/2010 à 22h32
Zebibizen :
Il y a un exemple de programmation souris chez retro8bits (à traduire avec google)



Les fichiers (mouse.asc & mouse.bin) se trouvent dans Sunrise Special #1 Sunrise The Netherlands 1992




Merci Zebibizen, grace à ça j'ai trouvé.



granced :
Argh, c'est du dur là, ils passent par les ports du PSG et les registres ! Encore plus compliqué en fait pour les débutants que nous sommes :|




Mais non Granced il faut occulter cette partie du programme qui ne gère que le son!



Bon, j'ai réussi à intégrer la méthode au programme et la commenter mais je ne comprends toujours pas. des trucs semblent fonctionner à l'envers et pourtant ça marche! :s



;****** Deplacement avec souris en SCREEN 5 ******



;-------------------------------------------------

;*** Directives d'assemblage spécifique AsMSX ***



.bios

.page 2

.rom

.start DEBUT



;---------------------------------------

;*** Adresses des tables du SCREEN 5 ***



NAMTBL equ 0000h

SPRTBL equ 7800h

SPRATR equ 7600h



MIN_X EQU 10 ; Valeurs maxi et mini

MAX_X EQU 255-10

MIN_Y EQU 10

MAX_Y EQU 211-10



;--------------------------

;*** Début du programme ***



DEBUT:

call DISSCR ; on coupe l'affichage

ld hl,0f3e9h ; on récupère l'adresse de la couleur d'écriture dans hl (zone de communication)

ld [hl],15 ; couleur d'écriture en blanc

inc hl ; on récupère l'adresse de la couleur de fond

ld [hl],0 ; couleur de fond transparente

inc hl ; on récupère l'adresse de la couleur de bordure

ld [hl],5 ; couleur de bordure bleue



;---------------------------

;*** Passage en SCREEN 5 ***



ld a,5 ; on met le numéro de SCREEN choisi dans l'accumulateur

call CHGMOD ; appel de la routine BIOS CHGMOD



;-----------

;*** CLS ***



ld hl,NAMTBL ; on met l'adresse de la table des noms dans hl

ld bc,27136 ; on met la longueur en octets de la table des noms (ici 27136) dans

; le registre double bc

xor a ; on annule la valeur de l'accumulateur

call FILVRM ; appel de la routine FILVRM (on remplit la VRAM à partir de l'adresse contenue par hl,

; sur une longueur d'octets contenue par bc, avec la valeur contenue par l'accumulateur

; ici 0, on remplit donc toute la table des noms par rien : on efface l'écran !



;----------------------------

;*** Définition du sprite ***



ld hl,SPR_CUR ; on met dans hl l'adresse des données qui constituent notre sprite

ld de,SPRTBL ; on met dans de l'adresse de destination

ld bc,8 ; on met dans bc la longueur en octets des données à transférer

call LDIRVM ; on appelle la routine BIOS LDIRVM, qui va copier les données indiquées dans la VRAM



;---------------------------------------------------

;*** Définition des attributs de sprite initiaux ***



ld hl,ATR_INITIAL ; on met hl à l'adresse de départ des attributs initiaux du sprite

ld de,SPRITES ; le registre de est mis à l'adresse de la zone variable

ld bc,4 ; le registre bc contient le nombre d'octets à transférer

ldir ; on copie bc (ici 4) octets depuis hl (ATR_INITIAL) vers de (SPRITES)



;---------------------------------

;*** Activation de l'affichage ***



call ENASCR ; on active l'affichage



;-------------------------

;*** Boucle principale ***



LOOP: ; Label de la boucle principale

ld a,12 ; on charge 12 dans l'accumulateur : c'est la valeur qui permet d'initialiser la souris

; dans le port joystick n°1

ld ix,01adh ; on fait appelle à une routine (NEWPAD) de la Sub-ROM MSX2, on charge donc l'adresse

; de cette routine dans ix

call 015fh ; appel de la Sub-Rom MSX2 (en 015fh)



ld a,13 ; on charge 13 dans l'accumulateur : c'est la valeur qui va permettre de gérer le

; déplacement horizontal de la souris

ld ix,01adh ; voir au-dessus

call 015fh ; idem

call XBORDR ; appel du sous programme de gestion des déplacements horizontaux

ld[SPRITES+1],a ; on remet dans l'adresse de la variable le résultat



ld a,14 ; toute cette partie est la même que la précédente

ld ix,01adh ; à ceci près que c'est la composante verticale qui

call 015fh ; est traitée

call YBORDR ; cette fois !

ld[SPRITES],a



call DUMP ; appel à la sous-routine DUMP (qui permet de transférer les valeurs en RAM vers la VRAM)

jp LOOP ; on boucle le programme



;------------------------------------------------

;*** Sous programme de transfert vers la VRAM ***



DUMP: ; label du sous-programme

halt ; synchronisation verticale

ld hl,SPRITES ; adresse de départ

ld de,SPRATR ; adresse d'arrivée

ld bc,4 ; longueur du bloc à transférer (en octets)

call LDIRVM ; appel à la routine BIOS LDIRVM

ret



;------------------------------------------------

;*** Sous programme du déplacement horizontal ***



XBORDR:

BIT 7,A ; vérification du signe du déplacement

JR Z,XBO_S1 ; si
positif saut au sous prog de gestion deplacement MAX

NEG ; Complément à 2 de la valeur de A (A=-A)

LD B,A ; sauvegarde de A dans B

LD A,[SPRITES+1] ; récup du X initial du sprite dans A

SUB B ; On soustrait la valeur inversée du déplacement à A

JR C,XBO_S2 ; Si dépassement saut à valeur mini

CP MIN_X ; comparaison à la valeur mini

RET NC ; retour boucle principale si pas dépassement.

XBO_S2:

LD A,MIN_X ; mise de A à la valeur mini.

RET ; retour boucle principale

XBO_S1:

ld HL,SPRITES+1 ; HL= valeur X du sprite

ADD A,[HL] ; ajout du déplacement au X du sprite

JR C,XBO_S3 ; Si dépassement saut à valeur max

CP MAX_X ; comparaison à valeur max

RET C ; retour boucle principale si dépassement

XBO_S3:

LD A,MAX_X ; A à valeur max

RET ; retour boucle principale



;------------------------------------------------

;*** Sous programme du déplacement vertical ***



YBORDR:

BIT 7,A ; Idem XBORDR, mais pour Y

JP Z,YBO_S1

NEG

LD B,A

LD A,[SPRITES]

SUB B

JR C,YBO_S2

CP MIN_Y

RET NC

YBO_S2:

LD A,MIN_Y

RET

YBO_S1:

ld HL,SPRITES

ADD A,[HL]

CP MAX_Y

RET C

LD A,MAX_Y

RET




;------------------

;*** Constantes ***



ATR_INITIAL:

db 92,124,0,15



SPR_CUR:

db 000h,038h,05dh,0ffh,07dh,038h,000h,000h



;-----------------

;*** Variables ***

.page 3



SPRITES:

ds 4



Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 02/04/2010 à 08h10
Alors là je te tire mon chapeau bien bas ! :top

Je m'en vais maintenant décortiquer tout ça pour saisir le principe.

Merci l'Osaure !! ;)

EDIT:

Après quelques tests "à la main", je constate comme toi qu'il y a des choses qui marchent un peu à l'envers, j'ai un peu de mal à saisir le comportement du Z80 pour le coup : je vais détailler un peu ce qui me gêne, en essayant de soumettre une explication un tant soit peu logique.

Pour mon essai, j'ai pris une coordonnée X=50 (00110010) et un déplacement de -10 (11110110). J'applique la routine XBORDR :

BIT 7,A : j'ai 11110110 dans A, le bit 7 est à 1, l'indicateur Z prend donc sa valeur opposée, soit 0.
JR Z,XBO_S1 : pas ici, vu que j'ai NZ (Z=0), je continue donc dans la routine sans effectuer le saut
NEG : -10 devient 10, donc 00001010
LD B,A : B reçoit la valeur 10
LD A,[SPRITES+1] : A reçoit la valeur 50 (00110010)
SUB B : je retire la valeur de B à celle de A. C'est là que le bât blesse, car une soustraction en principe c'est l'addition de l'opposé !! Je dois donc additionner 00110010 et 11110110, et je trouve (1)00101000. J'ai donc l'indicateur C qui doit être à 1, ce qui devrait fausser le test suivant. En regardant la description de SUB, je vois qu'il est dit qu'il n'est pas nécessaire de se préoccuper du carry, mais AVANT l'opération, c'est ce qui me dérange un peu pour le coup, car le résultat en génère un... La seule option possible est d'après moi que le fait qu'en repassant à son opposé lors du SUB, on a (1)11110110, qui pour le coup annule bien le carry et permet le passage du test suivant.

Je continue (comme si de rien n'était :p ).
JR C,XBO_S2 : en partant du raisonnement précédent le carry n'est pas positionné, donc pas de saut : on continue
CP MIN_X : je compare (0)00101000 à 10 (0)00001010 (j'ôte de la valeur de l'accu la valeur à laquelle je le compare) : j'ai donc (0)00101000 + (1)11110110, ce qui me donne le résultat de (0)00011110 : C est à 0.
RET NC : NC signifie C=0, c'est ce que j'ai : je retourne au programme principal, et j'affiche le sprite avec les coordonnées contenues dans A.


MSX un jour, MSX toujours ! :D
Site web    
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 774

Le 02/04/2010 à 18h42
J'ai corrigé mon erreur (en rouge) du post précédent. Quand le bit7 est à 1, Z est à 0 et vice-versa, j'avais noté l'inverse.

Pour le PSG en fait tu avais raison il faut passer par le PSG pour la gestion des ports manettes (et donc souris) mais dans ton programme NEWPAD en SUB-ROM le fait pour nous ;)

Par contre pour la suite je cale moi aussi!


Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 06/04/2010 à 11h17
Variations sur le même thème : j'ai enrichi le programme initial par quelques nouvelles routines, qui vont gérer les passages à des endroits précis et le clic sur le bouton gauche de la souris.



La première partie se trouve dans la boucle principale et consiste à traiter le sprite s'il est compris entre les coordonnées (128,100) et (200,150) : si c'est le cas, je modifie la couleur du sprite en rouge.



La deuxième partie (BLOC 2) permettra de tester la présence du sprite dans le carré (50,50)-(100,100). S'il est dedans, sa forme sera modifiée.



Enfin (à partir de BOUTON), je teste si le bouton est enfoncé. Si oui, j'aurais un point de couleur blanche affiché au point indiqué par le curseur.



Pour réaliser tout ça, j'aurai besoin de nouvelles constantes, et aussi de nouvelles sous-routines que je vais détailler par la suite.



Voici déjà la modification de la boucle principale (je place tout ceci juste avant l'appel à la sous-routine DUMP) :



ld a,[SPRITES+1] ; je stocke dans l'accu l'abscisse du sprite

cp 128 ; je le compare à 128

jr nc,@@TEST1 ; si c'est plus grand, je saute à TEST1

ld a,15 ; sinon, je place la valeur de couleur normale dans l'accu...

call COUL_SPR ; ...et j'appelle la sous-routine COUL_SPR

jr BLOC2 ; je saute ensuite à l'autre test

@@TEST1:

cp 200 ; je compare l'abscisse à 200

jr c,@@TEST2 ; si c'est plus petit, je saute à TEST2

ld a,15 ; sinon même traitement qu'au-dessus

call COUL_SPR

jr BLOC2

@@TEST2:

ld a,[SPRITES] ; je charge cette fois l'ordonnée dans l'accu

cp 100 ; je la compare à 100

jr nc,@@TEST3 ; si c'est plus grand, je saute à TEST3

ld a,15 ; sinon, je remets la couleur 15, bla bla bla...

call COUL_SPR

jr BLOC2

@@TEST3:

cp 150 ; je compare maintenant l'ordonnée à 150

jr c,@@TEST4 ; si c'est plus petit je saute à TEST4

ld a,15 ; sinon, comme d'habitude.

call COUL_SPR

jr BLOC2

@@TEST4:

ld a,8 ; toutes les conditions sont requises pour être dans ma zone

call COUL_SPR ; je charge la couleur rouge (8) dans l'accu et j'appelle ma sous-routine



BLOC2:

ld a,[SPRITES+1] ; même principe que précédemment...

cp 50

jr nc,@@TEST1

ld hl,SPR_CUR ; ... sauf qu'ici je charge l'adresse du patron de sprite normal

call CHG_SPR ; et j'appelle une routine pour le définir

jr BOUTON ; saut au test suivant

@@TEST1: ; je vous passe les commentaires de cette partie

cp 100 ; c'est le même principe qu'auparavant...

jr c,@@TEST2

ld hl,SPR_CUR

call CHG_SPR

jr BOUTON

@@TEST2:

ld a,[SPRITES]

cp 50

jr nc,@@TEST3

ld hl,SPR_CUR

call CHG_SPR

jr BOUTON

@@TEST3:

cp 100

jr c,@@TEST4

ld hl,SPR_CUR

call CHG_SPR

jr BOUTON

@@TEST4: ; ici par contre les tests m'amènent ici si je suis dans la zone à traiter

ld hl,SPR_ALT ; je charge dans HL l'adresse du patron "altéré"

call CHG_SPR ; et j'appelle la sous-routine qui va modifier l'aspect de mon sprite



BOUTON:

ld a,1 ; ma souris est dans le port manette 1 : je charge 1 dans l'accu

call GTTRIG ; appel à la routine BIOS GTTRIG (elle renvoie 0ffh dans l'accu si le bouton est pressé)

cp 0ffh ; je compare à 0ffh pour savoir si le bouton est effectivement pressé

call z,AFF_POINT ; si oui, j'appelle la sous-routine AFF_POINT


MSX un jour, MSX toujours ! :D
Site web    
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 06/04/2010 à 11h41
Détaillons à présent les sous-routines nécessaires :



COUL_SPR:

ld hl,SPRCOL

ld bc,8

call FILVRM

ret




C'est un mode de fonctionnement déjà rencontré auparavant pour le CLS par exemple. Sauf qu'ici je prends pour charger hl SPRCOL. Qu'est-ce donc ? Eh bien c'est une valeur que je devrai déclarer avec mes tables relatives au SCREEN 5 : c'est l'adresse de la table des couleurs de sprites, qui commence en 7400h. Donc au début de mon programme, je devrai placer un SPRCOL equ 7400h.

Je remplis les 8 lignes de couleur par la couleur choisie dans A avant l'appel à la routine !





CHG_SPR:

ld de,SPRTBL

ld bc,8

call LDIRVM

ret




Pour changer la forme de mon sprite, il me suffit de modifier son patron ! Avec l'adresse de départ des données de patrons, il ne me reste plus qu'à indiquer la destination dans DE, le nombre d'octets à transférer dans BC et d'utiliser LDIRVM et le tour est joué !!

D'ailleurs, penser à insérer (après la définition du patron initial par exemple) la définition du patron altéré :

SPR_ALT:

db 081h,042h,03ch,024h,024h,03ch,042h,081h



AFF_POINT:

ld b,0

ld d,0

ld a,[SPRITES+1]

inc a

inc a

inc a

ld c,a

ld a,[SPRITES]

inc a

inc a

inc a

ld e,a

ld a,15

call SETATR

call PSET

ret




Pour cette sous-routine, un traitement un peu particulier. Je commence par annuler b et d, car je vais faire appel à une routine du BIOS (PSET) qui a besoin des coordonnées mises dans des registres doubles. Je récupère la valeur de l'abscisse, je l'incrémente 3 fois pour arriver au niveau du centre du curseur, et je mets dans le registre c la valeur obtenue. Le registre double BC contient donc l'abscisse.

Je fais de même pour l'ordonnée (j'incrémente 4 fois par contre pour arriver au centre du curseur), qui sera stockée dans DE.

Ensuite, je charge dans l'accu la valeur 15 : c'est la couleur que je souhaite affecter à l'affichage d'un point. Je confirme ce choix en appelant la routine BIOS SETATR, nécessaire au fonctionnement de la routine suivante. J'appelle ensuite PSET (en n'ayant pas oublié de le définir dans la série de "equ" de début de programme : PSET equ 57f5h, car curieusement asMSX ne le reconnaît pas comme les autres routines).



Voici les fichiers : souris2.zip


MSX un jour, MSX toujours ! :D
Site web    
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 774

Le 08/04/2010 à 17h08
granced :




Pour changer la forme de mon sprite, il me suffit de modifier son patron ! Avec l'adresse de départ des données de patrons, il ne me reste plus qu'à indiquer la destination dans DE, le nombre d'octets à transférer dans BC et d'utiliser LDIRVM et le tour est joué !!

D'ailleurs, penser à insérer (après la définition du patron initial par exemple) la définition du patron altéré :

SPR_ALT:

db 081h,042h,03ch,024h,024h,03ch,042h,081h



AFF_POINT:

ld b,0

ld d,0

ld a,[SPRITES+1]

inc a

inc a

inc a

ld c,a

ld a,[SPRITES]

inc a

inc a

inc a

ld e,a

ld a,15

call SETATR

call PSET

ret








Ne serait-il pas plus judicieux de définir tous les sprites à l'avance (comme en basic dans le programme que j'avais fait dans "Déplacement d'un sprite en assembleur" puis de changer juste le N° dans la TAS par la suite :hum


Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 09/04/2010 à 07h56
Plus judicieux je ne sais pas, plus pratique sans doute dans le contexte de ces exemples. Disons que je me suis inspiré d ece que j'ai pu voir du comportement de la TGS sous Meisei pour les jeux Konami. Ce que je fais doit être plus pratique dans le cas où on a un grand nombre de sprites (plus de 64) dans la TGS.
Enfin bon, cause différente, effets similaires :D


MSX un jour, MSX toujours ! :D
Site web    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie