Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Sprites en snes

  • Login to see the comments

Sprites en snes

  1. 1. TUTORIAL SNES:USAR SPRITESPor David Senabre, Junio 2005INTRODUCCIÓN Y EL POR QUÉ DE ESTE TUTORIAL.En primer lugar, escribo este tutorial porque no he visto ningúndocumento hasta la fecha que explique adecuadamente como usar spritesen la SNES, ni en español, ni en ingles. Y a mi me ha dado bastantedolores de cabeza lograr usarlos. Hay varios documentos técnicos sobrela SNES muy buenos por internet, como los de Yoshi, pero por ejemplo,este hombre explica a menudo las cosas de una forma muy poco clara. Endefinitiva, hay temas, como el de los sprites, donde la informaciónestá esparcida y a veces es oscura y ambigua.Mi objetivo es explicar con detalle y suficiente claridad, el usosencillo de sprites en la SNES, desde cero y ordenadamente.¿A QUIÉN VA DIRIGIDO?A todo aquel que quiera usar sprites en la SNES, y por supuesto quesepa programar y tenga nociones de ensamblador, aunque no sea deensamblador de la SNES. También se da por sabido conceptos como tile,bitplanes, o WRAM ;)Ah, y también saber qué es un registro y como usarlos.(ver otros tutoriales míos).¿QUÉ SON LOS SPRITES?Creo que esto sobra, pero bueno, hagamos las cosas bien. En un juego,por una parte, están los escenarios, las plataformas, etc. Que formanparte de los planos de scroll, constituidos por tiles, y que sirvenpara representar los niveles, los mapas, o lo que sea, en definitiva,el mundo que se representa en el juego.Y por otra parte están los sprites, que son los objetos móviles que“viven” en ese mundo, tanto los enemigos, como el propio personaje quecontrola el jugador, o los ítems. En definitiva, los sprites son losobjetos que interactúan en los juegos.Por lo tanto es imprescindible saber usarlos, a no ser que queramoslimitarnos a programar demos con fondos, imágenes, texto, y sinacción. Para quien tenga experiencia en programación de la NES,resultará sencillo usarlos en la SNES, aunque aquí la cosa se complicamucho. Yo empezaré a explicarlo todo suponiendo que el lector no tieneesta experiencia previa.LA TABLA DE SPRITES (OAM)Los sprites en SNES se llaman objetos o OAM.Para manejarlos, la SNES tiene una zona de memoria llamada tabla OAMdonde guarda información sobre todos los sprites. En esta tabla caben128 sprites, y por lo tanto la SNES puede manejar un máximo de 128sprites a la vez, aunque seguramente en la practica se ralentice si seusan tantos. Aún así esto supone una mejora, porque la NES sólo podíamanejar 64.Lo que tenemos que hacer es introducir los datos de los sprites enesta tabla. Cada sprite ocupa 4 bytes.Byte 1 : xxxxxxxx Posición X del sprite en la pantalla (0-255)Byte 2 : yyyyyyyy Posición Y del sprite en la pantalla (0-255)Byte 3 : tttttttt Número de tile que representa al spriteByte 4 : vhooppptDe este ultimo byte:
  2. 2. v : mirroring verticalh : mirroring horizontalo : bits de prioridadp : bits de paletat : bit alto de número de tileLos 2 primeros son auto explicativos.Por ahora hablaré de los bits de paleta y de tile.Con el byte 3 decimos que tile se mostrará como sprite. Podemos elegirun tile desde 0 hasta 255. Pero el bit t del byte 4 también vale paraelegir el tile, y de hecho es el bit más significativo de estadirección, luego:Bit t del byte 4 = 0 Byte 3 elige un tile de 0 hasta 255Bit t del byte 4 = 1 Byte 3 elige un tile de 256 hasta 511Luego diré como saber qué tile es el 127 o el 63.Por ahora añadir que los bits p sirven para elegir la paleta delsprite, de entre 8 (ya que tenemos 3 bits para ello).PALETAS Y COLORES.Recuerdo que la paleta de la SNES es una lista de colores que sealmacenan en una memoria de la SNES, la CG-RAM, que guarda todos loscolores que se pueden mostrar por pantalla en un momento dado, y quese carga por el programador con los colores que se quiera. Estoscolores se reverencian por el orden que ocupan en esta lista, desde el0, hasta el 255.Los colores que se usan en los sprites son los que van del 128 enadelante (es decir, los que vienen después de los primeros 128).Los sprites usan 16 colores. Por lo tanto, si a un sprite le ponemospaleta 0, los 16 colores que se usarán para él serán los que van del128 al 143, y si escoges la paleta 1, los 16 siguientes, etc.CARGAR LA TABLA DE SPRITES (OAM)Bueno, ahora que ya sabemos esto, es el momento de aprender a meteresta información en la tabla de sprites.La tabla de sprites ocupa 512 bytes (4 bytes por 128 sprites), quesirven para almacenar la información ya explicada, pero esta tabla alfinal tiene otros 32 bytes que sirven para otras 2 cosas; para hacerde noveno bit en la posición X de los sprites, y para elegir el tamañodel sprite entre 2 posible. Pero de momento estos 32 bytes lospondremos a cero. Con esto seleccionaremos el tamaño por defecto, y noafectaremos a la posición X del sprite dada con antelación.Esta tabla se carga usando los registros $2102, $2103, $2104.Los dos primeros sirven para dar la dirección del sprite en la tabla,y el tercero sirve para escribir en esa dirección el byte deseado.Cuando inicialicemos la consola, en nuestra rutina de arranque, seríabueno que llenáramos la tabla de sprites de ceros. Esto se puede hacermuy fácilmente usando DMA.La siguiente rutina sirve perfectamente. Como necesitamos llenar latabla con ceros, yo lo que hago es copiar a la WRAM el valor cero enalguna posición de memoria, y luego copiar el contenido de esaposición a la tabla OAM.En este ejemplo usaré la dirección $0020. Se puede usar otra direcciónsin problemas. Fijarse que en el registro $4300 de DMA se selecciona
  3. 3. dirección fija (Fixed address), para que siempre se transfiera elmismo byte, que es lo que nos interesa.Las opciones que hay que usar para trasnferir a la tabla OAM usandoDMA son:- CPU memory -> PPU- Absolute addressing- 1 address write twice, o 1 address write once- Transferir al registro $2104Y además, en esta ocasión, como es para llenar todo su contenido de unmismo valor:- Fixed addressNo olvidar resetar la dirección de la tabla OAM antes de copiar.;--------------- LDX #$0 STX $2102 ; empezar desde el comienzo de la tabla OAM LDY #$0408 ; transferir al registro $2104 STY $4300 ; con dirección fija LDY #$0020 ; desde la dirección $20 STY $4302 ; que almacena el valor cero LDY #544 ; transferir 544 bytes para llenar la tabla STY $4305 LDA #$7E ; seleccionar banco de origen, STA $4304 ; el banco 7E, comienzo de la WRAM. LDA #$01 STA $420B ;hacer DMA!;---------------Listo, ya tenemos la OAM llena de ceros, incluida la tabla de 32bytes.¿Y LOS TILES?Hasta ahora todo va bien, pero aunque en la tabla OAM tengamosnuestros sprites danzando, no veremos nada en la pantalla.Para que todo esto funcione necesitamos almacenar en la VRAM los tilesque usarán los sprites, y decirle a la SNES en qué posición de memoriaempiezan estos tiles. Estos tiles deben usar 4 bitplanes, para ofrecer16 colores. Por lo tanto cada uno ocupará 32 bytes (tiles de 8x8 = 64pixels, a 4 bits por píxel, 256 bits, que son 32 bytes). El tile 0 esel primero, el tile 1, el que está en el offset 32, el tile 2, en eloffset 64, y así sucesivamente.Procedamos a definir la dirección base de estos tiles. Para ellonecesitaremos el registro $2101, que me ha dado casi todos losproblemas que he tenido con sprites.$2101: sssnnbbbLos bits b definen la dirección base de comienzo en VRAM de los tilesque usaremos en nuestros sprites. Esta dirección se da en bloques de8k palabras (o sea, de 16Kb).Por ello, si ponemos los bits b a 010 (2), estaremos dando ladirección 2*8k palabras, $4000(w), o lo que es lo mismo, la dirección$8000 en bytes de la VRAM, aunque es mejor acostumbrarse a usar lasdirecciones en palabras de 16 bits cuando nos referimos a la VRAM, enlugar de en bytes. Como la VRAM tiene una capacidad de 32k palabras(64Kb), si la partimos en bloques de 8k palabras veremos que sólo hay4 posibles posiciones donde colocar los tiles de los sprites.
  4. 4. En palabras, las posibles zonas de VRAM para sprite tiles son:VRAM bits b------------------------------------| $0000-1FFF | 000 |------------------------------------| $2000-3FFF | 001 |------------------------------------| $4000-5FFF | 010 |------------------------------------| $6000-7FFF | 011 |------------------------------------Para qué sirve el bit más significativo lo ignoro. Por ahora, loconsidero siempre cero.Los bits n sirven para seleccionar una dirección base distinta dentrode la que hemos seleccionado. Cuando un tile tiene un indice 256 omayor, a la dirección base se le suma la seleccionada en los bits n,que definen un desplazamiento en bloques de de 1k palabra.Por ejemplo, si elegimos los bits b 010, seleccionamos el bloque------------------------------------| $4000-5FFF | 010 |------------------------------------Pero si hacemos los bits n 01, para tiles de indice mayor que 255, esdecir, los que ocupan posiciones a partir de $5000 (la mitad delbloque), la dirección base pasará a ser:$5000 + 400 = $5400 (se le suma un bloque de 1k palabra)Y análogamente, para bits 10 y 11, tendremos:$5000 + 800 = $5800 (se le suma dos bloquess de 1k palabra)$5000 + 1000 = $6000 (se le suma tres bloques de 1k palabra)Esta técnica es muy útil para crear sprites animados de 4 frames, deuna forma sencilla. Basta con colocar los tiles de esos sprites enposiciones 256 y superiores, y variar los bits n cada par de frames.Así, se irán eligiendo los tiles en posiciones separadas por 1kpalabra de forma ciclica.ACTIVAR SPRITESAhora tenemos que definir el modo gráfico en el que vamos a trabajar,activar los planos de scroll que vayamos a usar, y activar lossprites.En primer lugar definimos modo1, por ejemplo, que es uno de los mássencillos para aprender. Este modo tiene disponible 3 planos descroll, el BG1, el BG2 y el BG3. Los dos primeros usan 16 colores(tiles de 4 bitplanes), y el BG3 de 4 colores unicamente (tiles de 2bitplanes). El registro para seleccionar modo es el $2105, en concretosus 3 bits menos significativos.
  5. 5. $2105: abcdefffLos bits f son los bits de modo que acabo de decir.Del bit a, al d, sirven para seleccionar el tamaño de los tiles de losplanos BG4 al BG1 (0=8x8, 1=16x16). Yo nunca he usado tiles que nosean de 8x8 así que no daré más información.El bit e sirve para dar máxima prioridad al BG3 en modo1. Por ahora nolo usaremos tampoco.;-----------------------lda #$01 ;mode 1, 8x8 tiles (16 colores para BG1 + BG2 y 4 para BG3)sta $2105;-----------------------Y para activar los planos de scroll que queramos, al igual que lossprites, está el registro $212C$212C: 000abcdeLos 3 bits altos no se usan.El bit a se refiere a los sprites.El bit b al BG4El bit c al BG3El bit d al BG2El bit e al BG1Un bit a 1 significa activado, a 0, desactivado.;-----------------------lda #$17 ;Activar todos los planos del modo 1, y spritessta $212C;-----------------------ACTUALIZAR LA TABLA OAMHemos aprendido a resetar la tabla de sprites. Ahora vamos a necesitarllenar esta tabla con información correcta sobre cada sprite, de suposición, tile y atributos. Esto lo haremos de la siguiente manera.En primer lugar, designaremos una zona de memoria donde almacenaremosnuestra tabla de forma temporal, y durante la rutina de refresco depantalla, copiaremos esta tabla temporal a la tabla OAM, usando DMA,como antes.Por ejemplo, dediquemos la zona de WRAM $0040-$25F a almacenar nuestratabla temporal.;---------------.DEFINE Sprites $40 ;544 bytes, $220;---------------Con el identificativo Sprites, designaremos el offset de inicio.Ahora debemos ir copiando aquí la información que se transferirá a latabla OAM cada frame, en el mismo formato claro, y dejando los últimos32 bytes a cero de momento. Los primeros 512 bytes estarán disponiblespara usar hasta 128 sprites. Por ejemplo, añadamos un sprite en laposición X = 16, Y = 191, que use el tile $80, paleta cero, y sinatributos de prioridad o mirroring. Este será nuestro sprite cero,luego lo copiamos al inicio de nuestra tabla en WRAM, por ejemplo dela siguiente forma:
  6. 6. ;--------------- LDY #$BF10 STY Sprites + 0 LDY #$0080 STY Sprites + 2;---------------Y si queremos un segundo sprite, a continuación.;--------------- LDY #$B710 STY Sprites+4 LDY #$0081 STY Sprites+6;---------------Etc.Lo que resta es volcar esta tabla temporal a la tabla OAM cadarefresco de pantalla, como hacemos con el resto de planos de scroll,por ejemplo, y esto se hace fácilmente usando DMA, y una rutina casiidéntica a la de inicialización de antes, sólo que ahora usaremos comodirección origen la dirección de nuestra tabla temporal, y no se usarádirección fija (Fixed address), sino autoincremento, para ir copiandouno tras otro todos los bytes de la tabla temporal. Es decir,seleccionar:- CPU memory -> PPU- Absolute addressing- 1 address write twice, o 1 address write once- Transferir al registro $2104- Auto address inc/decrement.- Automatic increment. ;--------------- LDX.w #$0 STX $2102 ; resetar la dirección de la tabla OAM LDY #$0400 ; copiar al registro $2104 (OAM) STY $4300 ; incrementar dirección LDY #Sprites ; copiar desde el inicio de nuestra STY $4302 ; tabla temporal LDY #544 STY $4305 ; numero de bytes LDA #$7E ; banco 7E, primer banco de la WRAM STA $4304 ; LDA #$01 STA $420B ; DMA!;---------------También se puede copiar manualmente, sin usar DMA. Es muy sencilloPERO ojo, hay que usar un registro de 8 bits para la transferencia uobtendrás resultados indeseables. Esta rutina funciona perfectamente,y es equivalente a la anterior:;---------------LDX.w #$0STX $2102 ; resetear dirección OAMSEP #$20 ; el registro A debe estar configurado en 8 bits LDY #$00CopySpr: LDA Sprites, Y STA $2104 INY CPY #544
  7. 7. BNE CopySpr;---------------Con esto doy por concluído el tutorial. Creo que con esta informaciónno será problema meter un par de sprites que revoloteén por ahí, y denalegría a un frío plano de scroll ;)Dejo para más adelante el uso de sprites de más de 8x8 pixels, y otrascosillas más avanzadas.CUADRO RESUMEN:1º copiar los tiles que usarán los sprites a un dirección de VRAM.Esta tiene que ser una de las siguientes.VRAM bits b------------------------------------| $0000-1FFF | 000 |------------------------------------| $2000-3FFF | 001 |------------------------------------| $4000-5FFF | 010 |------------------------------------| $6000-7FFF | 011 |------------------------------------2º Establecer la dirección base de estos tiles en el registro $21013º Seleccionar modo gráfico en el registro $21054º Activar los sprites en el registro $212C5º Limpiar la tabla OAM6º Cada refresco de pantalla actualizar la tablaMucha suerte.

×