CODINGCHRONIQUE A100% DES LOGON SYSTEM ★ LOGON SYSTEM ACPC N°47 - SPRITES !!!! ★

Logon System ACPC n°47 - Sprites !!!!Coding Chronique A100% Des Logon System
Salut bande de codeurs en délire! Voici comment afficher un sprite selon diverses méthodes, en allant de la plus élémentaire et lente à la plus évoluée et rapide. Vous découvrirez aussi la diversité des modes d'affichage qu'offre le Z80.

Le listing se compose donc d'un programme principal et de différentes routines d'affichage de sprites que nous allons expliquer une par une. Qu'entendons-nous par « mode d'affichage » ? Eh bien! c'est la façon dont va se combiner le motif du sprite avec le fond ou le décor affiché à l'écran: le sprite peut se superposer au fond, passer derrière, se mélanger avec, l'effacer, etc.

LE SPRITE EN MODE 1

Mais avant de voir les possibilités d'affichage, nous allons d'abord voir comment déterminer l'adresse-écran où il faut afficher le sprite en fonction des coordonnées x et y données. Nous allons étudier le cas d'un sprite en mode 1, car c'est un cas assez global. Un écran mode 1 normal fait 320 pixels de large, soit 80 octets. Un octet contient donc 4 pixels, et leur organisation binaire est si complexe qu'il est très compliqué d'afficher un sprite au pixel près: cela demanderait énormément de temps-machine pour faire tous les décalages, rotations et masquages nécessaires en temps réel. L'astuce consiste, comme d'habitude, à précalculer les positions des sprites au pixel près. Le même sprite est reproduit 4 fois en mémoire, à chaque fois décalé d'un pixel. Inconvénient : un sprite ainsi codé en mémoire prend 4 fois plus de place (2 fois plus de place s'il était en mode 0 puisqu'il n'y a que 2 pixels par octet et 8 fois plus de place en mode 2 [8 pixels par octet]). Ainsi, le petit listing en Basic met en mémoire un petit sprite de 4 octets sur 1 3 lignes, décalé 4 fois, ainsi que son masque également décalé (nous en verrons l'utilité plus tard). En résumé, il faut donc décomposer l'abscisse x en nombre d'octets et en nombre de décalages de pixel par rapport au nombre de pixels contenus dans un octet (selon le mode).

Voilà pour l'abscisse, maintenant. occupons-nous de l'ordonnée (y). Comme vous le savez, l'organisation de la mémoire écran n'est pas linéaire: c'est-à-dire que la 2' ligne visible à l'écran ne se trouve pas en mémoire juste après la première. Bien qu'il soit relativement facile de descendre d'une ligne à une autre, il est plus difficile de se positionner directement à la ligne voulue par un algorithme, d'où la nécessité encore une fois de pré calculer une table des ordonnées contenant l'adresse écran de chaque ligne, les unes en dessous des autres, permettant d'obtenir automatiquement et directement l'adresse de la ligne voulue! On récupère l'adresse de la ligne voulue en prenant l'ordonnée et en la multipliant par 2 (puisqu'une adresse tient sur 2 octets) et on additionne à cette valeur l'adresse où est stockée la table; on pointe ainsi sur l'adresse voulue qu'on n'a plus qu'à récupérer. Cette opération peut se faire de plusieurs façons; dans le listing 1, c'est le registre HL qui pointe sur la table des adresses des lignes écran tandis que dans le listing 2, les adresses sont récupérées grâce à la pile (ce qui peut s'avérer plus rapide, à condition que la pile ne soit pas utilisée en même temps). Voilà donc obtenues l'adresse source (l'adresse du sprite décalé correspondant à l'abscisse) et l'adresse destination (l'adresse écran ou va être affiché le sprite). On peut donc maintenant passer à l'affichage proprement dit

L'AFFICHAGE

Le listing 1 regroupe plusieurs façons conventionnelles d'afficher un sprite, nous allons donc les commenter une par une, des plus simples aux moins évidentes avec leurs points forts et leurs points faibles:

— n°1 : affichage par LDIR. Vraiment la méthode la plus élémentaire pour afficher un sprite ! Avantage: le code ne prend pas beaucoup de place en mémoire. Inconvénient: un LDIR demande l'équivalent de 5 NOPS en temps-machine, ce qui est quand même pas mal, d'autant plus que le sprite est affiché à l'écran en effaçant le fond sur tout le rectangle qui définit sa surface;

— n°2 : affichage par LDI. Le principe est à peu près le même que celui de la routine n°1, à ceci près qu'on remplace le LDIR par autant de LDI que le LDIR doit être effectué (autrement dit, on met autant de LDI qu'il y a d'octets qui composent le sprite en largeur). Avantage: sensiblement plus rapide que LDIR (un LDI prend 4 NOPS en temps-machine), surtout si le sprite est large. Inconvénient: la routine d'affichage prend d'autant plus de place que le sprite est large, et le fond à l'endroit où le sprite s'affiche disparaît là encore;

— n°3 : affichage avec test d'octet Ce système permet de donner au sprite un semblant de masquage. On teste à l'aide d'un OR si l'octet du sprite est nul. S'il n'est pas nul. on l'affiche, sinon, on passe au suivant. Avantage: le fond derrière le sprite est ainsi partiellement sauvé, et la routine occupe peu de mémoire. Inconvénient : la routine est lente et le résultat à l'écran n'est pas toujours parfait car le masquage se fait a l'octet et non au pixel (remarque: le résultat reste fort convenable en mode 0).

— n°4 : affichage en « mélangeant » sprite et fond. Ici, on fait directement un OR entre le sprite et le fond, et on affiche le résultat. Ce genre de routine est avantageuse lors d'un écran en « dual-playfield » : grâce à un jeu d'encre, on peut afficher des sprites masqués au pixel par un simple OR. mais ces sprites sont moins colorés que des sprites normaux. Dans le cas d'un dual playfield (cf les sprites de la démo du dernier numéro d'Amstrad Cent Pour Cent), il suffit d'utiliser exactement la même routine avec un XOR à la place du OR pour réafficher le fond. S'il n'y a pas de dual-playfield, le résultat à l'écran peut parfois être bizarre (superpositions de couleurs...), mais cette routine a l'avantage d'être suffisamment rapide et de ne pas prendre trop de mémoire.

— n°5 : affichage par masquage. La routine qui offre le meilleur résultat visuel, mais aussI la plus compliquée! Elle nécessite, en plus des données du sprite, un masque qui détermine quels pixels du fond doivent disparaître (cela permet, par exemple, de faire un petit contour noir autour des sprites, comme dans le jeu KnightTime). On fait un AND entre le masque et le fond, puis on fait un OR entre le résultat et la donnée de l'octet du sprite, et enfin, on affiche. Avantage: finesse de l'affichage. Inconvénients: le masque prend autant de place que le sprite et l'affichage est lent.

— n°6 : affichage à la pile. un affichage qui trouve son utilité, surtout pour déplacer de gros sprites sur un fond uni. En effet cette technique d'affichage prend les octets 2 par 2 (d'où la nécessité d'avoir un sprite composé d'un nombre pair d'octets en largeur), ce qui permet d'être plus rapide, mais le fond derrière le sprite est détruit.

Voilà pour ce qui est de l'affichage des sprites. Il est possible, par exemple dans le cadre d'une animation, que vous souhaitiez que le fond soit restitué. Dans ce cas, il suffit de le sauver à l'aide de LDIRs ou de LDis dans un buffer de la taille du sprite, puis que vous affichiez le sprite, et ensuite que vous réaffichiez le fond précédemment sauvegardé grâce à des LDis, LDIRs, PUSH-POP, etc.

BAS LES MASQUES

On a donc vu que les routines les plus intéressantes, notamment celles par masquage, sont souvent les plus lentes. Pour avoir un masquage rapide, nous allons faire un générateur de codes, qui produit une routine telle que le sprite est incrusté dans cette routine. C'est ce que fait la routine « gêner » du listing 2. Cette routine crée donc 4 routines de sprites différentes (une pour chaque décalage de pixel). Les adresses de ces 4 routines sont contenues dans une table qui sert lors du traitement de l'abscisse, à savoir sur quelle routine d'affichage il faudra sauter plus tard. Comme les masquages entre le fond et le sprite sont immédiats, l'affichage est extrêmement plus rapide de cette façon En revanche, la mémoire demandée est assez considérable puisqu'il n'y a pas de boucle et puisqu'il faut environ 8 octets de code autogénéré pour afficher un octet du sprite. Néanmoins, on peut se permettre cette perte d'espace mémoire pour des petits sprites, et à plus forte raison si on fait une démo.

Le listing 2 vous explique le code auto-généré pour l'affichage par masquage, mais de toutes façons, il est également possible de faire du code auto-généré avec les autres types d'affichage. Par exemple, pour l'affichage avec test d'octet, il suffit de vérifier si l'octet est vide ou non lors de la génération du code; le code résultant se trouve grandement optimisé!

Voilà, nous avons vu l'essentiel concernant l'affichage des sprites, il ne me reste plus qu'à vous souhaiter de bien assimiler cette rubrique et à espérer que j'en aurai bientôt fini avec cette ?#'!$@ de grippe!

A bientôt! Pict

Pict / Logon System, ACPC n°47 Avril 93, p 18-19-20-21

★ ANNÉE: 1993
★ AUTEUR: PICT

Page précédente : Logon System ACPC n°46 - Une demo décortiquée
★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tools:
» logon47DATE: 2012-02-15
DL: 352
TYPE: image
SiZE: 471Ko
NOTE: w1872*h1713
 
» LOGON47    (Typed  by  Spoke)    LISTINGDATE: 2012-02-19
DL: 303
TYPE: text
SiZE: 14Ko
NOTE:

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Logon System ACPC n°35 - Le Gate Array
» Coding » Logon System ACPC n°49 - Le soundtrack sur CPC
» Coding » Logon System ACPC n°46 - Une demo décortiquée
» Coding » Logon System ACPC n°32 - La rupture
» Coding » Chronique A100% par les Logon System
» Coding » Logon System ACPC n°37 - Histoire de rasters
Je participe au site:
» Vous avez des infos personnel ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop
Page créée en 288 millisecondes et consultée 2735 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.