MSX Village forum

La Place des Développeurs Déplacement d'un sprite en assembleur ... ou le résultat de mes derniers travaux

granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 25/03/2010 à 10h09
Comme vous le savez, je passe pas mal de temps à faire des tests et des recherches en assembleur.
Je me suis dit qu'il pourrait être bien en l'absence (provisoire ? :D) de tutoriel Z80 pour MSX de vous faire partager mes recherches, quitte à ce que les membres les plus éminents de notre communauté améliorent ce que je propose. Pour le code, j'utiliserai la syntaxe d'AsMSX, qui est assez facile à mettre en oeuvre (et surtout ça m'évite de coder un header pour les roms :D).

Ici donc, je suis parti de la problématique suivante : déplacement d'un sprite avec le clavier, avec tests des bords de l'écran et modification de sa forme suivant la direction prise.

Pour les néophytes en Z80, il faut vous expliquer que toutes les jolies fonctions et instructions du MSX-Basic telles que PUTSPRITE ou SCREEN n'existent pas en tant que tel, et il faut tout se repalucher pour arriver à quelque chose de concret et d'à peu près correct ! Heureusement, il y a Findus les routines du BIOS qui vont énormément nous aider. Les puristes râleront peut-être à cause du manque de rapidité, mais pour mon exemple, c'est plus que suffisant !

Passons maintenant à l'analyse du problème :

Dans la VRAM, un sprite est caractérisé par ses attributs, qui sont ses coordonnées, son numéro de patron (j'y reviendrai plus tard) et sa couleur. Toutes ces informations sont rangées dans une partie de la VRAM appelée table des attributs de sprites. Suivant le mode d'affichage utilisé, l'adresse de cette table change, pour ça je vous invite à regarder toute la documentation dans les divers ouvrages de la bibliothèque du village. J'ai opté pour un affichage en SCREEN 2, je consulte donc mon « Pratique du MSX2 » et hop miracle je trouve mes adresses des différentes tables dans la VRAM :
- Table des noms : 01800H
- Table des couleurs : 02000H
- Table des formes ou patrons : 00000H
- Table des attributs de sprites : 01B00H
- Table des formes ou patrons de sprites : 03800H
- Table de palette (sur MSX2) : 02020H

Je vous fais un topo rapide sur les différentes tables :
La table des noms est comme une matrice de 32 colonnes sur 24 lignes, dont chaque case contient un octet (entre 0 et 255, ou 0h et Ffh pour faire vrai :p ). Cet octet correspond à une forme bien particulière, qui est elle définie sur la table des formes ou patrons. Je ne m'étends pas sur le sujet de la division en 3 parties égales de cette table, ce n'est pas l'objet ici. La table des attributs de sprites contient 128 octets, soit des informations pour 32 sprites de taille normale en 8*8, ça tombe bien vu qu'on a 32 plans de sprites, comme quoi sur MSX tout est bien pensé !
Dans l'ordre, c'est l'ordonnée, l'abscisse (révisez vos cours de maths si vous avez oublié à quoi ça correspond :p), le numéro de forme et la couleur. Le numéro de forme correspond, à l'instar de ce qui se fait pour la table des noms, à une forme définie dans la table des formes de sprites.

Pour mon exemple, les tables qui m'intéressent sont la table des noms, pour le fond d'écran (que je vais remplir de... vide), la table des patrons de sprites pour y dessiner les formes, et la table des attributs de sprite.

Et maintenant, codons tout ça !

Première étape : préparation des données et variables, directives d'assemblage spécifiques

Pour réaliser mon exemple, je vais prendre le sprite du Metalion (pour les incultes, le vaisseau de Nemesis 2, pas notre concitoyen du village :lol ). Il a 3 formes distinctes : une que je qualifierai de normale, une lorsqu'il se déplace vers le haut, une lorsqu'il se déplace vers le bas. En passant, ce ne sera pas un sprite seul, vu qu'il a 2 couleurs pour chaque forme ! En tout j'aurai donc 6 sprites de 16*16 pixels à coder.



Je vais utiliser des labels pour chaque série de données :
SPR_NEM pour la définition de la position "normale", SPR_UP pour la position vers le haut, SPR_DOWN pour la position vers le bas.
Pour chacun de ces labels, une série de 64 octets, les 32 premiers codant le sprite blanc, les 32 suivant le sprite de couleur bleue ou rouge.

On aura donc ceci à placer dans notre code :

SPR_NEM:
db 000h,080h,0e0h,070h,07fh,07fh,0bfh,0bfh,0bfh,078h,0e0h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,088h,0ffh,0f8h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,0c0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h

SPR_UP:
db 000h,080h,0e0h,070h,0ffh,01fh,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,080h,0f0h,0ffh,000h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,0e0h,0feh,07fh,03fh,01eh,018h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,000h,000h,0fch,0f0h,000h,000h,000h,000h,000h,000h,000h

SPR_DOWN:
db 000h,000h,0b0h,0fch,07fh,07fh,0bfh,0bfh,0bfh,07fh,078h,0e0h,000h,000h,000h,000h
db 000h,000h,000h,000h,080h,018h,08fh,0fch,0e0h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
db 000h,000h,000h,000h,000h,0e0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h

Les labels servent à appeler une adresse, sans avoir à l'entrer manuellement, ce qui est plus qu'utile dans un code long pour se repérer !

Ensuite, il me faut les attributs de sprite initiaux. On va placer le vaisseau au centre de l'écran, avec le sprite de forme normale (le premier blanc, le deuxième rouge). Je crée donc un nouveau label comme suit :

ATR_INITIAL:
db 88,120,0,15
db 88,120,4,8

Il me faut maintenant penser à ce qui est variable, donc me réserver de l'espace en dehors du code pour les données qui sont amenées à changer. Ce qui est amené à être modifié, ce sont les attributs de sprites. 4 octets pour chaque sprite, donc 8 octets à réserver. Je les positionne à partir de l'adresse 0C00H (codée en .page3 par AsMSX), grâce à ds qui permet de réserver un nombre d'octets. Evidemment, pour me repérer plus facilement, j'y mets aussi un label (ici SPRITES). Voici la portion de code correspondante :

.page 3
SPRITES:
ds 8

Il ne me reste plus qu'à indiquer quelques bricoles à AsMSX pour qu'il me compile mon programme bien comme il faut (attention, cette syntaxe est je le répète spécifique à AsMSX) :

Voici le code :

.bios
.page 2
.rom
.start DEBUT

La première ligne indique au compilateur que je vais utiliser les routines du BIOS.

La deuxième que mon code d'assemblage commence en page 2, soit en 08000H.

La troisième ligne indique que le programme sera compilé sous forme de ROM (vous pourrez le lancer via le port cartouche de votre émulateur préféré).

Enfin, la quatrième ligne indique l'adresse à partir de laquelle le programme sera exécuté (remplacée ici par un label, une fois de plus).

Suite au prochain numéro !


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 22h54

Messages: 3280

Le 25/03/2010 à 10h31
Très intéressant tout ça, même si cela vole un peu trop haut pour moi :lol
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 25/03/2010 à 10h51
Deuxième étape : préparation de l'écran

Il nous faut passer en SCREEN 2, indiquer qu'on utilise des sprites en 16*16, passer en COLOR 15,0,0 et enfin effacer l'écran !

Mais avant de commencer, et pour éviter des manipulations fastidieuses pour les adresses des différentes tables qui nous intéressent, on va utiliser quelques EQU !

Code ASM :
NAMTBL equ 1800h 
SPRTBL equ 3800h
SPRATR equ 1b00h
 

NAMTBL pour la table des noms, SPRTBL pour la table des sprites, SPRATR pour la table des attributs de sprites. Ainsi, quand j'aurais besoin de ces tables dans mon code, j'utiliserai les noms au lieu des adresses !

Maintenant passons dans le vif du sujet !

Voici la portion de code qui va faire tout ce qu'il faut, je la détaillerai après :

Code ASM :
DEBUT:
call DISSCR
ld hl,0f3e9h
ld [hl],15
inc hl
ld [hl],0
inc hl
ld [hl],0
call INIGRP
ld bc,06201h
call WRTVDP
ld hl,NAMTBL
ld bc,768
xor a
call FILVRM


- DEBUT: c'est le label qui indique où mon programme va commencer, rien de bien méchant là-dedans.

- call DISSCR : premier appel à une routine BIOS ! Celle-ci a comme effet d'empêcher l'affichage pendant que je bidouille la VRAM !

- ld hl,0f3e9h : j'utilise une des adresses de la zone de communication : celle qui contient la couleur d'écriture ! Je charge cette adresse dans l'accumulateur 16 bits.

- ld [hl],15 : je place la valeur 15 à cette adresse, la couleur d'écriture passe donc au blanc.

- inc hl
ld [hl],0
inc hl
ld [hl],0 : j'incrémente la valeur de l'accumulateur, ce qui me permet de passer à la couleur de fond (que je mets à 0) en utilisant la même méthode que précédemment. J'enchaîne aussi sur la couleur de bordure.

- call INIGRP : nouvelle routine BIOS, qui me permet de passer immédiatement en SCREEN 2.

- ld bc,06201h
call WRTVDP : j'utilise la routine WRTVDP qui me permet d'écrire une valeur dans un registre du VDP. Cette routine nécessite d'utiliser 2 registres du Z80 : b qui doit contenir la donnée à écrire, et c le numéro du registre à modifier. Pour passer à des sprites en 16*16, je dois modifier le registre 1 du VDP, c prendra donc comme valeur 1. Le registre b du Z80 sera quant à lui mis à la valeur e2h (ou 01100010 en binaire, ce qui va nous permettre entre autres de mettre les sprites en 16*16)

- ld hl,NAMTBL
ld bc,768
xor a
call FILVRM : Appel à la routine FILVRM, qui remplit la VRAM sur une longueur d'octets donnée par le double registre bc (ici 768, la longueur de la table des noms) avec la donnée contenue dans l'accumulateur a. Comme j'utilise un xor a, j'annule la valeur de l'accumulateur. En conclusion, je mets rien dans les 768 cases de la table des noms, donc j'efface l'écran !

Je fais ensuite une petite manipulation qui me sera fort utile pour le reste du code : je copie le contenu des attributs de sprites initiaux dans la partie "variable" de mon code :

ld hl,ATR_INITIAL
ld de,SPRITES
ld bc,8
ldir

La première ligne, met dans le registre double hl l'adresse de départ.
La deuxième met dans le registre de l'adresse d'arrivée (c'est là qu'on voit toute l'utilité des labels ;) ).
La troisième met dans le registre double bc le nombre d'octets.
La dernière fait appel à l'instruction ldir, qui permet la copie d'un bloc de RAM vers une adresse.

Enfin, je peux réactiver l'affichage, avant d'attaquer le fond du problème : le déplacement !

call ENASCR (routine BIOS qui annule le call DISSCR du début).


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 25/03/2010 à 13h11
3ème étape : le programme

En analysant ce que j'avais à faire, j'ai pu déterminer mon programme :

1) Préparation des attributs et formes initiaux des sprites
2) lecture du clavier : en fonction de la ou des touches enfoncées, partir vers un sous-programme qui gère le déplacement dans la direction voulue, en modifiant la forme au besoin et en testant les bords d'écran.
3) affichage du sprite ainsi modifié
4) retour au 1)

C'est bien entendu la partie 2 qui sera la plus délicate à traiter !!

Je commencerai donc par le commencement : la préparation des attributs et formes initiaux des sprites :

Code ASM :
LOOP:
ld hl,SPR_NEM
call CHOIX_SPRITE
ld a,8
ld [SPRITES+7],a


Comme vous l'aurez remarqué, je commence par un nouveau label LOOP. Celui-ci me sert d'indicateur pour ma boucle de programme, c'est par là que je recommencerai.
Ensuite, je mets dans le registre double hl l'adresse de mes 2 premiers patrons de sprite dits normaux. J'appelle ensuite CHOIX_SPRITE, qui n'est certes pas une routine BIOS, mais une routine que j'expliciterai ci-après et qui me permet de remplir la table des patrons de sprite avec les données qui vont bien. Les deux dernières lignes serviront à mettre le deuxième sprite à la bonne couleur.

Voici à présent la fameuse routine CHOIX_SPRITE :

Code ASM :
CHOIX_SPRITE:
ld de,SPRTBL
ld bc,64
call LDIRVM
ret
 

Cette routine fait appel à la routine BIOS LDIRVM, qui permet la copie d'un bloc de RAM vers une position de la VRAM. Ici, hl contiendra l'adresse de début des données de patrons de sprites (SPR_NEM, SPR_UP ou SPR_DOWN), de l'adresse de la VRAM où les informations seront envoyées et enfin bc la longueur en octets du bloc à transférer. Enfin, le ret me permet de retourner au programme principal !

Nous pouvons maintenant attaquer la partie la plus complexe !

Gestion du clavier

Pour gérer le clavier, nous avons une routine BIOS fort utile qui s'appelle GTSTCK. En fonction de la valeur de l'accumulateur a (0 pour le clavier, 1 pour le joystick du port 1, 2 pour le joystick du port 2), elle renvoie le numéro de direction (voir STICK en MSX-Basic pour connaître ces valeurs) dans l'accumulateur, ce qui nous permet d'effectuer une batterie de tests ! Comme je suis parti dans une utilisation du clavier, j'ai donc la portion de code suivante :

Code ASM :
xor a
call GTSTCK
ld b,a


Oui mais c'est pour quoi faire le ld b,a me demanderez-vous ? Eh bien pour tout vous dire, je pense que c'est une erreur de ma part car je croyais que l'usage d'un cp modifiait la valeur de l'accumulateur, ce qui n'est pas le cas (si je l'enlève, mon programme bugge par contre, allez comprendre :| ) ! Je stocke donc dans b la valeur renvoyée par GTSTCK, et j'aborde courageusement la série de tests !

Code ASM :
cp 1
CALL z,NORTH
ld a,b
cp 2
CALL z,NORTHEAST
ld a,b
cp 3
CALL z,EAST
ld a,b
cp 4
CALL z,SOUTHEAST
ld a,b
cp 5
CALL z,SOUTH
ld a,b
cp 6
CALL z,SOUTHWEST
ld a,b
cp 7
CALL z,WEST
ld a,b
cp 8
CALL z,NORTHWEST


En gros, je compare la valeur renvoyée par GTSTCK à chaque direction possible, et si la différence entre les deux est nulle, j'appelle la sous-routine de déplacement correspondante. Vous aurez aussi remarqué qu'avant chaque nouveau test (toujours cette erreur de ma part) je remets dans l'accumulateur la valeur initiale renvoyée par le GTSTCK !


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 25/03/2010 à 14h33
Dernière partie :

Pour ce qui est des routines de déplacement, je ne détaillerai ici que certaines d'entre elles, les autres étant calquées sur le même principe. Voici la routine qui gère le déplacement à droite :

Code ASM :
EAST:
ld a,[SPRITES+1]
cp 240
jr z,@@STOP
ld a,[SPRITES+1]
inc a
inc a
ld [SPRITES+1],a
ld a,[SPRITES+5]
inc a
inc a
ld [SPRITES+5],a
@@STOP:
nop
ret


Que fait donc cette routine ? Au départ, on va rechercher la valeur de l'abscisse dans la zone des variables et on teste si elle atteint 240 (oui parce qu'il faut compter la largeur du sprite de 16 pixels !). Le jr z,@@STOP renvoie à un sous programme qui ne fait rien si la valeur est effectivement atteinte. Si elle ne l'est pas, alors j'incrémente deux fois la valeur de l'accumulateur, puis je le remets à son emplacement d'origine. Je fais de même pour l'abscisse du deuxième sprite, et je retourne au programme principal.

Voyons à présent le déplacement vers le haut :

Code ASM :
NORTH:
ld hl,SPR_UP
call CHOIX_SPRITE
ld a,4
ld [SPRITES+7],a
ld a,[SPRITES]
cp 0
jr z,@@STOP 
ld a,[SPRITES]
dec a
dec a
ld [SPRITES],a
ld a,[SPRITES+4]
dec a
dec a
ld [SPRITES+4],a
@@STOP:
nop
ret


Le principe est comparable à la routine gérant le déplacement vers la droite, à ceci près qu'au départ, on rappelle la routine CHOIX_SPRITE en mettant cette fois dans hl l'adresse des données de patron de sprite correspondant à un déplacement vers le haut ! Ensuite on modifie la couleur du deuxième sprite (ld a,4 puis ld [SPRITES+7],a). Puis on teste le bord supérieur, etc.

On fait de même pour les autres déplacements, en notant que les déplacements en diagonale sont à la fois des déplacements dans une direction et une autre !

Il ne nous reste plus alors qu'à afficher les sprites, ce qui est fait avec la routine DUMP suivante :

Code ASM :
DUMP:
halt
ld hl,SPRITES
ld de,SPRATR
ld bc,2*8
call LDIRVM
ret


Le halt du début permet de synchroniser l'affichage en fonction du balayage vertical, le reste a déjà été expliqué auparavant.

Une fois l'affichage fait, il ne reste plus qu'à boucler vers LOOP :

jp LOOP

Dans le post suivant, le listing complet, et la ROM pour voir le résultat !


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 25/03/2010 à 14h36
Code ASM :
.bios
.page 2
.rom
.start DEBUT
 
NAMTBL equ 1800h
SPRTBL equ 3800h
SPRATR equ 1b00h
 
DEBUT:
call DISSCR
ld hl,0f3e9h
ld [hl],15
inc hl
ld [hl],0
inc hl
ld [hl],0
call INIGRP
ld bc,06201h
call WRTVDP
 
ld hl,NAMTBL
ld bc,768
xor a
call FILVRM
 
ld hl,ATR_INITIAL
ld de,SPRITES
ld bc,8
ldir
 
call ENASCR
 
LOOP:
ld hl,SPR_NEM
call CHOIX_SPRITE
ld a,8
ld [SPRITES+7],a
 
 
xor a
call GTSTCK
ld b,a
 
cp 1
CALL z,NORTH
ld a,b
 
cp 2
CALL z,NORTHEAST
ld a,b
 
cp 3
CALL z,EAST
ld a,b
 
cp 4
CALL z,SOUTHEAST
ld a,b
 
cp 5
CALL z,SOUTH
ld a,b
 
cp 6
CALL z,SOUTHWEST
ld a,b
 
cp 7
CALL z,WEST
ld a,b
 
cp 8
CALL z,NORTHWEST
 
 
call DUMP
jp LOOP
 
EAST:
ld a,[SPRITES+1]
cp 240
jr z,@@STOP
ld a,[SPRITES+1]
inc a
inc a
ld [SPRITES+1],a
ld a,[SPRITES+5]
inc a
inc a
ld [SPRITES+5],a
@@STOP:
nop
ret
 
WEST:
ld a,[SPRITES+1]
cp 0
jr z,@@STOP
ld a,[SPRITES+1]
dec a
dec a
ld [SPRITES+1],a
ld a,[SPRITES+5]
dec a
dec a
ld [SPRITES+5],a
@@STOP:
nop
ret
 
NORTH:
ld hl,SPR_UP
call CHOIX_SPRITE
ld a,4
ld [SPRITES+7],a
ld a,[SPRITES]
cp 0
jr z,@@STOP 
ld a,[SPRITES]
dec a
dec a
ld [SPRITES],a
ld a,[SPRITES+4]
dec a
dec a
ld [SPRITES+4],a
@@STOP:
nop
ret
 
SOUTH:
ld hl,SPR_DOWN
call CHOIX_SPRITE
ld a,[SPRITES]
cp 176
jr z,@@STOP
ld a,[SPRITES]
inc a
inc a
ld [SPRITES],a
ld a,[SPRITES+4]
inc a
inc a
ld [SPRITES+4],a
@@STOP:
nop
ret
 
NORTHEAST:
call NORTH
call EAST
ret
 
NORTHWEST:
call NORTH
call WEST
ret
 
SOUTHEAST:
call SOUTH
call EAST
ret
 
SOUTHWEST:
call SOUTH
call WEST
ret
 
DUMP:
halt
ld hl,SPRITES
ld de,SPRATR
ld bc,2*8
call LDIRVM
ret
 
CHOIX_SPRITE:
ld de,SPRTBL
ld bc,64
call LDIRVM
ret
 
ATR_INITIAL:
db 88,120,0,15
db 88,120,4,8
 
 
SPR_NEM:
    db  000h,080h,0e0h,070h,07fh,07fh,0bfh,0bfh,0bfh,078h,0e0h,000h,000h,000h,000h,000h
    db  000h,000h,000h,000h,000h,088h,0ffh,0f8h,000h,000h,000h,000h,000h,000h,000h,000h
    db  000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db  000h,000h,000h,000h,0c0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
 
SPR_UP:
    db 000h,080h,0e0h,070h,0ffh,01fh,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,080h,0f0h,0ffh,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,0e0h,0feh,07fh,03fh,01eh,018h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,000h,000h,0fch,0f0h,000h,000h,000h,000h,000h,000h,000h
 
SPR_DOWN:
    db 000h,000h,0b0h,0fch,07fh,07fh,0bfh,0bfh,0bfh,07fh,078h,0e0h,000h,000h,000h,000h
    db 000h,000h,000h,000h,080h,018h,08fh,0fch,0e0h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,0e0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h
 
.page 3
 
SPRITES:
ds 8


depl_sprite.zip


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

Villageois

Rang

Avatar

Inscrit le : 04/10/2009 à 21h35

Messages: 213

Le 25/03/2010 à 21h32
Ben là, c'est du travail de PRO !!

E-mail    
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 26/03/2010 à 08h24
Merci, mais je pense qu'il y a des améliorations à faire ! Comme ce problème si je vire les ld b,a et ld a,b. En principe ça ne devrait pas foirer mais ça foire, étrange... :hum

Comme je dis, si ça peut susciter des vocations, tant mieux, après tout ça ne fait que peu de temps que je me suis mis à l'assembleur, il faut s'accrocher et faire des essais (plein ! :) ) et bien regarder ce qu'on peut trouver par ailleurs pour comprendre, et si possible suivre le déroulement du programme avec papier et crayon :D !
Mais n'hésitez pas, lancez-vous !


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 22h54

Messages: 3280

Le 26/03/2010 à 09h56
Ce qui est rigolo (sur BlueMSX) c'est que si on fait sortir le vaisseau sur la guache plusieurs fois, il devient soit bleu soit rouge :)
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1500

Le 26/03/2010 à 12h22
Argh, j'ai mis une version non corrigée ! :oups

Voici la bonne, avec le listing dans le zip (s'ouvre avec le bloc-notes ou application style Notepad++) ;)

depl_sprite.zip


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

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 03/10/2009 à 08h06

Messages: 1702

Le 26/03/2010 à 12h36
moi jadore :top


MSX 8235 , MSX 8245 , MSX 8250 , MSX 8280

   
Walter Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++

Inscrit le : 02/10/2009 à 19h33

Messages: 1880

Le 26/03/2010 à 16h08
Parfait la version corrigée granced ! :noel

Quelques commentaires dans le listing si possible... sinon, c'est clair et net. Excellent travail ! :top
Riton Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 11/10/2009 à 21h47

Messages: 163

Le 26/03/2010 à 18h26
Chapeau :top Génial!


riton
   
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 772

Le 26/03/2010 à 21h10
Voilà le genre de post qui m'intéresse ;)
Beau boulot Granced et tu as le mérite de te lancer et de bien nous expliquer ton raisonnement pour ton programme, pour suivre il faut bien sur avoir quelques notions.
Je débute moi aussi et j'ai déjà fait un petit travail sur la base du tien, il me reste quelques trucs à voir et commenter un peu tout ça.
Il n'y a plus qu'à lancer les inscriptions pour le club des petits assemblistes en herbe! ;)


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 772

Le 26/03/2010 à 22h22
Bon, j'ai fait différemment, après reste à savoir s'il y a une méthode meilleure qu'une autre :hum

Le programme de Granced avec mes modifs

Code ASM :
.bios
.page 2
.rom
.start DEBUT
 
NAMTBL equ 1800h
SPRTBL equ 3800h
SPRATR equ 1b00h
 
DEBUT:
call DISSCR
ld hl,0f3e9h
ld [hl],15
inc hl
ld [hl],0
inc hl
ld [hl],0
call INIGRP
ld bc,06201h
call WRTVDP
 
ld hl,NAMTBL
ld bc,768
xor a
call FILVRM
 
ld hl,ATR_INITIAL
ld de,SPRITES
ld bc,8
ldir
;
; Defininitions des sprites
;
        ld      hl,SPR_DEF ;On charge en HL le début de l'endroit de la mémoire ou sont stocké les patrons des sprites
        ld      de,SPRTBL;On indique où on veut les mettre (table  des patrons des sprite à partir de 0) 
        ld      bc,6*4*8;on boucle sur 6 sprites de 4 carrés de 8 octets
        call    LDIRVM        ;on copie HL en ROM sur DE en VRAM, HL=HL+1, DE=DE+1, BC=BC-1 jusqu'à ce que BC=0.
 
call ENASCR
 
LOOP:
 
xor a        ; mise à 0 de l'accu (a)
call CHOIX_SPRITE; mise à la valeur par défaut de l'aspect du vaisseau
;
; DEPLACEMENT 
;
xor a        ; mise à 0 de l'accu (a)
call GTSTCK; test du pad clavier (0)
pushaf; Sauvegarde de a dans la pile
;
;EST
;
ld HL,STK_POE; HL pointe vers les 3 positions ou le sprite va à droite (2,3,4)
ld bc,3        ; BCà 3 on boucle sur 3 tours voir instruction suivante:
cpir        ; test de a avec l'adresse pointé par HL puis HL=HL+1 et BC=BC-1
        ; jusqu'à ce que BC=0 (fin de la boucle) :-) je viens de découvrir cette instruction!
JR NZ,@@WEST ; si pas d'égalité entre a et une des 3 valeurs pointé par HL on passe à la suite
        ; sinon on déplace le sprite
ld a,[SPRITES+1]           ; a=position en x du sprite 1
cp 240                ; a=240?
jr z,@@NORTH       ; oui donc on passe direct au déplacement vertical
inc a                ; sinon a=a+2
inc a
ld [SPRITES+1],a  ; remise de a+2 dans x du sprite1
ld [SPRITES+5],a     ; puis dans x du sprite2 car il sesuivent en permanence ;-)
jp @@NORTH          ; puis on passe direct au déplacement vertical
;
;OUEST
;
@@WEST:
ld HL,STK_POW
ld bc,3
cpir
JR NZ,@@NORTH 
ld a,[SPRITES+1]
cp 0
jr z,@@NORTH
dec a
dec a
ld [SPRITES+1],a
ld [SPRITES+5],a
;
;NORD
;
@@NORTH:
popAF
ld HL,STK_PON
ld bc,3
cpir
JR NZ,@@SOUTH 
ld a,8
call CHOIX_SPRITE
ld a,[SPRITES]
cp 0
jr z,@@END
dec a
dec a
ld [SPRITES],a
ld [SPRITES+4],a
JP @@END
;
;SUD
;
@@SOUTH:
ld HL,STK_POS
ld bc,3
cpir
JR NZ,@@END
ld a,16
call CHOIX_SPRITE
ld a,[SPRITES]
cp 176
jr z,@@END
ld a,[SPRITES]
inc a
inc a
ld [SPRITES],a
ld [SPRITES+4],a
 
@@END:
call DUMP
jp LOOP
 
 
nop
ret
 
 
DUMP:
halt
ld hl,SPRITES
ld de,SPRATR
ld bc,8
call LDIRVM
ret
 
CHOIX_SPRITE:
ld [SPRITES+2],a
add a,4
ld [SPRITES+6],a
cp 12
jr nz,@@ROUGE
ld a,4
jp @@COULEUR
@@ROUGE:
ld a,8
@@COULEUR:
ld [SPRITES+7],a
ret
 
ATR_INITIAL:
db 88,120,0,15
db 88,120,4,8
STK_POE:
db 2,3,4
STK_POW:
db 6,7,8
STK_PON:
db 8,1,2
STK_POS:
db 4,5,6
 
SPR_DEF:
;SPR_NEM1=sprite0 
    db  000h,080h,0e0h,070h,07fh,07fh,0bfh,0bfh,0bfh,078h,0e0h,000h,000h,000h,000h,000h
    db  000h,000h,000h,000h,000h,088h,0ffh,0f8h,000h,000h,000h,000h,000h,000h,000h,000h
;SPR_NEM2=sprite1*4= 4 
    db  000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db  000h,000h,000h,000h,0c0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;SPR_UP1=sprite2*4= 8
    db 000h,080h,0e0h,070h,0ffh,01fh,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,080h,0f0h,0ffh,000h,000h,000h,000h,000h,000h,000h,000h,000h
;SPR_UP2=sprite3*4= 12
    db 000h,000h,000h,000h,000h,0e0h,0feh,07fh,03fh,01eh,018h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,000h,000h,0fch,0f0h,000h,000h,000h,000h,000h,000h,000h
;SPR_DOWN1=sprite4*4= 16
    db 000h,000h,0b0h,0fch,07fh,07fh,0bfh,0bfh,0bfh,07fh,078h,0e0h,000h,000h,000h,000h
    db 000h,000h,000h,000h,080h,018h,08fh,0fch,0e0h,000h,000h,000h,000h,000h,000h,000h
;SPR_DOWN1=sprite5*4= 20
    db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
    db 000h,000h,000h,000h,000h,0e0h,070h,000h,000h,000h,000h,000h,000h,000h,000h,000h
 
.page 3
 
SPRITES:
ds 8

Le fichier qui va bien et fait la même chose que celui de Granced :D
depspr2.zip


Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie