Página 20 de 22

Re: Compresor de mapas

Publicado: Jue, 30 Ene 2014, 15:59
por elborra
$this->bbcode_second_pass_quote('na_th_an', 'H')ostia, ni me acordaba del warning :lol: Jodó, si es que hice esa utilidad hace ya cuatro años XD
y lo bien que funciona todavía!! 8-)

Subo de nuevo quitando el texto de WARNING (la información y uso siguen disponibles)
Quitado símbolos y tildes para que no se vean mal en el output de la consola.

De todas formas el código, como nathan mismo puso en el código fuente XD, es bastante ineficiente pero como el mismo pensaría en su momento no voy a "perder" tiempo en hacer una mega-hiper-aplicación optimizada y reducida para convertir un mapa con los equipos de hoy en día :P (al menos no de momento jejejejeje)

Por cierto, antonio, también me bajé las fuentes de TmxCompress para cambiarle la salida por los valores de la churrera, subiría el binario también pero el ejecutable que me saca tiny c compiler me lo detecta con un falso positivo el avast (avira por ejemplo, que es el que uso en el portatil, no) supongo que por temas de compresión y otras historias que no vienen al cuento, y no es plan de subir algo que luego me vengan con que tienen virus y hostias varias :lol:

Re: Compresor de mapas

Publicado: Jue, 30 Ene 2014, 16:09
por na_th_an
La verdad es que es una cacota. Lo hice en cinco minutos, y básicamente hace su trabajo XD

En las versiones más recientes no uso ese conversor, porque necesito salida en binario para meter en las páginas extra de los 128K (ver el make.bat de GOKU MAL).

Ahora mismo, en la versión "por venir" de la churrera, hay dos conversores nuevos: el que viene en Goku Mal (versión 3.99.3) que pilla todos los datos de una fase (gráficos, mapa, enemigos, etc...) y crea un binario gordo con todo, y otro nuevo que pertenece a un set de conversores que generan archivos binarios, no de código.

Estos están mejor, dan menos vergüenza :lol:

Re: Compresor de mapas

Publicado: Jue, 30 Ene 2014, 18:55
por antoniovillena
$this->bbcode_second_pass_quote('elborra', '
')Por cierto, antonio, también me bajé las fuentes de TmxCompress para cambiarle la salida por los valores de la churrera, subiría el binario también pero el ejecutable que me saca tiny c compiler me lo detecta con un falso positivo el avast (avira por ejemplo, que es el que uso en el portatil, no) supongo que por temas de compresión y otras historias que no vienen al cuento, y no es plan de subir algo que luego me vengan con que tienen virus y hostias varias :lol:


Pues me parece buena idea así que he hecho lo mismo en la versión oficial. Así si escribes:
TmxCompress bla bla > archivo.h

Pasas los parámetros a archivo.h, y con un sencillo include en config.h lo tienes todo automatizado

Re: Compresor de mapas

Publicado: Mié, 26 Feb 2014, 14:30
por elborra
Vuelvo a reflotar el tema con una duda de compresión.

Tengo una duda, no tanto de la adaptación ZX7+RCS que hicistes para los mapas de la churrera (que buen uso le estoy dando ^_^) sino al tema de las rutinas de descompresión y la viabilidad o no de una idea que a continuación te expongo. Todo esto viene porque ya sueño con bits, bytes y tiles y una cifra constante de fondo: 36,5K. Entre todo ese batiburrillo de pensamientos cruzados me vino una idea de imposible ejecución por mi total ignorancia en algoritmos de compresion y ensamblador :oops:

Por ahora tanto con aapack como con ZX7 descomprimimos el binario entero a una zona de la memoria. Bueno, realmente en la función C le pasamos la dirección de memoria donde está el binario y la dirección de destino (lo que ocurre en la trastienda con asm y tal ni idea, a cada página del hilo en WOS sobre ZX7 menos me enteraba XD, algo he pillado pero no mucho). En fin, la cuestión es poder descomprimir el binario pero OBVIANDO parte de los datos según le indiquemos a la rutina de alguna forma.

¿Para que? pues, en mi caso concreto, para tener todos mi 'sets' de tiles en sólo 2 ficheros: 1 para los gráficos y el otro para los atributos (ahora tengo 20 ficheros binarios, 10 y 10)

¿Por qué? pues porque no es lo mismo lo que ocuparian los 10 binarios en un sólo fichero y comprimirlos que individualmente tal como lo tengo ahora (en mi caso ahorro más de 500 bytes)

¿y como me gustaría (de poderse) que funcionara? ¿qué es eso de OBVIAR XD? Centrándonos en los gráficos en si y siguiendo mi caso; una vez generado el binario con todos los tiles (+80) y comprirlo está claro que sólo voy a poder usar 48 de ellos. Como gestionar esto...

Si cada tile lo forman (descomprimidos) 32 bytes quizás sería posible en el proceso que ciertos conjuntos de 32 bytes descomprimidos no machaquen el tileset[], quizás esto no sea siquiera posible por la rutina en si misma (la manera de leer y descomprimir no sea ordenada o vaya usted a saber.... yo estoy pez). De ser esto viable ya "sólo" quedaria decirle a la rutina que conjuntos de 32 bytes queremos descomprimir y cuales no. Y digo descomprimir por llamarlo de alguna manera, a mi me daría igual que se procese todo el fichero pero los datos los vaya depreciando o no según otra estructura o lo que haga falta.

Más que nada me gustaría saber si esto es posible o no. De ser posible yo no tengo los conocimientos para hacerlo y por ello quiero dejar claro que no estoy pidiendo que lo hagais cualquiera de vosotros; dependerá de la complejidad, las ganas, y por supuesto si creeis, en definitiva, que merece la pena. Yo lo único que puedo hacer es de conejillo de indias xD.

Ejemplo explicativo final :ayayay: :

- Por un lado tengo un fichero binario de 82 tiles (por poner) = 2624 bytes
- Compririamos con aapack o zx7 = tamaño variable

- Dentro del código del juego tendria una estructura (es lo primero que se me ha ocurido y seguramente sea la peor idea de todas ya que quizás lo que ahorro en compresión lo pierdo con estas estructuras), con la información de que tiles tengo que extraer en tileset[]; por ejemplo: el 0,1,3,5,7,12,34,36,37,58,59,60,61 ....... 80 (48 tiles).
De alguna manera la rutina descompresora tendría que ir recorriendo esa estructura (llamemosla "quetiles" a la vez que va descomprimiendo)

En definitiva,una aproximación cutre de la rutina descompresora en pseudocodigo sería:

$this->bbcode_second_pass_code('', '
quetiles = 0,1,3,5,7,12,34,36,37,58,59,60,61 ....... 80, //set 1
3,5,7,9,11,14,15 ......................................., //set 2
etc....


posicion_en_quetiles= n // 48*set
dirección_descomprimir = tileset+512 // tile 0
numero_tile = quetiles[posicion_en_quetiles]

MIENTRAS {

DESCOMPRIMIR 32 BYTES DEL BINARIO EN dirección_descomprimir // En esta aproximación los datos siempre van a parar a direccion_descomprimir, pero como esta no se actualiza si no es el tile requerido se machacará por el correcto cuando toque

SI (dirección_descomprimir == numero_tile) ENTONCES
direccion_descomprimir+=32
posicion_en_quetiles++
numero_tile = quetiles[posicion_en_quetiles]
FINAL SI

} no_hayamos_acabado_de_descomprimir')

Esta claro que esto sólo sería posible si la descompresión es ordenada, supongo. Además habría que ver como pasar los datos de que tiles usar o no, ya que una estructura pelada como la que planteo ocuparía más de lo que ahorramos por otro lado. Quizás a nivel bit donde con cada byte podriamos representar que tiles entre 8 estan activos o no. (podriamos representar cada set con 8-9 bytes) Aparte habría que hacer lo mismo pero con los atributos, es decir en lugar de ir de 32 bytes en 32 sería de 4 en 4.

Ahí lo dejo.... :dalefran:

Re: Compresor de mapas

Publicado: Mié, 26 Feb 2014, 16:26
por antoniovillena
Eso ya está. ZX7+RCS es para las pantallas, el descompresor discrimina si es pantalla o no para aplicar el filtro RCS. El compresor de mapas es un compresor custom diseñado por mí, lo único que he cogido de Einar es parte del código compresor (el algoritmo de descompresión es muy diferente).

Fíjate en el código fuente de Sami Troid o de Escape from the lost Abbey, ambos tienen compresión de binarios (e imágenes).

Re: Compresor de mapas

Publicado: Mié, 26 Feb 2014, 17:15
por elborra
Ya ya antonio,

Yo tengo ahora mismo mi mapa.map convertido a tmx y luego comprimido con tus utilidades.
aplib sustituido por compress.h que contiene tu rutina custom descomprimir_mappero y también la rutina "Smart" integrated RCS+ZX7 decoder by Einar Saukas (110 bytes) para las pantallas de titulo y ending.
Aparte 10 png con conjuntos de tiles (con diferentes números de tiles cada uno) que proceso en 10 ficheros binarios para los graficos y otros 10 para los atributos correspondientes, comprimidos a su vez con ZX7

Ya "dentro" de la churrera:
Tengo una estructura en la que cada pantalla tiene asignado un set (Tengo 7 "sets")
Otra estructura que representa como se conforma cada set (que conjunto de tiles y en que posición)
Cada "set" está formado siempre por 4 conjuntos de tiles (de los 10)
Y cada vez que entro en una pantalla compruebo que set utiliza, y descomprimo los 4 conjuntos de tiles en sus direcciones correspondientes (y sus atributos)

Todo esto funciona perfectamente (y seguro que bastante ineficazmente xD)

La idea es cambiar este tinglado por lo que te explico en la edición de mi anterior post :D

Re: Compresor de mapas

Publicado: Mié, 26 Feb 2014, 20:07
por elborra
Primero lo que tendría que saber es si los datos al descomprimirse son secuenciales o no. En caso afirmativo si previamente tenemos lo siguiente:

- Un binario comprimido con ZX7 con N tiles (vamos a decir 64).

- Un puntero con la dirección origen del binario
- Un puntero con la dirección destino (al tileset vaya)
- Un puntero (ptile) a memoria donde tenemos un conjunto de 8-10 bytes
$this->bbcode_second_pass_code('', 'Cada bit del conjunto represantaría 1 tile. 0-> no se usa. 1->se usa .Así, sí tenemos 8 bytes, podriamos representar:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ->64 tiles

Como sólo tenemos 48 tiles para usar por pantalla, podríamos representar cualquier combinación secuencial de 48 tiles entre nuestros 64 disponibles indicando 0 o 1.')
Voy a imaginarme que los datos de descomprimen byte a byte (realmente daría igual si es así o no, la cuestión es saber cuando hemos descomprimido 32 bytes, si es que se puede). Con todos estos "y si" la cuestión sería añadirle lo siguiente a la rutina descompresora.

- Cuando hayamos descomprimido 32 bytes reales (1 tile) comprobamos si el bit n del byte que apunta ptile es 0 o 1 y en función de ello
$this->bbcode_second_pass_code('', 'Si es 0 la dirección destino se decrementaría en 32 bytes. (Como no queremos usar ese tile descomprimimos el siguiente "encima").
Si es 1 continuariamos normalmente')- Independientemente de si es 0 o 1 "pasariamos" al siguiente bit del byte ptile. Al comprobar los 8 bits incrementariamos el puntero ptile al siguiente byte
- Y así hasta terminar
Creo que así se entiende mejor :corchoneta: Otra cosa es que esto en ensamblador tiene que ser un pifostio.

Edito: Si veis que estoya se aleja del proposito inicial del post abrimos otro hilo y movemos estas útimas consultas.

Re: Compresor de mapas

Publicado: Jue, 27 Feb 2014, 01:26
por antoniovillena
Eso que dices no se puede hacer. Hay que descomprimir todo el stream.

Meter compresión en tiles o sprites es en general mala idea. En FASE (o en otro engine con mayor número de tiles) por ejemplo se aplica indexación, que no es exactamente compresión pero se reducen muchos bytes. Consiste en usar los mismos colores para distintos tiles o los mismos bitmaps con distintos colores (o ambas a la vez). Pero claro para 48 tiles no merece la pena aplicar esta técnica.

De todas formas si sigues con la idea de aplicar compresión, te comentaré algunas cosillas. Así sin hacer números ni nada te adelanto que para 2 sets de tiles no merece la pena. Por cierto, si tienes tiles comunes entre los sets directamente no los comprimas. ¿Por qúe? Pues porque si los vas a tener siempre en memoria descomprimidos, ¿dé que te sirve una versión comprimida de los mismos?. El problema de la compresión es la RAM, tienes que tener espacio para todos los streams comprimidos y para un set completo descomprimido. Vamos a suponer que no hay tiles comunes entre los sets de tiles. Si cada set de tiles descomprimido ocupa 2K, y se puede comprimir al 50%, comprimido te ocupará 1K. Si no usas compresión necesitarás 4K (2K para cada set), pero si usas compresión necesitarás 4K más lo que te ocupe el código descompresor. Son 4K porque necesitas 2K para el buffer descomprido y 2K para los streams comprimidos (1K para cada stream).

Re: Compresor de mapas

Publicado: Jue, 27 Feb 2014, 02:24
por elborra
No se si te he entendido yo bien a tí... pero yo el stream en el ejemplo que te pongo se descomprime entero lo único que no lo descomprimiria "seguido".

Otra cosa es que no se pueda, como preguntaba, saber cuantos bytes llevo descomprimidos en cada momento (dentro de la rutina descompresora obviamente).

Par aclarar, se que tileset[] reserva los 2048+256 byte y eso está ahí y no me lo quita nadie.

Aparte tengo 11 (me olvidé el 0 en las cuentas anteriores) conjuntos de tiles (en estos conjuntos no se repite ningún tile) y son de diferentes tamaños: 10 tiles, 8 tiles, 4 etc.. Dependiendo de la pantalla genero una combinación uniendo 4 de estos conjuntos de tiles que configuran mi tileset final de 48 tiles para dicha pantalla. Para ello descomprimo con unpack (ZX7) cada conjunto de tiles dandole como dirección origen el binario del conjunto y como destino tileset+offset.

Esto como comentas conlleva que tengo datos comprimidos que en principio podría tenerlos en el tileset.h que genera la churrera ( en mi caso casi no me sirve de nada, salvo 6 o 7 tiles que son fijos y nunca se "sobreescriben"). ¿que gano con esto? pues que si quisiera "crear" el mapeado que he hecho necesitaría 6 sets de 48 tiles y esto obviamente ocuparía muchiiisimo más.

La cuestión era que si la rutina descompresora sabe cuantos bytes a descomprimido en cada momento se le podía condicionar a que la dirección destino fuese cambiando.

Cuando hablas de buffer para la descompresión ya me pierdo precisamente porque no se que ocurre en la trastienda de la rutina asm
¿necesitaría por tanto un buffer intermedio de al menos el tamaño del stream descomprimido? es como lo que comentabas con el mapa "pidiendo" un buffer de al menos 150 bytes libre para las pantallas. Por tanto necesitaría más de 2,5K de buffer (ya que lo que pretendía es tener un binario con todos los tiles, aprox 80) :loco: si esto es así , me queda claro porque auque pudiese contar los bytes descomprimidos con semejante tamaño de buffer apaga y vamonos. ¿El propio tileset[] no podría ser parte del buffer? aunque creo que otra ve sería peor el remedio que la enfermedad (lo que me ahorro en bytes al juntar todos los conjuntos de tiles en uno sólo lo pierdo, o empeoro, aumentando el tamaño de la variable tileset)

Bueno, primero acabaré con lo que me queda de lógica y empezaré a revisar como loco el código que he hecho con la esperanza de sacar algo. Sino habrá que moverse a los 128K. Con suerte si despues de trasladar todo lo trasladable a la pagina RAM extra sobra espacio le añadiría cosas que había dejado en el tintero.

Gracias otra vez ^_^

Re: Compresor de mapas

Publicado: Jue, 27 Feb 2014, 08:06
por na_th_an
Según yo he entendido, lo que dice el_borra es que haya trozos del binario descomprimido que no se escriban. Por ejemplo, podría hacerse un descompresor que fuera sacando bytes y sólo escribiese cuando el byte que ha sacado es distinto de cero, o está en un rango, pero que siempre fuese incrementando el puntero de escritura. Sería descomprimir el binario entero, pero sólo escribir en el buffer de salida los bytes descomprimidos según cierta máscara, dejando los demás bytes sin tocar.