Sprites en movimiento

Hoy vamos a mover el sprite que hicimos por la pantalla, utilizando el joystick en el port 2.

Los joysticks son manejados una de las CIA que tiene la C64, para ello vamos a leer la direccion de memoria $dc00 que corresponde al joystick 2. Los bits 0,1,2,3 corresponden a las direcciones (0 up, 1 down, 3 right, 4 left) y el bit 5 correspondiente al disparo. Si leemos la direccion vamos a notar que nos devuelve el valor 127, y cuando movemos en alguna direccion o disparamos se pone el bit correspondiente en 0. Hay muchas formas de leer esto, pero me parecio la mas simple la siguiente:

Cargamos en el registro A el contenido de $dc00, le hacemos un AND (1, 2, 4, 8, 16), y si da 0 es porque esta pulsado el joy en la direccion que estamos chequeando, entonces incrementamos o decrementamos el registro de posicion X o Y del sprite correspondiente, y proseguimos a chequear otra direccion de movimiento.

El codigo es mas claro:

joy2 = $dc00

main_loop
          lda            joy2      ; cargo en A el contenido de $DC00
          cmp            #127      
          beq            next      ; si es 127 (11111111) es que no pulse nada, salteo el checkeo restante

; aca entra si se pulso algo en el joystick
          lda            joy2      
          and            #1        ; up (11111110 AND 00000001 = 0 si pulso arriba, si no es 1)
          bne            chkDown   ; si el resultado de la ultima operacion es 1 pasa a chequear otra direccion de movimiento (*)
          dec            spry      ; y si no decrementa posicion Y del sprite 1 

chkDown   lda            joy2      
          and            #2        ; down
          bne            chkLeft   
          inc            spry      

chkLeft   lda            joy2      
          and            #8        ; left
          bne            chkRight  
          dec            sprx      

chkRight  lda            joy2      
          and            #4        ; right
          bne            chkFire   
          inc            sprx      

chkFire   lda            joy2      
          and            #16       ; fire
          bne            next      
          rts                      ; vuelve al BASIC
next
          jmp            main_loop 

La parte mas ‘rara’ de entender para mi fue donde señalé con (1). BNE es una instruccion que hace un salto si la comparacion previa da distinto:
ejemplo: tengo en X el valor #5, hago CPX #6 y la siguiente instruccion BNE va a saltar, porque el resultado de la comparacion da que son diferentes.
Ahora ¿como hace la comparacion el procesador? Simple, lo que hace es una resta, y si da 0 es que son iguales, y si da distinto de 0 son diferentes.
En este caso estamos haciendo una operacion logica AND, y si el resultado de la operacion es 1 hace un salto (porque BNE hace un salto si el resultado de la ultima operacion es distinto de 0). Si da 0 es porque el bit de la direccion que queremos testear se pone en 0, BNE no hace el salto, pasa a la siguiente instruccion que (o casualidad) decrementa o incrementa la posicion X/Y del sprite.
¿Se entiende?

Aca el codigo completito

Cambiamos el sprite del pacman por el del juego Jetpac, de la ZX Spectrum, lo podemos mover con el joystick conectado al port 2, y volvemos al BASIC con el disparo. La idea con este codigo es ir incorporando bloques para armar un pequeño juego. En las siguientes entregas vamos a agregar disparos, colisiones, 2 jugadores… lo que salga…

*         = $c000

raster    = $d012
cborde    = $d020
cfondo    = $d021
spractive = $d015
sprcolor  = $d027
sprpoint  = $07f8
sprx      = $d000
spry      = $d001
joy2      = $dc00

defm      putsprite
          ldx            #/1       
          stx            sprx
          ldx            #/2       
          stx            spry
          endm

defm      waitrt
@loop     ldx            raster
          cpx            #$0       
          bne            @loop     
          endm

main      lda            #$00      
          sta            cborde     
          sta            cfondo

          putsprite      172,139     

          lda            #$01      
          sta            spractive ;activamos el sprite 0

          lda            #$01      
          sta            sprcolor  ; lo ponemos color blanco

          lda            #$0d      
          sta            sprpoint  ; ponemos el puntero del sprite 0 en $0340

          jsr            movedata  

main_loop
;         check joystick 
          lda            joy2      
          cmp            #127      
          beq            next      

          lda            joy2      
          and            #1        ; up
          bne            chkDown   
          dec            spry      

chkDown   lda            joy2      
          and            #2        ; down
          bne            chkLeft   
          inc            spry      

chkLeft   lda            joy2      
          and            #8        ; left
          bne            chkRight  
          dec            sprx      

chkRight  lda            joy2      
          and            #4        ; right
          bne            chkFire   
          inc            sprx      

chkFire   lda            joy2      
          and            #16       ; fire
          bne            next      
          rts
;         end check joystick          

next
          waitrt
          jmp            main_loop 

exit
          rts                      ; return to BASIC

movedata  ldx            #$0
@loop     lda            jetpac,x  
          sta            $0340,x   
          inx
          cpx            #$3f      
          bne            @loop
          rts

jetpac    bits           ..........BBBB..........
          bits           .........BBB............
          bits           .......B.BB.BBBB........
          bits           .......B.BBB.BBB........
          bits           .......B.BBB.BBB........
          bits           ......BB..BBBBB.........
          bits           ......BB................
          bits           ......B.B.BBBB..........
          bits           ......BBB.B..BB.B.......
          bits           ......B.B.B..BB.B.......
          bits           ......BBB.B....BBBBB....
          bits           ......B.BB.BBBB.........
          bits           ......BBBB.BBB..........
          bits           .......BBBB.BBBBBB......
          bits           .......B.B..BBBBBB......
          bits           ......B.B.B.....BB......
          bits           ......BBBBB.............
          bits           ................BBB.....
          bits           .......BB.B.....BBBB....
          bits           .......B..B.............
          bits           .....B..B...............

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s