Revenir au plan du site

Le cas de l'exclusion

Notre routine de sprite clippé est conçue pour afficher AU MOINS un octet. Mais si le sprite est en dehors de l'écran, attention aux effets secondaires. En même temps, il serait aberrant d'appeler notre routine si notre sprite n'est pas dans l'écran non?

À quel moment commence-t'on à afficher les sprites ? Bééééééééh quand ils sont dans l'écran! Pour le moment, notre routine de sprite ne gère que des coordonnées X en 8 bits très petites mais suffisantes pour gérer le clipping
AfficheSprite
; BC=page + coordonnée X (0-79) / HL=coordonnée Y (0-199) / DE=adresse des données du sprite
; XL=largeur du sprite en octets / XH=hauteur du sprite en nombre de lignes


Si on prend la position minimale d'un personnage sur l'écran précédent (-80) et même pour la position à la fin de l'écran suivant (160, soit -96 en signé), ça pourrait passer. Mais il faut quand même réaliser la comparaison comme quoi le sprite n'est pas présent dans l'écran! Voici le récapitulatif des comparaisons à effecturer pour savoir si notre sprite est totalement hors de l'écran.


Pour ce snipet je vais partir du principe que votre sprite est dans une structure contenant son X en 16 bits, son Y en 16 bits, l'adresse des données, sa taille et ce que vous voulez ensuite.
struct sprite
positionx defw
positiony defw
adresse   defw
sprlargeur defb
sprhauteur defb
; ...
endstruct


Sur cette base, le code de clipping avant appel de la routine AfficheSprite serait le suivant
AfficherTableauSprite
ld iy,tableau_sprite
.loop
ld hl,(iy+sprite.positionx)
bit 7,h : jr nz,.testGauche ; si c'est négatif on fait le test de gauche
; on teste le débordement à droite (80 octets en configuration standard)
ld de,80 : or a : sbc hl,de
jp m,.hautBas
jr .horsEcran
.testGauche
ld a,(iy+sprite.sprlargeur) : add l : ld l,a : ld a,h : adc 0
jp m,.horsEcran ; négatif hors écran, reste à tester le zéro
ld a,l : or a : jr z,.horsEcran ; on fait un raccourci de calcul car on partait d'une position négative
; quasiment le même code de tester le débordement en vertical
.hautBas
ld hl,(iy+sprite.positiony)
bit 7,h : jr nz,.testHaut ; si c'est négatif on fait le test du haut
; on teste le débordement en bas de l'écran de 200 lignes
ld de,200 : or a : sbc hl,de
jp m,.affiche
jr .horsEcran
.testHaut
ld a,(iy+sprite.sprhauteur) : add l : ld l,a : ld a,h : adc 0
jp m,.horsEcran ; négatif hors écran, reste à tester le zéro
ld a,l : or a : jr z,.horsEcran ; on fait un raccourci de calcul car on partait d'une position négative
.affiche
ld b,#C0 ; bank vidéo par défaut
ld c,(iy+sprite.positionx) ; on peut ne lire que 16 bits à la même adresse, merci le little endian
ld hl,(iy+sprite.positiony)
ld de,(iy+sprite.adresse)
ld a,(iy+sprite.sprlargeur) : ld xl,a
ld a,(iy+sprite.sprhauteur) : ld xh,a
push iy ; car notre routine de sprite masqué utilise YL ...
call AfficheSprite
pop iy
.horsEcran
; ajouter ici une condition de bouclage, par exemple sur les données...
ld de,{sizeof}sprite : add iy,de
ld a,(iy+sprite.sprlargeur) : or a ; tester la largeur du prochain sprite
jp nz,.loop ; on reboucle si le prochaine sprite n'a pas une largeur nulle


Je suis au regret de ne pouvoir vous faire un test visuel pour cette routine puisque l'object de cette routine est de ne pas afficher le sprite si il déborde!

Je ne dis pas qu'il ne soit pas possible de tester ce programme, il suffirait de donner des coordonnées hors-écran à la routine et de mettre un point d'arrêt pour contrôler qu'on ne déclenche pas l'appel aux sprites pour des coordonnées invalides, mais on entre dans un cadre plus abstrait qui requiert par ailleurs d'autres sur la façon de tester des routines. On n'est pas à l'école non plus là ;)