MSX Village forum

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

granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1501

Le 29/03/2010 à 14h48
Je continue donc mon exploration de la galaxie assembleur par la gestion de la souris.



En m'inspirant grandement de mon programme précédent, j'obtiens ce programme, qui pour le moment ne gère pas les détections de bord d'écran. Listing et ROM en pièce jointe !



;****** 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



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

;*** 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],0 ; couleur de bordure transparente



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

;*** 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

ld b,a ; on charge dans b la valeur renvoyée par la routine (valeur du déplacement horizontal)

ld a,[SPRITES+1] ; on charge dans l'accu l'abscisse variable du curseur

add a,b ; on additionne l'abscisse et le déplacement horizontal

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

ld b,a ; cette fois !

ld a,[SPRITES]

add a,b

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



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

;*** Constantes ***

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

ATR_INITIAL:

db 92,124,0,15



SPR_CUR:

db 010h,010h,010h,0eeh,010h,010h,010h,000h



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

;*** Variables ***

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

.page 3



SPRITES:

ds 4






souris.zip


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

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 02/10/2009 à 19h33

Messages: 1883

Le 29/03/2010 à 17h30
Du papier à musique !

Excellent travail, granced ! :top
Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10328

Le 30/03/2010 à 13h26
une solution serait de na pas déplacer le sprite directement avec les coordonnées de la souris

mais de passer par une variable intermédiaire qui elle serait comparée aux valeurs de limitations d'écran comme dans l'exemple avec le clavier

enfin ce n'est qu'une suggestion a toi de voir


:noel
Site web    
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1501

Le 30/03/2010 à 13h58
Je vais tester cette méthode. :top


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1501

Le 30/03/2010 à 14h29
Ca marche... presque ! En fait, on dirait que lorsque le mouvement de la souris est trop rapide, le test des bords n'est pas fait... Je me demande s'il ne faut pas que je fasse un test de signe sur le déplacement :gne


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

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 02/10/2009 à 19h33

Messages: 1883

Le 30/03/2010 à 16h58
D'après ce que je lis, tu boucles le programme sans vérifier les coordonnées du pointeur par rapport à sa position précédente granced. C'est normal ?
Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10328

Le 30/03/2010 à 18h32
il faut simuler un > ou < car si tu ne passe pas par la coordonnée pile exacte avec la souris le calcul est faussé


:noel
Site web    
Franck Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 22h54

Messages: 3295

Le 30/03/2010 à 21h13
C'est extrêmement bien expliqué en tout cas ! :|
   
Riton Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 11/10/2009 à 21h47

Messages: 164

Le 31/03/2010 à 08h12
:hum :| Mais bon sang, mais c'est bien sur :heink

En tous cas félicitation mais trop technique pour moi


riton
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1501

Le 31/03/2010 à 08h32
Walter :
D'après ce que je lis, tu boucles le programme sans vérifier les coordonnées du pointeur par rapport à sa position précédente granced. C'est normal ?




Non non, tu n'as pas rêvé, je ne fais pas de test de ce genre, du moins pas dans le listing ci-présent. Je me creuse la tête pour trouver une solution pour la gestion des bords mais c'est un peu le casse-tête !



En fait ce qui est renvoyé par la routine NEWPAD, c'est le déplacement relatif de la souris (donc un entier signé !). Je me demande s'il ne faut pas que je regarde à ça.



Jipe :
il faut simuler un > ou < car si tu ne passe pas par la coordonnée pile exacte avec la souris le calcul est faussé




J'ai fait des essais dans ce but, mais pour l'instant sans résultat probant (utilisation de C lors du CP : si l'accu A est a une certaine valeur, un CP op réalise A-op. Si A-op>=0, C=0, si A-op<0, C=1). Je fais des essais aussi avec P et M pour le signe


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 775

Le 31/03/2010 à 12h15
La tache est ardue :|



Pour vérifier si un entier signé est négatif il faut vérifier s'il est supérieur à 128 (10000000 en binaire) en vérifiant le bit 7 (le premier en partant de la gauche, les bits étant numérotés de0 à 7 de droite à gauche :s ). Un bit 7,b renvoie 1 dans Z s'il est supérieur à 128 (1000000, 10000001, 10000010... 11111111).



Pour vérifier si a dépasse une certaine valeur (dans mon exemple 240(11110000)) je fais and 240[ , le a and 240 ne renverra 240 que si a est supérieur ou égal à 240.

voir AND

exemples:

1111 1110 AND

1111 0000

1111 0000



0111 1111 AND

1111 0000

0111 0000




Après il suffit de comparer a à 240 pour savoir si la précédente valeur en abscisse de la souris est supérieure ou égale à 240.



Je n'est testé que sur émulateur et un mouvement brusque de la souris crée un bug.



Je me creuse la tête pour les "inférieur à" mais ça me parait plus compliqué... :moue



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

;*** 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



ld b,a ; on charge dans b la valeur renvoyée par la routine (valeur du déplacement horizontal)

ld a,[SPRITES+1]; on charge dans l'accu l'abscisse variable du curseur

push af ;sauvegarde de a

and 240 ;on met a à 240 si supérieur

cp a,240 ;on compare si a=240

jr nz,suiteh ;sinon mvt normal

bit 7,b ;on vérifie si le mouvement de la souris est négatif

;bit7 de b à 1 implique que b>=128 donc z=1 indique que b est négatif

jr z,finh ;abandon si positif



suiteh:

pop af ;récupération de a

add a,b ; on additionne l'abscisse et le déplacement horizontal

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



finh:

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

ld b,a ; cette fois !

ld a,[SPRITES]

add a,b

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




souris.zip


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: 1501

Le 31/03/2010 à 12h34
Oui j'ai eu le même souci... :gne

Lorsque la valeur du déplacement est trop importante, le test de détection des bords échoue...

L'adaptation du programme en Basic ne pose quant à elle pas ce genre de problème... Trop rapide l'assembleur ?

En y réfléchissant, je me dis qu'il y a forcément une autre méthode : si le déplacement est trop important, alors il faut le limiter à la différence entre le bord à traiter et la position du curseur. Je détaille un peu mon raisonnement, (pour le bord gauche pour un déplacement horizontal) vers la gauche avant de le tenter en prog :

Imaginons que mon curseur soit en position (10,Y). Je mets un grand coup de souris à gauche, mon déplacement est de -127, ça va foirer. Par contre si je vois que le déplacement est inférieur à 0-coordonnée X (ici -10 donc), je le limite à -10. Ca va me forcer à effectuer aussi un test en fonction de la coordonnée X de mon curseur, cette méthode n'étant valable à mon avis que lorsque le curseur est entre 0 et 127 en abscisse. Pfff, que c'est compliqué !!! :moue


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

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 02/10/2009 à 19h33

Messages: 1883

Le 31/03/2010 à 19h37
C'est pour cela que je parlais de vérifier les coordonnées.

Est-il possible de définir un "pas" de déplacement pour ta souris granced, et ainsi controler sa vitesse et peut-être bloquer les abscisses et ordonnées ?



Si cela peut t'inspirer, en MSX-Basic, je procède ainsi :



Selon le mode écran utilisé, Il suffit de changer les valeur MAX SX en ligne 150 et SY en ligne 170.



granced :
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


Es-tu obligé d'initialiser le port à chaque boucle ? :hum
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1501

Le 01/04/2010 à 08h46
En Basic c'est plus facile je pense parce que les tests des valeurs prennent bien en compte que ce sont des entiers signés (le déplacement maximal est de + ou -127, en assembleur ce n'est pas aussi facile j'ai l'impression... Il doit y avoir un truc à faire avec un des bits du registre F (le bit P/V).

Le déplacement est codé sur un octet allant de 0h à FFh, sachant que de 0h à 7Fh ce sont les déplacements positifs (vers la droite ou vers le bas), et de 80h à FFh les déplacements négatifs (vers la gauche et vers le haut). Si on prend une des coordonnées et qu'on l'ajoute à ce déplacement, les tests sont faussés (imaginons que je sois à l'abscisse 200 et que je fasse un déplacement de 127 vers la droite, et que ma borne maximale est de 240 : en hexa j'ai C8h + 7Fh, j'obtiens 47h (avec une retenue), ma borne maximale est F0h. Mon test pour le bord droit est de rejeter toute coordonnée supérieure à F0h, or 47h est bien inférieur à F0h : test foiré... :gne


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 775

Le 01/04/2010 à 09h26
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
   
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie