[Homebrew] [VDP1] - Controlando Sprites.


Ir a la página 1, 2  Siguiente

Objetivo: [Homebrew] [VDP1] - Controlando Sprites.
Tomando en cuenta lo básico para alimentar el espíritu, vamos a ver los ansiados Sprites.



Para comenzar:

  • Nivel de dificultad: fácil.
  • Lenguaje: ANSI C/C++.
  • Herramientas: SaturnOrbit, 3Deditor



Copiamos el ejemplo S_2_2 de la carpeta C:SaturnOrbitSGL_302jSAMPLE en la raiz del disco C: ó donde quieran.

Cambiamos las rutas necesarias para que compile, si no sabes como hacerlo aca podes ver el como.




Lo que tenemos que saber, es que existen dos formas de tomar datos en Sega Saturn, ó lo hacemos levantando un binario desde el directorio del CD ó
lo incluimos dentro del main.c . Nosotros vamos a ver la segunda opción.

En Sega Saturn, las texturas y los sprites son considerados la misma cosa.

Vamos a prepartar los datos necesarios.

Utilizando la herramienta 3Deditor dentro del SegaSaturnSDK (C:SaturnOrbitTOOLSSSSDK) .
La abrimos, vamos a View y tildamos texture list.

vdp1_1

Antes debemos saber que todas las imagenes deben ser multipo de 8, tanto en x como en y. En mi caso son todas de 48x48.

Normalmente los estandares para estas consolas son de 16x16,32x32 ó 64x64.
El color usado como transparencia, es el 0x0000 osea el negro. Por lo tanto todo sprite que tenga este color lo debes cambiar por 0x8000 así de esta forma se verá.

Como mis sprites tiene este color los voy a reemplazar uno por uno por 0x8000, usen algun editor de texto, sino va a largar todo por la ventana :P .
Luego para obtener las tranparencias, yo utilize el Magenta (es horrible) que es el color 0xfc1f a este lo cambio por el 0x0000 (que es el que Saturn no pinta).


Vamos a File, Import y seleccionamos las imagenes que queremos.

vdp1_2

Guardamos el archivo con formato .TXR; en mi caso SonicX.TXR

Un Archito TXR tiene las siguientes estructuras:
  • Uint16 texture_SonicX000[] : Son los datos de los colores, pixel por pixel en 15bits.

  • TEXTURE tex_SonicX[] : Es la tabla con las sprites/texturas medidas en bytes.

  • PICTURE pic_SonicX[]: Es la tabla sprites/texturas determinando el color de cada uno de los sprites. Podemos utilizar distintos tipos de colores por cada uno.

  • SPR_ATTR attr_SonicX[] : Aca van los atriburos de los sprites, esta tabla la tenemos que escribir a mano, todos los sprites son llamados desde esta tabla, ademas podemos especificar si tiene flip, grourad y paleteado.





En mi caso tengo dos tablas, una con los Datos originales, y otra con los invertidos (con flip horizontal)

Les dejo las talbas que deben pegar donde quiera, yo las pegue junto al SonicX.TXR


Uint16 texture_SonicX000[] = {}

........
Uint16 texture_SonicX010[] = {}

TEXTURE tex_SonicX[] = {}

TEXTBL( 48, 48, CGADDRESS+0),
TEXTBL( 48, 48, CGADDRESS+4608),
..............
TEXTBL( 48, 48, CGADDRESS+46080),
};

PICTURE pic_SonicX[] = {
PICTBL( 0, COL_32K, texture_SonicX000),
...........
PICTBL( 10, COL_32K, texture_SonicX010),
};

SPR_ATTR attr_SonicX[] = {
SPR_ATTRIBUTE(0,No_Palet,No_Gouraud,CL32KRGB|SPenb|ECdis,sprNoflip),
............
SPR_ATTRIBUTE(10,No_Palet,No_Gouraud,CL32KRGB|SPenb|ECdis,sprNoflip),
};

SPR_ATTR attr_SonicX_flip[] = {
SPR_ATTRIBUTE(0,No_Palet,No_Gouraud,CL32KRGB|SPenb|ECdis,sprHflip),
.............
SPR_ATTRIBUTE(10,No_Palet,No_Gouraud,CL32KRGB|SPenb|ECdis,sprHflip),
};



Una vez que tenmos todo esto listo, vamos a comenzar con el codigo
primero debemos inlcuir en nuestro main.c el archivo SonicX.TXR

#include "SonicX.txr"

Ahora necesitamos inicializar la lista con los sprites/texturas.

slInitSystem(TV_320x240, tex_SonicX , 1);

Luego necesitamos copiar los sprites/texturas a la memoria del VDP1.
Con la siguiente función (la extraje de un ejemplo) copiamos los sprites a la memoria, asi que debemos incluirla en el main.c .


static void set_sprite(PICTURE *pcptr, Uint32 NbPicture, TEXTURE *texptr)
{
TEXTURE *txptr;

for(; NbPicture-- > 0; pcptr++){
txptr = texptr + pcptr->texno;
slDMACopy((void *)pcptr->pcsrc,
(void *)(SpriteVRAM + ((txptr->CGadr) << 3)),
(Uint32)((txptr->Hsize * txptr->Vsize * 4) >> (pcptr->cmode)));
}
}


Para llamar a esta funcion le pasamos los parametros correspondientes

set_sprite(pic_SonicX, 11, tex_SonicX);


El segundo parametro indica, la cantidad de sprites/texturas que tenemos, si te equivocas, el sistema va a leer una posición erronea y se va a corromper algun sprite (lo vas a ver feo).


Ahora vamos a mostrar dentro del bucle while los sprites. Los sprites se deben mostrar siempre y debe existir la función slSynch() para sincronizar con el sistema.

Según los manuales hay varias funciones para mostrar sprite, vamos a ver la más simple.


slDispSprite(FIXED pos, SPR_ATTR *atr, ANGLE Zrot);


El primer parametro es un vector, de cuatro componentes que indican, X,Y,Z y S que es la escala.
El segundo es la tabla que tuvimos que escribir a mano, le tenemos que pasar la variable más el número de sprite que queremos mostrar.
El Tercero, es el angulo de rotación en la que se va a mostrar.

Por ejemplo para ver el escudo re River Plate :twisted: :

El Sprite de River es el numero 11, pero como comienza de 0, entonces es el 10.

FIXED pos_river[XYZS] = {toFIXED(60.0), toFIXED(60.0), toFIXED(169), toFIXED(1.0)};
ANGLE ang_river = DEGtoANG(0.0);
slDispSprite(pos_river, attr_SonicX + 10, ang_river);



Ahora ponemos una variable para que paresca un sprite y no una imagen estática.

Uint32 sprite_walk_ID=0;
Uint32 sprite_running_ID=6;


Estas son para Sonic caminando y corriendo respectivamente. En cada ciclo debemos incrementar el número, pero también controlar que no se pase, sino va a mostrar otros sprites y no queremos eso :wink: .

Entonces cada vez que se pase, lo volvemos al inicio:

if(sprite_walk_ID>=5)
{ sprite_walk_ID=0;
}
if(sprite_running_ID>=9)
{ sprite_running_ID=6;
}



Con Sonic caminando muestro los sprites usando la primera trabla que creé.

slDispSprite(pos1, attr_SonicX + sprite_walk_ID, ang1);

Con Sonic corriendo muestro los sprites usando la segunda trabla (la invertida).

slDispSprite(pos2, attr_SonicX_flip + sprite_running_ID, ang1);

Todo esto me sirve para ahorrar memoria y no tener que cargar los sprites invertidos.




Les paso el código del main.c


#include "sgl.h"
#include "SonicX.txr"

static void set_sprite(PICTURE *pcptr, Uint32 NbPicture, TEXTURE *texptr)
{
TEXTURE *txptr;

for(; NbPicture-- > 0; pcptr++){
txptr = texptr + pcptr->texno;
slDMACopy((void *)pcptr->pcsrc,
(void *)(SpriteVRAM + ((txptr->CGadr) << 3)),
(Uint32)((txptr->Hsize * txptr->Vsize * 4) >> (pcptr->cmode)));
}
}

void ss_main(void)
{
static ANGLE ang[XYZ];
static FIXED pos[XYZ];
//Inicializamos el sistema con los sprites----------------------------
slInitSystem(TV_320x240, tex_SonicX , 1);

//Pintamos el fondo de color azul, asi comprobamos que el negro se ve.
slBack1ColSet((void *)BACK_CRAM, CD_Blue);

//Cargamos al VDP1 los sprites----------------------------------------
set_sprite(pic_SonicX, 11, tex_SonicX);
slPrint("VDP1 - Sprite Manipulation", slLocate(9,2));
slPrint("www.segasaturno.com", slLocate(9,3));
slPrint("Jano Dev Team - FacundoARG",slLocate(12,28));

FIXED pos1[XYZS] = {toFIXED(-60.0), toFIXED(0.0), toFIXED(169), toFIXED(1.0)};
ANGLE ang1 = DEGtoANG(0.0);

FIXED pos2[XYZS] = {toFIXED(60.0), toFIXED(0.0), toFIXED(169), toFIXED(1.0)};

FIXED pos_river[XYZS] = {toFIXED(0.0), toFIXED(0.0), toFIXED(169), toFIXED(1.0)};
ANGLE ang_river = DEGtoANG(0.0);

//Para usar con el escudo de River Plate
pos[X] = toFIXED( 0.0);
pos[Y] = toFIXED( 0.0);

Uint32 sprite_walk_ID=0;
Uint32 sprite_running_ID=6;

while(-1){

if((Per_Connect1) == 0)
{slPrint("No conectaste el PAD",slLocate(2,20));}

//Pintamos los sprites.----------------------------------------
slDispSprite(pos1, attr_SonicX + sprite_walk_ID, ang1);
slDispSprite(pos2, attr_SonicX_flip + sprite_running_ID, ang1);
slDispSprite(pos_river, attr_SonicX + 10, ang_river);

//Incrementamos la posicion en la tabla-------------------------
sprite_walk_ID++;
sprite_running_ID++;

if(sprite_walk_ID>=5)
{ sprite_walk_ID=0;}

if(sprite_running_ID>=9)
{ sprite_running_ID=6;}

Uint8 index=0;
//Controlando KEY-PAD------------------------------
if( (Smpc_Peripheral[index].data & PER_DGT_KU) == 0)
{ pos[Y] = pos[Y] - toFIXED( 5.0);
pos_river[Y] = pos[Y];
}
if( (Smpc_Peripheral[index].data & PER_DGT_KR) == 0)
{ pos[X] = pos[X] + toFIXED( 5.0);
pos_river[X] = pos[X];
}
if( (Smpc_Peripheral[index].data & PER_DGT_KD) == 0)
{ pos[Y] = pos[Y] + toFIXED( 5.0);
pos_river[Y] = pos[Y];
}
if( (Smpc_Peripheral[index].data & PER_DGT_KL) == 0)
{ pos[X] = pos[X] - toFIXED( 5.0);
pos_river[X] = pos[X]; }

if( (Smpc_Peripheral[index].data & PER_DGT_TL) == 0)
{ang_river = ang_river - DEGtoANG(5.0);}

if( (Smpc_Peripheral[index].data & PER_DGT_TR) == 0)
{ang_river = ang_river + DEGtoANG(5.0);}

slSynch();
}
}

última edición por FacundoARG el 10 Agosto 2009, 12:35 AM; editado 2 veces
Perfil MP  
Objetivo: Re: [SaturnBrew] - VDP1 - Controlando Sprites.
Muchisimas gracias por despejarme las dudas que tenia sobre el tema , haber si tarde o temprano hago algo aunque sea un microjuego o similar xD sigue asi Facundo, fijate que fallo mas tonto , no me cargaba parte de los sprites por no contar el sprite 0 al decirle cuantos tenia en la tabla xD en fin , con lo que no soy capaz de ninguna de las maneras es con la carga de backgrounds o fondos ... eso es el infierno. Lo de los TGA , los Bin y los C me tiene loco...

Perfil MP  
Objetivo: Re: [SaturnBrew] - VDP1 - Controlando Sprites.
Oye Facundo (y para todo el que se anime) te dejo un codigo y una iso , en el emulador a mi me deja estela , comentame si te deja estela y si lo hace mirate el codigo haber si esta todo bien

Perfil MP  
Objetivo: Re: [SaturnBrew] - VDP1 - Controlando Sprites.
Jean La Montarde escribió: [Ver mensaje]
Oye Facundo (y para todo el que se anime) te dejo un codigo y una iso , en el emulador a mi me deja estela , comentame si te deja estela y si lo hace mirate el codigo haber si esta todo bien


Tu ejemplo me funciona perfecto. Debe ser tu emulador, probalo con sff.

Despues subo un tuto para usar el Background N1. Es muy sencillo.

Perfil MP  
Objetivo: Re: [SaturnBrew] - VDP1 - Controlando Sprites.
OK ,la puñeta es que ya estoy usando SFF probare con otros, por cierto , ¿Subiste la ISO del ejemplo que has hecho tu? Así veo como se ve en mi emu por si no encuentro solución

Perfil MP  
Objetivo: Re: [SaturnBrew] - VDP1 - Controlando Sprites.
Jean La Montarde escribió: [Ver mensaje]
OK ,la puñeta es que ya estoy usando SFF probare con otros, por cierto , ¿Subiste la ISO del ejemplo que has hecho tu? Así veo como se ve en mi emu por si no encuentro solución


Ya la subí, fijate como te funciona. No se si te habias dado cuenta, pero no tiene control de frame.
Es algo que estoy investigando, así que se va a ver muy rápido.

En el video se ve más lento porque no captura a 60pfs.

Perfil MP  
Objetivo: Re: [VDP1] - Controlando Sprites.
Probado , no se que puñetas le pasa al SSF pero todas las animaciones 2D tienen estela y luego las 3D no da problemas, en fin que cosa mas rara

Perfil MP  
Objetivo: Re: [VDP1] - Controlando Sprites.
Una cuestion sencilla de cara al futuro, si en el ejemplo que has puesto tu todos los sprites tienen la misma coordenada Z ¿Porque el escudo de River se pone por delante de los sprites de Sonic al moverlo por delante?¿Si pinto dos sprites en la misma posicion cual se vera por delante?

Perfil MP  
Objetivo: Re: [VDP1] - Controlando Sprites.
Jean La Montarde escribió: [Ver mensaje]
Una cuestion sencilla de cara al futuro, si en el ejemplo que has puesto tu todos los sprites tienen la misma coordenada Z ¿Porque el escudo de River se pone por delante de los sprites de Sonic al moverlo por delante?¿Si pinto dos sprites en la misma posicion cual se vera por delante?

Que buena pregunta que acabas de hacer, es porq' tambien existe el orden de pintado, el escudo de River se pinta al último.
Para que no se interfieran, imaginate si se pintasen igual, la maquina no sabria que pintar, y si lo hiciese haría algo extraño o un cliping.

Perfil MP  
Objetivo: Re: [VDP1] - Controlando Sprites.
Resultado de la fusion de tutoriales :P a este paso cuando termines los tutos tendre un juego xDDD


YouTube Link


Una pregunta que al menos no me ha quedado clara, en el ultimo ejemplo , para poder meter los sprites con flip (invertidos horizontalmente) tendria que haber cambiado la tabla desde la que el sistema accede al sprite a para la funcion sldispsprite(posicion,tabla,angulo) problema , no me deja con variables ni nada similar asi que al final he tirado por en medio y he metido en el sprite.txr todos los sprites con y sin flip (8 en vez de 4 ) no es una programacion eficiente pero por ahora funciona , si me dices como arreglarlo lo hago :p

Perfil MP  
Ir a la página 1, 2  Siguiente

Página 1 de 2


  
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
No puede descargar archivos
Puede publicar eventos en el calendario

   

Está utilizando la versión (Lo-Fi). Para ver la versión completa del foro, haga clic aquí.

Powered by Icy Phoenix based on phpBB
Design by DiDiDaDo

Página generada en:: 0.1742s (PHP: 16% SQL: 84%)
Consultas SQL: 15 - Debug off - GZIP Desactivado