Página 6 de 10

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 08:37
por Hark0
Estoy empezando a montar un mapa con varias pantallas...

De momento he montado 9, para poder comprobar todas las entradas salidas, conexiones etc...

La cosa ya se está "engordando"... he alcanzado los 19 kb...

Osea, mola meter 1000 graficos, pero me como ram.
Mola meter 1000 pantallas, pero me como ram.
Necesito reservar logicamente, espacio para la logica del programa, etc.

Me pregunto... ¿como calcular un equilibrio mapas/sprites?

¿alguna pista/idea?

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 08:43
por na_th_an
Amigo, eso es bien jodido :) Si ya tuvieses el motor terminado, podrías ver cuánto te queda libre y equilibrar así.

Ten muy presente cuánto te ocupa una pantalla y cuánto te ocupa cada gráfico/sprite. Por ejemplo, en la churrera, como los movimientos son a pixel los gráficos de los sprites ocupan mucho más. Cada frame de sprite ocupa como dos pantallas del mapa... En tu caso el ratio no es tan heavy.

También puedes intentar tirar con lo que tienes y si te ves picueto de memoria buscar una forma de comprimir el mapa, como la que propone A. Villena, con la que se consigue muy buen ratio de compresión.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 09:43
por radastan
Pues mira, mi experiencia haciendo el juego para Interface II que debe ocupar 16K como máximo:

- Un mapa de 1000 pantallas es absurdo, es más, según te lo curres incluso uno de 8x8 pantallas es todo un Mundo.
- Cada pantalla no tiene porqué ocupar todo el área visible, haz el área visible más pequeñita y podrás engordar el mapa artificialmente (y queda mono).
- Como bien dices 1000 tiles molan, pero lo mismo con 96 sobra.

Un ejemplo:

- Pantalla de 16x8 tiles (marcador abajo de 4 caracteres de alto)
- Mapa de 8x8 pantallas

Eso da 8192 bytes, 8K, para el mapa. No es un disparate, pero puedes recortar la pantalla a 10x10 tiles y se te queda el mapa en 6K nada más. 64 pantallas es tela de grande.

Pero vamos, que llevas 18K ocupados, tampoco es tanto. Mete el mapa completo y todos los tiles, aunque haya tiles y pantallas vacías, y sabrás exactamente lo que queda de código.

La otra opción es meter compresión de mapas, pero no creo que te haga falta a menos que seas muy burro.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 10:51
por Hark0
Os entiendo a ambos...

Estoy en una fase bastante inicial y tengo en mi cuaderno cuadriculado de toda la vida un mapa más / menos planteado...

Lo que tengo claro es que las pantallas las quiero de 32x20; si meto "marcos" para encoger la pantalla no tiene porqué desmerecer (basta ver todo lo que hay ya) pero soy partidario de llenar la pantalla con el mapa en todo lo que pueda.

Como comentáis es difícil porque estoy ante la tesitura de hacer el mapa más detallado (más tiles) ó recortarlo...

Creo que de momento iré puliendo el "motor mainloop" con las 9 pantallas que tengo y cuando esté "limpio, etc" voy engordando la cosa...

Una cuestión más:

¿Tarda lo mismo pintar una pantalla usando put_sprite16 que usando put_h1_Sprite (2 pasadas)? Tengo muchos tiles de 8x8 que podria aprovechar...


EDITO: Gracias por vuestra paciencia conimgo ;)

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 10:59
por radastan
$this->bbcode_second_pass_quote('Hark0', 'Â')¿Tarda lo mismo pintar una pantalla usando put_sprite16 que usando put_h1_Sprite (2 pasadas)? Tengo muchos tiles de 8x8 que podria aprovechar...


Evidentemente tarda bastante más.

Tu hazlo todo con tiles de 16x16 que el concepto de megatiles ya lo explicaré más adelante. Se basa en usar combinaciones de tiles, de varios tamaños, para hacer otro más grande. De esa forma, si en el mapa se repiten muchos patrones, puedes ahorrar mucha memoria y tener un mapa más grande.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Jue, 22 May 2014, 11:17
por Hark0
$this->bbcode_second_pass_quote('radastan', '')$this->bbcode_second_pass_quote('Hark0', 'Â')¿Tarda lo mismo pintar una pantalla usando put_sprite16 que usando put_h1_Sprite (2 pasadas)? Tengo muchos tiles de 8x8 que podria aprovechar...


Evidentemente tarda bastante más.

Tu hazlo todo con tiles de 16x16 que el concepto de megatiles ya lo explicaré más adelante. Se basa en usar combinaciones de tiles, de varios tamaños, para hacer otro más grande. De esa forma, si en el mapa se repiten muchos patrones, puedes ahorrar mucha memoria y tener un mapa más grande.


prefestro! ;)

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Vie, 23 May 2014, 09:20
por Hark0
Bueno... sólo comentar que ayer puse en práctica lo comentado en el post que postee en speccy.org (http://foro.speccy.org/viewtopic.php?f= ... =45#p42085)

Pego aqui lo posteado allí:

$this->bbcode_second_pass_code('', 'Cuando declaras un sprite y luego lo usamos con putsprite_... veo que usas

unsigned char XXXX.

Yo he probado lo siguiente:
- He editado motorzx.h y he cambiado el unsigned char *puntero por unsigned int *puntero.
- He añadido un unsigned int mem_sprites[x];
- mem_sprites[0]=sprite0;
- mem_sprites[1]=sprite1;
etc.

- Para pintar putsprite(mem_sprites[num_sprite],x,y);

Y así me ahorro los switch para pintar el numero de sprite...

¿es buena idea o estoy gastando MAS ram?')


He pasado de 20 Kb -> 16 Kb. :mrgreen:

Y es que "sólo" con los tiles de test ya tengo +25 sprites (16x16 px) + la typo... :P

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Vie, 23 May 2014, 10:21
por na_th_an
Si tienes todos los sprites seguidos, y el primero está apuntado por sprite0, teniendo en cuenta que uno de 16x16 ocupará 32 bytes (si no me salen mal los cálculos, 16 lineas de 2 bytes), puedes ahorrarte también el array global:

$this->bbcode_second_pass_code('', 'putsprite (sprite0 + (num_sprite << 5), x, y);')

Como putsprite recibe un puntero con la dirección del sprite, y los tienes todos seguidos, directamente le envías la dirección calculada con respecto al primero.

Esto puede parecer más lento que usar un array, pero no lo es. Ten en cuenta que para acceder a mem_sprites [num_sprite] el compilador también tiene que generar código que coja la base y añada el desplazamiento dentro del array.

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Vie, 23 May 2014, 22:07
por Hark0
Necesito algunas aclaraciones acerca de la rutina put_sprite_x16 (unsigned char *posicion, unsigned int x, unsigned int y).... y unos bonitos Warnings que tengo, aunque el programa funciona bien. Sé que son temas de C, no específicos de Z88DK... pero es que me hago la piiiii un lio con los punteros y sus conversiones...

Hago lo siguiente:

-Cargo los gráficos con

extern unsigned char sprite1 [];

#asm
._sprite1 // tile check
defb 255,255,129,129,137,153,153,137
defb 137,153,157,145,129,153,255,255
defb 255,255,129,129,153,145,137,149
defb 153,157,137,133,153,133,255,255
defb 71,71,71,71
#endasm

- Para dibujar el sprite el curso recomienda (se que éste no está acabado... y que esta es la forma "simple" de pintar):

put_sprite_x16(sprite1,x,y);


Ahora bien, esto no es práctico y ya lo comenté en el foro speccy.org (link nos post atrás) si quieres que el listado no se haga enoooorme.

Se me ocurrió que dado que sprite1 entra como puntero cuando es llamado a la función, leer el valor de éste y meterlo en una matriz, luego para pintar un sprite determinado:


unsigned int matriz_direccion_sprite[cantidad_total_sprites];

matriz_direccion_sprite[1]=sprite1;
matriz_direccion_sprite[2]=sprite2;
matriz_direccion_sprite[3]=sprite3;

put_sprite_x16(matriz_direccion_sprites[num_sprite_a_pintar],x,y);


Bien, el programa funciona, pero a la hora de generar la cinta, me genera unos Warning tipo:

 warning: assignment makes integer from pointer without a cast...

... en las lineas matriz_direccion_sprite[1]=sprite1; ...


Si hago un printf("Valor puntero: %i"),sprite1 por pantalla obtengo algo tipo:

28962

E incluso si utilizo esto otro:

unsigned int direccion_ram_sprite=sprite1;

put_sprite_x16(direccion_ram_sprite+(num_sprite_a_pintar*36),x,y); // 8x4 ink +4 attrb

también funciona, pero con Warnings... 

Además, como me he cepillado todos los switch he reducido el consumo de Kb una barbaridad...

¿paso de los warnings? el juego funciona bien...
¿que hago mal?
¿paso de todo lo hecho y ataco directamente con el codigo de na_th_an?
¿y porque me embolico tanto?

Perdón por el tocho... pero soy de esos primos que disfrutan picando "cosas raras"... a ver si van... :P

Re: Z88DK (curso Radastan) - Dudas Varias

Publicado: Vie, 23 May 2014, 22:15
por na_th_an
Te avisa por si acaso te has equivocado. Como no te has equivocado, puedes evitarlo. De todos modos, te sale porque estás asignando punteros a un array de enteros. En esta plataforma no importa, porque los punteros son valores de 16 bits, y los enteros también, por lo que los tipos son compatibles y el programa no te casca... Sin embargo en otras no tienen por qué ser compatibles (por ejemplo, en MSDOS, si estás en modo large el puntero puede ser de 32 bits y los enteros tienen 16...). Por eso no es buena práctica de programación en C, y un buen compilador te avisa.

Lo suyo es, por tanto, hacer las cosas bien para que el compilador no se queje.

Cada extern unsigned char [] es en realidad un puntero a unsigned char. Si, teniendo en cuenta esto, haces tu array como un array de punteros a unsigned char, y problema solucionado:

$this->bbcode_second_pass_code('', 'unsigned char *matriz_direccion_sprites [] = {
sprite1, sprite2, sprite3
}')

Así, cuando llamas a la función, que espera un unsigned char *, con "matriz_direccion_sprites [1]", por ejemplo, estarás pasándole precísamente un unsigned char *, ya que la matriz contiene elementos de este tipo.

En ese mismo sentido iba el consejo que te di. La función que usas espera un puntero, o sea, una dirección de memoria. Teniendo la dirección de memoria del primer elemento (sprite0 en tu ejemplo de antes) calcular la de los siguientes es cuestión de sumar y multiplicar.