La Place des Développeurs Assembleur et gestion de la souris
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
Le MSXien le plus à l'ouest ... ou presque
Ca peut être aussi une piste à explorer. Il faudrait faire des essais (encore et toujours ) !
C'est vrai que Metalion pourrait peut-être éclairer notre lanterne pour le coup !
C'est vrai que Metalion pourrait peut-être éclairer notre lanterne pour le coup !
MSX un jour, MSX toujours !
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]
Les fichiers (mouse.asc & mouse.bin) se trouvent dans Sunrise Special #1 Sunrise The Netherlands 1992
[EDIT: liens morts corrigés]
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
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!
;****** 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
;-------------------------------------------------
;*** 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 ... ou presque
Alors là je te tire mon chapeau bien bas !
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 ).
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.
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 ).
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 !
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!
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 ... ou presque
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) :
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
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étaillons à présent les sous-routines nécessaires :
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 !
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
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
COUL_SPR:
ld hl,SPRCOL
ld bc,8
call FILVRM
ret
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
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
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 !
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
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
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
Le MSXien le plus à l'ouest ... ou presque
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
Enfin bon, cause différente, effets similaires
MSX un jour, MSX toujours !
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie