Les players

Afin de faire quelques expériences avec les players, nous allons laisser de côté nos programmes précédents et repartir d’un écran vierge. Ce sera bien assez « sport » comme ça, pas la peine de s’ajouter des difficultés !

Commençons avec ce kernel simplissime :

   lda #$82
   sta COLUBK
   ; -------------- fin du vblank -------------
   ; --------- Kernel = logique d'affichage -------------------
   LDY #191

Ciel ; lignes de ciel
   STA WSYNC
   dey
   bne Ciel

Le vcs met à votre disposition 2 players (ou sprites, lutins, appelez-les comme vous voulez) Mis à part pour pong ou combat, cela fait un peu juste non ?
La bonne nouvelle, c’est que, tout comme les registres de playfield, vous pouvez modifier les registres des players à la volée, de scanline en scanline, ce qui nous autorise en fait 2 players par tranche horizontale d’écran.

Le graphisme d’un player occupe 8 pixels horizontalement, et est stocké dans les registres GRP0 et GRP1. Tout comme les playfields, le contenu de ce registre est utilisé à chaque scanline, jusqu’à ce que vous réinitialisiez son contenu. Chose assez inhabituelle, vous pouvez du coup avoir un player qui fait toute la hauteur de l’écran (mais sur 8 pixels de large !).

La couleur de chaque player est représentée par les registres COLUP0 et COLUP1.

Une autre bonne nouvelle, c’est qu’un registre (NUSIZ0 et NUSIZ1)  permet de dupliquer jusqu’à 3 fois  chaque player, et/ou l’étirer horizontalement.

On a vu que le player se positionne verticalement en commençant à mettre des valeurs de graphisme dans son registre GRP0 à la scanline désirée.
La mauvaise nouvelle maintenant, c’est qu’horizontalement, ce n’est pas aussi simple ! Pour indiquer où sur la scanline commencer à afficher le player, il faut préalablement initialiser le registre RESP0 (ou RESP1) lorsque le balayage est à l’endroit souhaité. Une fois ceci fait, la position est mémorisée, jusqu’à ce que vous souhaitiez la modifier à nouveau.

Mais chaque chose en son temps 🙂

Ecrivons un petit programme afin de visualiser l’effet du registre NUSIZ :

Tout d’abord, 2 cases mémoire, la première contiendra la position verticale de notre premier player, la seconde contiendra la valeur courante de NUSIZ (vu que les registres x et y sont utilisés par ailleurs).

P0YPos1      ds 1
TempVal      ds 1

Initialisons la position verticale à 180 (= 12e ligne puisqu’on décompte) et la couleur du player (blanc) :

   ; ---------- initialisations diverses ------------
   lda #180
   sta P0YPos1
   lda #$0E    ; blanc
   sta COLUP0  ; couleur player 0

Pendant la première ligne qui suit le vertical blank, nous indiquons la couleur de fond d’écran (bleu), puis nous positionnons horizontalement notre player :

Wait_VBLANK_End
   LDA INTIM            
   BPL Wait_VBLANK_End    
   STA WSYNC         ; 1e ligne
   
   LDA #0 
   STA VBLANK            
   lda #$82
   sta COLUBK
   nop 
   nop
   nop 
   nop
   nop 
   nop
   
   sta RESP0 ; positionne le player qqpart à gauche, au pif

Qu’avons-nous fait ? L’instruction nop signifie « no operation », donc le processeur ne fait rien, et ce pendant 2 cycles. Durant ces 12 cycles (6 nop * 2), le balayage a parcouru une distance horizontale, et c’est là où le balayage se trouve au bout de 12 cycles (en réalité, 12 cycles + le nombre de cycles nécessaire aux 2 lda-sta) que nous positionnons le player, par assignation du registre RESP0 avec une valeur quelconque. Aucune précision n’est actuellement de mise ! Nous reviendrons ultérieurement sur le positionnement horizontal, pour le moment, tout ce qui nous importe, c’est qu’il soit positionné quelque part dans la gauche de l’écran de façon à avoir assez de place pour son afffichage complet, mais pas trop à gauche pour éviter des problèmes de timing.

Les bits 0, 1 et 2 de NUSIZ déterminent la taille et le nombre de duplications du player. Nous allons donc faire varier TempVal de 0 à 7 et, pour chaque valeur, consommer une ligne à fins d’initialisation, puis 8 lignes pour afficher le player. Voici notre kernel :

    ; --------- Kernel = logique d'affichage -------------------
   LDY #191
 
Ciel              ; lignes de ciel
   STA WSYNC   
   
   cpy P0YPos1    ; position de la ligne qui précède
                  ; le player pour les diverses init
   bne SkipPos1

   ; test NUSIZ bits 0,1 et 2
   lda #0
   sta TempVal
   
TestLoop   
   ; 1e ligne consacrée aux initialisations
   sta NUSIZ0    
   lda #0
   sta GRP0       ; player éteint lors de l'init.

   jsr DrawP0Pos1 ; 8 lignes d'affichage du player

   dey
   sta WSYNC
   
   inc TempVal
   lda TempVal
   cmp #8
   bne TestLoop
   
SkipPos1
   lda #0
   sta GRP0
   
   dey
   bne Ciel
   ; ---------- Kernel terminé --------------------------------

Et voici la sous-routine d’affichage du player et les données d’affichage :

DrawP0Pos1   SUBROUTINE   
   ldx #8
DrawP0
   dey
   sta WSYNC

   lda DataP0-1,x
   sta GRP0

   dex
   bne DrawP0
   rts   
   
DataP0   ; image du player
   .byte #%11000011
   .byte #%10000001
   .byte #%00000000
   .byte #%00011000
   .byte #%00011000
   .byte #%00000000
   .byte #%10000001
   .byte #%11000011

Notez que la boucle x va de 8 à 1, car la valeur 0 est le test de sortie de boucle. C’est pour cela que nous attaquons les données à partir de l’octet précédant DataP0.

Voici le résultat de notre petit programme :

Test NUSIZ0 de 0 à 7

Valeur des bits 0, 1 et 2 de NUSIZ0 =

  • 0 : un exemplaire
  • 1 : deux exemplaires proches
  • 2 : deux exemplaires moyennement éloignés
  • 3 : trois exemplaires proches
  • 4 : deux exemplaires très éloignés
  • 5 : un exemplaire double-largeur
  • 6 : trois exemplaires moyennement éloignés
  • 7 : un exemplaire quadruple-largeur

Deux constatations :

  • les versions élargies du player sont légèrement décalées vers la droite, il faudra s’il y a lieu en tenir compte
  • les versions dupliquées laissent un trou de 8 pixels entre chaque élément; ainsi, pour afficher un score par exemple, il conviendra d’intercaler le deuxième player, même si 2 ou 3 positions suffisent.

Cet exercice nous a fait mettre en pratique

  • GRP0 et GRP1 : données graphiques des players
  • COLUP0 et COLUP1 : couleur des players
  • NUSIZ0 et NUSIZ1 : nombre et taille des players (et missiles)
  • RESP0 et RESP1 : initialisation de la position horizontale des players

Vous pouvez télécharger ce fichier source prêt à compiler ici : https://dl.dropbox.com/u/56947388/Cambouis/tstnusiz.asm
(click-droit/enregistrer la cible sous)

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :