Compresor de mapas

For all things Churrera. ¿Estás haciendo un juego? ¿quieres proponer un cambio? ¿tienes alguna duda? ¡Cuéntanoslo!

Moderador: na_th_an

Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Compresor de mapas

Mensajepor radastan » Mar, 05 Nov 2013, 09:35

Pues si, va como un tiro, esto me viene de perlas.
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Compresor de mapas

Mensajepor antoniovillena » Mar, 05 Nov 2013, 10:34

He medido la velocidad con Ticks y me da que tarda 14987 ciclos en descomprimir la primera pantalla. Los tiempos no son iguales en todas las pantallas, mientras más comprimida esté más rápidamente se descomprime. El algoritmo de descompresión es lento porque trabaja únicamente con el stream de bits (el zx7 basaba su velocidad en emplear masivamente el stream de bytes) y está optimizado en tamaño. Me salen 100 ciclos por byte descomprimido, que no está nada mal aunque supongo que la varianza es grande, habrá pantallas que se compriman en 50 ciclos por byte y otras que necesiten 150 ciclos.

El descompresor adaptado para Radastan será un poco más lento (necesita 6 llamadas a la rutina que lee un bit en lugar de 4) y aún más lento será el que use tablas huffman para decodificar los literales, pero no me preocupa porque a nivel comparativo:

-Tiempo que se tarda en llenar la pantalla de tiles: 129696 ciclos
-Tiempo que se tarda en descomprimir una pantalla: 14987 ciclos
-Proporción sobre el total entre pintar/descomprimir: 90%/10%

Estas cifras están calculadas en caso peor, es decir con una rutina de pintado de tiles optimizada en velocidad y una rutina de descompresión optimizada en tamaño (no es muy rápida). En el caso de la Churrera el cambio de pantalla es entre 5 y 10 veces más lento, por lo que el porcentaje de tiempo de ese cambio que se emplearía en descomprimir puede rondar entre el 1 y el 2%.
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Compresor de mapas

Mensajepor radastan » Mar, 05 Nov 2013, 10:43

:ymca:

Cuando tengas lista la prueba con 48 tiles me vendría perfecto saber la tasa media de compresión, no quiero pasarme de pantallas pero me gustaría aprovechar el espacio extra para meter más de las normales. Es que pienso en un mapa de 8x8 con 48 tiles y las babas se me caen a chorros.

A ver si me pongo las pilas también yo con la herramienta que quiero hacer en java para hacer la configuración de la churrera (config.h). He pensado en un método universal para que si hay cambios la herramienta se autoconfigure y muestre las nuevas opciones con comentarios y todo. :wan:

Básicamente consiste en tener un fichero config.hh estructurado en cierta forma para que me pase las secciones a mostrar, las opciones, los comentarios, etc. Así a nivel de usuario la cosa será un poco más amigable.
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Compresor de mapas

Mensajepor antoniovillena » Mar, 05 Nov 2013, 13:10

Bueno ya está, ya tengo una versión terminada para Radastan y todos los que queráis incluir el compresor de mapas para vuestros juegos. Más adelante sacaré otra versión que comprimirá más, aunque el descompresor también será más grande (sólo la publicaré si compensa).

En esta versión podéis cambiar el número de tiles a vuestro antojo con las constantes BITS_SYMBOL en TmxCompress.c y bitsymbol en juego.asm. Un valor de 4 es hasta 16 tiles, uno de 5 hasta 32 y uno de 6 hasta 64 tiles (éste último es el que te vale para 48 Radastan).

El funcionamiento es secillo, sigan este orden:
  • Creáis vuestro mapa con el Tiled o bien lo convertís desde Mappy con el Map2Tmx.
  • Compiláis todo con make.bat
  • Para ver el tamaño del archivo comprimido hacéis un dir mapa_comprimido.bin
  • Este script crea un TAP donde podéis ver vuestro mapa, lo más complicado es pasar dicho código a la Churrera, concretamente el código que va desde paint_map a sali (más la rutina gbita).
  • Se generan 2 archivos intermedios mapa2.tmx y tiles2.png, ignorarlos. Esto es para la futura versión y lo que hace es reordenar los tiles mostrando el mismo mapa (para que los tiles más frecuentes aparezcan primero).
Adjuntos
TmxCompress.0.20.zip
(83.03 KiB) Descargado 305 veces
Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Re: Compresor de mapas

Mensajepor D_Skywalk » Mar, 05 Nov 2013, 14:37

:vahka: :vahka: :vahka:

Entiendo entonces que debemos modificar a 6 tanto BITS_SYMBOL en TmxCompress.c como bitsymbol en juego.asm

Ok, pero integrarlo en la churrera ... no se por donde cogerlo.
¿Se supone que substituye a las funciones de pintado de mapas de la SPLIB? ¿las funciones de sprites las seguimos manteniendo con SPLIB?
¿sería muy complicado hacer un ejemplo con un juego churrero?

Mil gracias :adore:
David Skywalker
Weblog: http://david.dantoine.org
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: Compresor de mapas

Mensajepor antoniovillena » Mar, 05 Nov 2013, 15:13

Correcto (el valor 6 es para 48 tiles).

No, ni siquiera sustituye a las funciones de pintado splib, el ejemplo está para que comprobéis que el mapeado es correcto antes de meterlo en la churrera. He cogido precisamente dogmole porque es el juego que se explica en el tuturial, para facilitar una primera integración.

En realidad se almacenan 24 streams comprimidos (1 por cada pantalla) y 23 longitudes. De esos 24 stream en un momento dado sólo queremos descomprimir uno, por lo que indicamos cuál (qué pantalla va a mostrarse). En función de esa pantalla y con la información de las longitudes se calcula dónde empieza el stream comprimido. La descompresión se hace en el ejemplo en $c001-$c096, el byte bajo es fijo, el alto puede ser cualquiera, por lo que el buffer se aloja en ($xx01-$xx96).

Así que de la churrera hay que quitar las 24 pantallas originales (sin comprimir) y la rutina que calcula dónde empieza la pantalla. Luego metemos el código descompresor y el archivo comprimido. El descompresor se encarga que descomprimir a un buffer fijo la pantalla que reciba como parámetro (en el registro a).

Yo no sé cómo está programada la Churrera, podría intentar integrarlo pero me llevaría más tiempo, supongo que na_th_an lo acabaría antes, aunque puedo echar una mano depurando código.
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Compresor de mapas

Mensajepor na_th_an » Mar, 05 Nov 2013, 15:46

Yo ahora mismo estoy en 3000 manejes y no me puedo encargar. De todos modos lo único que hay que hacer es integrarlo en la función draw_scr_background de engine.h y asegurarse de que, además de pintar la pantalla, se rellenan bien los buffers map_attr y map_buff.
Como diría Rorshach: "Urm..."
Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Re: Compresor de mapas

Mensajepor D_Skywalk » Mar, 05 Nov 2013, 16:30

Voy a intentar integrarla yo, que na_th_an está en mil cosas...

a ver la funcion que pinta y calcula el tile es esta:
$this->bbcode_second_pass_code('', '
// Función que pinta un tile para mapas unpacked

void draw_coloured_tile (unsigned char x, unsigned char y, unsigned char t) {
unsigned char *pointer;
unsigned char xx, yy;
t = 64 + (t << 2);
pointer = (unsigned char *) &tileset [2048 + t];
sp_PrintAtInv (y, x, pointer [0], t);
sp_PrintAtInv (y, x + 1, pointer [1], t + 1);
sp_PrintAtInv (y + 1, x, pointer [2], t + 2);
sp_PrintAtInv (y + 1, x + 1, pointer [3], t + 3);
}
')

Está en printer.h

Y luego tenemos la draw que hablabamos:
$this->bbcode_second_pass_code('', '
void __FASTCALL__ draw_scr_background (void) {
map_pointer = mapa + (n_pant * 150);
gpx = gpy = 0;

// Draw 150 tiles

for (gpit = 0; gpit < 150; gpit ++) {
// Mapa tipo UNPACKED
gpd = *map_pointer ++;
map_attr [gpit] = comportamiento_tiles [gpd];
map_buff [gpit] = gpd;
draw_coloured_tile (VIEWPORT_X + gpx, VIEWPORT_Y + gpy, gpd);
gpx += 2;
if (gpx == 30) {
gpx = 0;
gpy += 2;
}
}

// Object setup

hotspot_x = hotspot_y = 240;
gpx = (hotspots [n_pant].xy >> 4);
gpy = (hotspots [n_pant].xy & 15);

if (hotspots [n_pant].act == 1 && hotspots [n_pant].tipo) {
hotspot_x = gpx << 4;
hotspot_y = gpy << 4;
orig_tile = map_buff [15 * gpy + gpx];
draw_coloured_tile (VIEWPORT_X + gpx + gpx, VIEWPORT_Y + gpy + gpy, 16 + (hotspots [n_pant].tipo != 3 ? hotspots [n_pant].tipo : 0));
}
for (gpit = 0; gpit < MAX_CERROJOS; gpit ++) {
if (cerrojos [gpit].np == n_pant && !cerrojos [gpit].st) {
gpx = cerrojos [gpit].x;
gpy = cerrojos [gpit].y;
draw_coloured_tile (VIEWPORT_X + gpx + gpx, VIEWPORT_Y + gpy + gpy, 0);
gpd = 15 * gpy + gpx;
map_attr [gpd] = 0;
map_buff [gpd] = 0;
}
}
}
')
vamos a ello... :dalefran:
David Skywalker
Weblog: http://david.dantoine.org
Avatar de Usuario
D_Skywalk
Mensajes: 352
Registrado: Mar, 01 Oct 2013, 13:36

Re: Compresor de mapas

Mensajepor D_Skywalk » Mar, 05 Nov 2013, 16:34

Los dos sitios clave sería según veo:

engine.h
$this->bbcode_second_pass_code('', ' for (gpit = 0; gpit < 150; gpit ++) {
// Mapa tipo UNPACKED
gpd = *map_pointer ++; <--- este puntero
')

printer.h
$this->bbcode_second_pass_code('', ' t = 64 + (t << 2);
pointer = (unsigned char *) &tileset [2048 + t];
')

Ahora me tienes que contar como funciona la rutina por que en asm, no entiendo nada...
Se supone que primero descomprimimos un cacho y luego pintamos?
Se descomprime todo conforme se va leyendo?

Un Saludo y a ver si entre los dos lo echamos a andar :wan:
David Skywalker
Weblog: http://david.dantoine.org
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Compresor de mapas

Mensajepor na_th_an » Mar, 05 Nov 2013, 16:44

No creo que tengas que tocar para nada la función que imprime un tile (sobre todo porque tiene en cuenta las sombras automáticas y además se llama desde muchas otras partes). Entiendo que habría que hacer que las rutinas nuevas descomprimiesen el mapa en un buffer y luego pintar la pantalla a partir de ahí, en lugar de leer de la estructura de mapas directamente.

Por debajo de 24200 tienes 150 bytes libres si los necesitas. Más abajo mejor no tocar, porque hay otro buffer que se emplea para algunas cosas.
Como diría Rorshach: "Urm..."

Volver a “La Churrera”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 146 invitados