ASMtrad CPC

Apprenez l'assembleur Z80

Masquage de sprite standard sans contrainte.

Prenons un sprite.

En général, celui ci tient dans un rectangle (mais ce n'est pas obligé non plus).

Imaginons que le gfx de notre sprite soit une boule.

Si l'on affiche notre sprite, nous aurons donc une boule dans un rectangle. Car autour de la boule nous aurons mis une couleur.
Hors, si notre fameuse boule est affichée sur un fond, nous verrons donc bien une boule dans un rectangle...
Le but du masquage est de supprimer les pixels se trouvant autour de notre gfx pour ne garder que la partie à afficher.
On obtient ainsi une boule sur un fond.

Plusieurs solutions s'offrent à nous...

On aurait par exemple pu utiliser une couleur pour le fond et uniquement pour lui.
Sauf que cela nous oblige à faire des tests pour déterminer si l'octet à afficher contient cette couleur.
On va perdre un maximum de temps et on perd aussi une couleur...
Solution donc complètement nulle, on oublie direct.

Il nous reste en gros 2 solutions: Le masquage au pixel avec un vrai masque. Ou: utiliser des bitsplan... On va donc voir cela.

A noter qu'il existe d'autres méthodes de masquages et nous en verrons donc quelques unes.

Mais avant tout cela il faut que je vous parle de quelques instructions d'opérations logiques. Rien de bien compliqué je vous rassure !!!

OR XOR AND

Ces 3 instructions permettent de modifier les bits à partir d'une logique binaire.
On va faire simple en partant de tableaux et d'exemples:

opérations logiques

Prenons le AND.
Si nous avons un octet et que nous faisons un AND avec un autre:

                                %01011010
                            AND %11010010
                                _________
                                %01010010

Rien de plus simple: dès qu'il y a un 0, on obtient un 0. Seuls deux 1 donnent 1.

Le OR lui préserve les bits à 1.

Le XOR fait la même chose mais supprime un double 1.

Je fais simple mais je pense que c'est le mieux pour comprendre.

Ces opérations logiques vont nous être bien utiles :)

Niveau instructions nous avons:

AND r8
AND val8
AND (r16) ; sauf BC et DE
OR r8
OR val8
OR (r16) ; sauf BC et DE
XOR r8
XOR val8
XOR (r16) ; sauf BC et DE

Utilisation du masque:

Regardons un peu le AND de plus pret.
Lorsque deux bits sont à 1, on aura 1.
0 AND 0=0.
En revanche, avec un bit à 0, on obtient toujours 0.

Nous allons nous en servir pour supprimer sur le fond de l'écran la silhouette de notre sprite (donc la partie graphisme du sprite).

Un petit exemple:

suppression de la silhouette du sprite

A gauche, nous avons notre fond bleu (qui pourrait être une image; donc plusieurs encres).
Au milieu, nous avons la silhouette de notre sprite.
La silhouette est en encre 0 et le tour en encre 15 (je vais vous expliquer pourquoi ensuite.).

Nous faisons un AND entre les deux, et nous obtenons la même image, mais la silhouette de notre sprite a été remplacée par l'encre 0 (donc des bits à 0).

Pourquoi utiliser l'encre 15 ? (En mode 0 bien entendu, sinon en mode 1, il faudra utiliser l'encre 4).

Eh bien, tout simplement parce qu'avec cette encre, tous les bits du pixel sont mis à 1 !!!
Dans le cas d'un AND c'est une obligation, sinon avec un bit à 1 et un autre à 0 vous allez modifier les bits (si vous ne voyez pas pourquoi bein faut relire et poser l'opération).

Maintenant que nous avons enlevé du fond notre silhouette (qui est donc pleine de jolis 0), on peut maintenant afficher notre sprite dessus. Mais pas n'importe comment !!!

Pas question de faire un affichage classique, car notre sprite étant carré (sauf si vous avez décidé d'économiser quelques octets), il y a donc un contour carré autour de votre dessin.

Là encore, une petite opération logique va nous rendre service et pour ce coup-ci c'est le OR.

Le OR c'est simple, si nous avons deux 1 ça donnera 1.
Si nous avons deux 0, ça donnera 0. Si nous avons un 1 et un 0, ça donnera un 1.

Pour le coup, on dessinera donc notre sprite tranquillement en utilisant comme encre de fond l'encre 0.

Ainsi en faisant un OR du fond avec le sprite, tous les pixels seront respectés, puisque pour le tour du sprite, le fond étant soit à 0 ou 1, le fait que le contour de notre sprite soit avec l'encre 0, tous les bits des pixels sont à 0.
Ainsi, si un pixel du fond contient un bit à 1, en faisant un OR avec notre 0 de contour donnera forcement un 1...

Pour le sprite de votre joli perso (ou autre bricole que vous affichez), comme nous avons supprimé la silhouette qui est donc passée en encre 0, on aura la même chose :)

Notre affichage consistera donc à faire:

- ANDer le fond avec le masque.

- ORer le sprite avec le fond.

Pour gagner du temps, on pourra aussi entrelacer le masque et le sprite 1 octet sur deux (donc avoir en ram un octet de masque puis un octet de sprite alternés).

Vous devriez donc maintenant réussir à faire un masquage sans contrainte (pas de sacrifice de couleur).