Sprites, BOBs  y otras criaturas mágicas (VI): SPRITES

 

Después de dar un buen repaso al funcionamiento del Blitter, durante las tres últimas entregas, vamos a dedicar este sexto capítulo de ‘Sprites, BOBs y otras criaturas mágicas’ a describir en detalle el otro gran mecanismo del que disponemos en Amiga para mostrar un elemento gráfico en pantalla: los sprites hardware.

 

Dedicado, con cariño, a todos mis amigos atarianos.

 

Características y limitaciones

En este punto, aprovecho para recomendaros que volváis a echar un vistazo a la primera entrega de esta serie. De todas formas, para los más vagos, aquí os dejo de nuevo la definición de sprite:

Sprite: no se dibujan sobre la memoria de vídeo, sino que se trata de elementos que se muestran de manera independiente y que, según un sistema de prioridades, pueden aparecer por delante o por detrás de los bitplanes.”

Así pues, la principal característica de los sprites hardware es que no “manchan” el fondo, por lo que no es necesario salvarlo (ni restaurarlo a posteriori), como sí ocurría con los BOBs. Es el propio hardware de vídeo el que “superpone” los sprites para que aparezcan en el resultado final, pero sin interferir para nada en el contenido de los bitplanes.

En Amiga disponemos de 8 sprites hardware (numerados del 0 al 7), cada uno de los cuales puede tener un ancho máximo de 16 pixels y un alto ilimitado. Además, podemos emplear los 8 sprites de manera independiente, en cuyo caso cada uno de ellos podrá mostrar un máximo de 4 colores (en realidad, 3 + transparente) o agrupados por parejas preestablecidas, cada una de las cuales podría mostrar 16 colores (15 + transparente). En este último caso, por supuesto, ambos sprites tienen que estar situados en la misma posición. Los colores reservados para los sprites son los que ocupan las posiciones 16 a 31 en la paleta. En el caso de emplear sprites individuales, estos 16 colores se agrupan de 4 en 4 y se reparten entre parejas de sprites, de la siguiente manera:

 

Uso de la paleta para sprites individuales.

 

Por el contrario, si agrupamos cualquiera de estas parejas de sprites para que funcionen como uno solo de 16 colores, dicha pareja podría emplear el rango completo, del 16 al 31, siendo el 16 el color transparente. Es posible combinar ambos modos de funcionamiento, por ejemplo:

● Los sprites 0 y 1, 2 y 3 y 4 y 5 de forma individual, mostrando cada pareja los 3 colores que le correspondan según la tabla anterior.
●Los sprites 6 y 7 agrupados, mostrando 15 colores, del 17 al 31.

 

Propiedades y datos de un sprite

¿Cómo especificamos tanto las propiedades como los datos asociados a un sprite hardware concreto? Simplemente tenemos que montar una estructura en la que tendremos 3 partes: cabecera (o palabras de control), datos y pie:

 

Estructura de datos de un sprite.

 

En la cabecera hemos de especificar las coordenadas X e Y del sprite, así como el alto del mismo, indicando la coordenada Y que iría justo tras finalizar el sprite. Nótese que no es necesario especificar el ancho, puesto que éste siempre será de 16 pixels. Además, en caso de sprites emparejados, hemos de indicarlo en la cabecera del sprite impar de la pareja.

Tras la cabecera vendrán los datos de la imagen que queremos mostrar con ese sprite hardware. El formato en este caso es como el que ya vimos en la primera entrega dedicada al Blitter: planar interleaved. Es decir, vamos especificando de manera sucesiva cada una de las líneas (de 16 pixels), indicando primero el plano 0 y después el plano 1. En el caso de sprites emparejados, el sprite de índice más bajo de la pareja (que siempre será par) proporcionará los planos 0 y 1, mientras que el de mayor índice (el impar) contendrá los planos 2 y 3, conformando así los 4 planos necesarios para codificar los 16 colores. Ejemplo: si emparejamos los sprites 0 y 1, el primero contendrá los dos primeros planos de la imagen, mientras que el segundo contendrá los dos siguientes.

Por último, en el pie, una secuencia de 32 bits a 0 (2 palabras de 16) dará por finalizada la definición del sprite.

A modo de ejemplo, vamos a ver cómo montaríamos la estructura de datos necesaria para mostrar la imagen del Lemming que ya vimos hace algunos capítulos, pero esta vez empleando el sprite 0, en lugar del Blitter:

 

Tu cara me suena…

 

Como veis, en la cabecera estamos indicando que queremos posicionar el sprite en las coordenadas (0, 0), es decir, en la esquina superior izquierda de la pantalla. Además, como el alto de la imagen es de 9 líneas, ésta llegará hasta la línea 8. Tal y como comenté previamente, sin embargo, en la cabecera especificamos la línea siguiente a aquélla en la que acabará el sprite, en este caso, la 9. A continuación, los datos del sprite en formato planar interleaved. Hay que tener en cuenta que, dependiendo del sprite que estemos empleando, el hardware sumará 16 (sprites 0 y 1), 20 (sprites 2 y 3), 24 (sprites 4 y 5) o 32 (sprites 6 y 7), de manera automática, para convertir el número del 0 al 3 proporcionado por los dos planos al índice correcto de la paleta. En nuestro caso, estamos empleando el sprite 0, así que el hardware sumará 16 a cada índice para obtener un color entre el 16 y el 19. Para sprites emparejados, los 4 planos que los conforman nos darán valores del 0 al 15, a los que el hardware siempre sumará automáticamente 16 para obtener un color dentro del rango 16-31. Por ejemplo, ésta es la forma en la que los datos de la línea 1 se convierten en los correspondientes colores de la paleta.

 

Traducción de una línea del sprite a colores de la paleta.

 

Reutilización de sprites

Por lo que hemos visto hasta ahora podría dar la impresión de que, en un momento dado, sólo es posible mostrar una imagen con cada uno de los 8 sprites hardware de los que dispone el Amiga. Nada más lejos de la realidad:

 

Ejemplo de reutilización de sprites.

 

En este ejemplo hay un total de 40 imágenes, que se muestran simultáneamente empleando los 8 sprites hardware, de forma que cada uno de ellos se reutiliza 5 veces durante cada frame. Al contrario de lo que podría parecer, en este caso, no se trata de una técnica avanzada, ni de un truco sino, simplemente, de ampliar en cierto modo lo que ya sabemos. Para reutilizar un sprite hardware durante el pintado de un frame, lo único que tenemos que hacer es ir repitiendo sucesivamente una secuencia de cabecera + datos y sólo incluir el pie tras el último uso del sprite:

 

Estructura de datos para reutilización de un sprite hardware.

 

Los únicos requisitos son que la lista esté ordenada por coordenada Y ascendente y dejar al menos una línea entre el final de un uso y el principio del siguiente. Si no hacemos esto veremos que hay sprites que desaparecen o, en el mejor de los casos (y sólo si lo hemos implementado así), parpadean. Dicho de otra manera, el límite estaría en un máximo de 8 sprites por línea, para evitar tener efectos indeseados como los que acabo de comentar. Cuando reutilizamos un sprite hardware no sólo podemos mostrar repetidamente la misma imagen en diferentes posiciones (como en el ejemplo que vimos anteriormente), sino que es posible que cada uso del sprite muestre una imagen distinta, por supuesto. La limitación en ese sentido estaría en el hecho de que dichas imágenes compartan la misma paleta, puesto que la del sprite permanecerá fija. O… aplicando vuestros ya amplios conocimientos sobre el Copper, podríais usarlo para hacer los cambios de paleta necesarios para cada uno de los diferentes usos del sprite. Hay que tener en cuenta que, como hemos visto, la paleta no es exclusiva de un sprite sino que se comparte por parejas (en caso de sprites de 3 colores). Por último, también sería posible que algunos de los usos del sprite fueran sin emparejar (3 colores) y otros emparejados (15 colores).

Sólo como apunte, porque es posible que vuelva a salir en próximos capítulos, quisiera terminar comentando que los sprites hardware pueden emplearse de 2 formas:

DMA: acceso directo a memoria, básicamente es lo que hemos visto hasta ahora, empleando listas que el hardware lee para saber cómo y cuándo debe mostrar cada sprite.
Manual: prescindimos de las listas y somos nosotros los que nos encargamos directamente de ir cargando la información necesaria en cada uno de los sprites hardware.

 

Conclusión

Los sprites hardware son un mecanismo muy potente que, en combinación con los BOBs, deberían permitirnos dar vida a cualquier elemento gráfico que podamos necesitar en un juego o una demo. La clave, como siempre, está en conocer sus virtudes y limitaciones para que podamos decidir en qué circunstancias usarlos.

 

 

Un artículo publicado por:

Fernando Cabrera (@fcabrera_77)
Ingeniero informático. Nostálgico del Spectrum, adorador del Amiga y aficionado a los videojuegos y a la retro-informática. Ahora también Colaborador desde mi sección para Commodore Spain. 

 

 

 

 

 

7 Comentarios sobre “Sprites, BOBs y otras criaturas mágicas (VI): SPRITES

  1. tolkien

    Me encanta…. Ya lo sabes nandius. Siempre muy bien esplicado, muy claro. Solo puedo dar las gracias. Me va a venir muy bien.

  2. Spiral World

    Fer, tú tendrias que hacer un libro pero ya xDD
    Un gustazo leerlo, que siempre aprendo y algo retendré…digo yo . :))

  3. Fernando Cabrera

    Muchas gracias por los comentarios, continuará! 😉

  4. colpasus

    Grande Fer!

    Pues muy interesante, como te decía hace algún tiempo ojalá que hubiera tenido estos manuales al principio de empezar mi proyecto jejej.

    Aplicaré el método de reusar los sprites en algún proyecto seguro, ya te enseñaré 😉

    Por cierto y a ver si te suena, ¿es posible que el Amiga 500 tuviera algún problema con los sprites 6,7 y 8 por los que en algunas condiciones cuando la cpu está muy cargada no se muestran en pantalla?
    Me está pasando en el juego que estoy haciendo y buceando en la documentación original del hardware habla de que puede ocurrir por los ciclos de la CPU que tiene reservados para usar el DMA. A ver si encuentro donde lo leí y te lo muestro.

    Yo sólo uso los 5 primeros sprites por este problema, tampoco necesitaba más pero la verdad es que me llevó mucho tiempo de pruebas pensando que era un tema mío.

    Bueno, sigue con estas guías. ¿vas a escribir algo del control de colisiones por hardware? estaría genial.

    Un saludo compi.

    • Fernando Cabrera

      Buenas colpasus,

      muchas gracias por tu comentario :). Tu duda está directamente relacionada con el que me gustaría que fuera el tema del siguiente artículo: el DMA. Para simplificar, te diré que, en función del momento en el que empiecen a leerse los datos para cada línea de la pantalla, podrían quedar anulados (total o parcialmente) algunos de los sprites hardware, empezando por el último (el 7) y en orden descendente. El registro clave para esto es el DDFSTRT (data fetch start). Por ejemplo, si DDFSTRT < $38 estarás empleando los slots de DMA correspondientes al sprite 7 para leer datos de la pantalla, por lo que dicho sprite no se mostrará correctamente.

      Más detalles en el Amiga Hardware Reference Manual… o, mucho mejor, en el próximo artículo! 😉

      Un saludo!

  5. freshko

    Muy buenos artículos. Ahora que me reencuentro con el Amiga, los aprovecharé.
    Por cierto, la idea del libro estaría bien. (Interested)

    • Fernando Cabrera

      Gracias! 🙂 Lo del libro lo veo complicado, pero artículos seguiré sacando mientras haya gente interesada como tú ;).

Deja un comentario

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

clear formSubmit