Problema de tamaño

Started by lou, January 13, 2010, 09:31:01 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

lou

Saludos por estas tierras!
Llevo ya como un mes con mi nuevo juego, usando el editor de mapas que programe, y me surge un gran problema!
Los mapas están basados en tiles. Cada tile está formado por una estructura padre y dos hijas:


TYPE tp_celda
int pos_x; //pos x de la celda
int pos_y; //pos y de la celda
tp_tile graf_suelo; //grafico del suelo
tp_tile graf; //grafico objeto o unidad
byte tiene_pj = FALSE; //tiene un pj encima
int id_pj = 0; //id del pj encima
byte tiene_muerto = FALSE; //tiene un pj muerto encima
int id_muerto = 0; //id del pj muerto
byte zona_segura = FALSE; //si en esta zona se puede pegar a un pj
END

TYPE tp_tile
byte tipo; //tipo de grafico terreno, objeto etc
short grafico = 0; //nº grafico en el fpg
byte traspasable = TRUE; //si se puede traspasar
byte es_proceso = FALSE; //si es un proceso
byte tipo_proceso; //tipo de proceso que es
byte respawn = FALSE; //a sido invocado ya?
int color; //color en el minimapa
byte es_borde = FALSE; //si es borde con otro tipo de terreno
byte tipo_borde; //tipo de borde
END


Como veis, he intentado reducir el tamaño usando tipos de dato pequeños, pero no me es suficiente...
De momento andaba probando con un mapa de 128x128, pero se queda extremadamente pequeño. Probé con un tamaño mayor, y el problema es que cuanto más grande es la matriz, mas tarda en arrancar el programa. Con una matriz de 1024x1024, que sería lo ideal, el programa tarda horrores en compilar. Imagino que es por el tamaño de los types.

Mi pregunta es, hay alguna manera de solucionar esto? Otro método para cargar mas rapido la matriz del mapa? Otro sistema para hacer un mapeado de tiles? o tendre que conformarme con un mapilla de 256x256 o 512x512?

P.D. en un futuro, mi plan era hacer mapas multinivel (varios pisos), pero por el momento lo veo irrealizable por este motivo :(

Muchas gracias por todo!

FreeYourMind

Por el titulo pense que el problema era otro  ;D

La verdad no entiendo nada del codigo que pones, o no entiendo bien tu explicacion...

lou

veamos, a ver si me explico mejor jeje^^


TYPE tp_celda
int pos_x; //pos x de la celda
int pos_y; //pos y de la celda
tp_tile graf_suelo; //grafico del suelo
tp_tile graf; //grafico objeto o unidad
byte tiene_pj = FALSE; //tiene un pj encima
int id_pj = 0; //id del pj encima
byte tiene_muerto = FALSE; //tiene un pj muerto encima
int id_muerto = 0; //id del pj muerto
byte zona_segura = FALSE; //si en esta zona se puede pegar a un pj
END

TYPE tp_tile
byte tipo; //tipo de grafico terreno, objeto etc
short grafico = 0; //nº grafico en el fpg
byte traspasable = TRUE; //si se puede traspasar
byte es_proceso = FALSE; //si es un proceso
byte tipo_proceso; //tipo de proceso que es
byte respawn = FALSE; //a sido invocado ya?
int color; //color en el minimapa
byte es_borde = FALSE; //si es borde con otro tipo de terreno
byte tipo_borde; //tipo de borde
END

Esas son las estructuras que uso para formar la matriz del mapa:

tp_celda tablero[SIZE_X_TAB][SIZE_Y_TAB]; //crea una matriz de tamaño x e y

Realmente lo que representan los datos en los TYPES no tiene importancia. Mi problema viene cuando al declarar por ejemplo
tp_celda tablero[512][512]; tarda como 2 o 3 minutos en compilar, hasta que sale la pantalla del juego vamos.
La pregunta es si hay alguna manera de reducir ese tiempo de compilacion.

Si quereis probar lo que quiero decir, crear un .prg con este codigo y compilar. Cuanto más grande sea el array, mas tardará en compilar

PROGRAM prueba_rendimiento;

import "mod_video";
import "mod_screen";

TYPE tp_tile
byte tipo; //tipo de grafico terreno, objeto etc
short grafico = 0; //nº grafico en el fpg
byte traspasable = TRUE; //si se puede traspasar
byte es_proceso = FALSE; //si es un proceso
byte tipo_proceso; //tipo de proceso que es
byte respawn = FALSE; //a sido invocado ya?
int color; //color en el minimapa
byte es_borde = FALSE; //si es borde con otro tipo de terreno
byte tipo_borde; //tipo de borde
END

TYPE tp_celda
int pos_x; //pos x de la celda
int pos_y; //pos y de la celda
tp_tile graf_suelo; //grafico del suelo
tp_tile graf; //grafico objeto o unidad
byte tiene_pj = FALSE; //tiene un pj encima
int id_pj = 0; //id del pj encima
byte tiene_muerto = FALSE; //tiene un pj muerto encima
int id_muerto = 0; //id del pj muerto
byte zona_segura = FALSE; //si en esta zona se puede pegar a un pj
END   
     
GLOBAL
tp_celda tablero[128][128]; //CAMBIAR ESTO POR VALORES MAS ALTOS, ENTONCES SE REALENTIZA (512,768,1024..)
BEGIN
set_mode(800,600,32,MODE_WINDOW);
LOOP
FRAME;
END
END


Espero haber aclarado algo!
Un saludo!

FreeYourMind

Me imagino por la dimensión, por lo que veo estas creando un tablero enorme y cada uno de los 512 va tener su gráfico, eso a vista rápida es lo que me parece. Yo que haria tiles de otra forma, creo que te estas aprofundizando más de lo necesário, no se para que necesitas crear matrizes para poner tiles, te bastarian coordenadas y indicar los graficos de los tiles...

SplinterGU

primero, no uses byte o tipos menores a 32bits... lo hace mas lento.

donde lo estas compilando, a mi me tarda 0 segundos en compilar tu ejemplo.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

osk

Quote from: SplinterGU on January 14, 2010, 02:19:37 AM
primero, no uses byte o tipos menores a 32bits... lo hace mas lento.

donde lo estas compilando, a mi me tarda 0 segundos en compilar tu ejemplo.

¿No importa, pues, desaprovechar memoria ram? Ya se sabe que hoy en día es casi infinita, pero a mi siempre me enseñaron que los tipos debían de ser acorde al tamaño del dato que queríamos guardar...Pero vaya, da lo mismo supongo.

Windgate

El problema de las matrices GORDAS a mí también me pasa en ocasiones, si el tablero tiene proporciones bíblicas (p. ej. 1024x1024), aunque sea de simples int ya tenemos 4Mb. Si además tienes varios campos puedes tener un tablero de unos 40Mb en memoria, que es bastante, después de compilar observa los bytes usados en GLOBAL data y verás lo que te digo.

Eso que comentas lo he sufrido estos días con mi Mundo3D al cual le podéis echar un vistazo porque es curioso de ver :P

Yo he estado planteando hacer un tablero dinámico que se vaya generando a medida que se usa... Puedes hacerlo 100% dinámico con mem_alloc, cosa que sería un trabajo curioso, o bien puedes tener una info "resumida" de todo el tablero y otra info extendida de la parte visible en pantalla...

De todas formas una vez compilada la cosa debería ejecutarte rápido, ¿No?.

Prg hace una cosa muy curiosa, que es tener varios .dcb compilados e ir invocándolos, quizás puedas dejar el tablero en un .dcb ya compilado para evitar la tediosa espera cada vez que haces un cambio y compilas.

En fin, espero que te sirva de algo :P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

lou

Quote from: SplinterGU on January 14, 2010, 02:19:37 AM
primero, no uses byte o tipos menores a 32bits... lo hace mas lento.

donde lo estas compilando, a mi me tarda 0 segundos en compilar tu ejemplo.

jeje, tarda 0 segundos con un tablero de 128x128. Por lo menos en mi caso, cuando el tablero es de 512x512 o mayor, la cosa empieza a realentizarse. Probare usando int en vez de byte, lo hacia por reducir el tamaño del fichero final al guardar el mapa.

Quote from: Windgate on January 14, 2010, 10:36:20 AM
Yo he estado planteando hacer un tablero dinámico que se vaya generando a medida que se usa... Puedes hacerlo 100% dinámico con mem_alloc, cosa que sería un trabajo curioso, o bien puedes tener una info "resumida" de todo el tablero y otra info extendida de la parte visible en pantalla...

De todas formas una vez compilada la cosa debería ejecutarte rápido, ¿No?.

Prg hace una cosa muy curiosa, que es tener varios .dcb compilados e ir invocándolos, quizás puedas dejar el tablero en un .dcb ya compilado para evitar la tediosa espera cada vez que haces un cambio y compilas.

En fin, espero que te sirva de algo :P

En memoria dinamica estoy completamente pez :S. Cuando pinto pinto solo la info de los tiles que aparecen en pantalla, pero de todos modos la info de los demas tiles tambien debe existir :S

Despues de compilado, la cosa va sin problemas. El problema está en los minutos que tarda en compilar antes :P

Lo de tener varios .dcb puede ser una solucion.. aunque tengo dudas. Podría compilar un programa que solo declarase el tablero?  Como invoco desde mi programa a otro .dcb? en esas cosas voy bastante pez tambien..XD

Muchas gracias y un saludo!

SplinterGU

Quote from: osk on January 14, 2010, 02:28:29 AM
Quote from: SplinterGU on January 14, 2010, 02:19:37 AM
primero, no uses byte o tipos menores a 32bits... lo hace mas lento.

donde lo estas compilando, a mi me tarda 0 segundos en compilar tu ejemplo.

¿No importa, pues, desaprovechar memoria ram? Ya se sabe que hoy en día es casi infinita, pero a mi siempre me enseñaron que los tipos debían de ser acorde al tamaño del dato que queríamos guardar...Pero vaya, da lo mismo supongo.

La cosa es que los actuales procesadores manejan mejor el alineamiento de acorde a el tamaño de palabra del procesador, en la mayoria de los casos 32 bits... por eso va mas rapido...

ahora voy a probar ponerle 2048x2048 a ver que pasa
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

Hombre, ten en cuenta que cuando hagas el programa/juego, el DCB lo vas a pasar ya compilado, así que si te tarda 3 minutos en compilar y 0 en ejecutar, no habría problema.
Es como compilar una Gentoo (desde que me hicieron aquella gracia, siempre la uso de ejemplo): puedes tirarte tres horas esperando, pero luego tienes un SO super-eficiente para tu máquina.

Como soluciones, mmm, podrías intentar simplificar un poco los campos, desechando variables que no uses o que puedas averiguar mediante otras. Puedes unir variables en un tipo de dato más grande y usar máscaras para leer los datos (como los flags pero con más bits)...
Supongo que estamos hablando de la estructura que almacena los datos, ¿no? no de la representación.

Para mirar el tema de punteros, tienes el extenso tutorial de OSK (recomendado) o los tutoriales de Windgate (creo que ha tratado ese tema ¿no?). Si no, tienes una ligera introducción que hice hace tiempo en un hilo:
http://forum.bennugd.org/index.php?topic=988.0
Espero que te sirva.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

el problema no es solo la compilacion, es la grabacion, son 188mb de dcb... :P

a 2048x2048 me tardo 4 segundos...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

WHAAAAAATTTT?????????
¿0'1 Gigowatios?.... digooo ¿188MB de DCB? ¿Están bien las funciones de reserva de memoria? juer, amigo, ve pensando en cambiar la forma de almacenar los datos ;D ;D ;D

De todas formas, 2 o 3 minutos para compilar me parece excesivo (aunque claro, con el maquinón que gasta Splinter tampoco podemos comparar ;D) a menos que tu PC funcione mediante un hamster corriendo en una rueda.

Tambien puedes pensar (se me olvidó decírtelo antes) en usar varios arrays para almacenar la información. En mi sistema de tiles uso dos mapas: uno con los valores de los graphs y otro para las durezas, cada uno permite varias capas y va todo super bien.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

maquinon el mio??? dualcore (ni core 2 duo) de 1.66mhz con linux a 32bits (ni siquiera el lindo 64 bits)... eso es un maquinon???
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

A ver... Yo tengo ahora mismo un i7 de esos y las matrices GORDAS tardan en compilar MUCHO xD

El maquinón es lo de menos.

Lou, lo de tener varios .dcb es una "magia" que conoce Prg, mándale un privado para que se una a este hilo, yo también quiero aprender sobre el tema.

Sobre usar memoria dinámica, para cosas así de grandes sería lo ideal, pero no lo "agradable", con Bennu he usado memoria dinámica y funciona que da verdadero placer, pero programar así no es algo que se haga por gusto... Desgraciadamente ahora mismo no hay NADA sobre ello en mis tutoriales... Pero es una buena sugerencia, lo tendré en cuenta.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

lou

Quote from: Drumpi on January 14, 2010, 11:35:27 PM
Hombre, ten en cuenta que cuando hagas el programa/juego, el DCB lo vas a pasar ya compilado, así que si te tarda 3 minutos en compilar y 0 en ejecutar, no habría problema.

Eso es lo que tenia pensao. Aunque me muera cada vez que tenga que compilar el programa yo, cuando lo pase por ahi debería ejecutarse rapido.
COMPROBADO. Una matriz de 1024x1024  me a tardado en compilar como 4 o 5 minutosXD, pero luego al ejecutarla a tardado -1.

Quote from: Drumpi on January 14, 2010, 11:35:27 PM
Como soluciones, mmm, podrías intentar simplificar un poco los campos, desechando variables que no uses o que puedas averiguar mediante otras. Puedes unir variables en un tipo de dato más grande y usar máscaras para leer los datos (como los flags pero con más bits)...
Supongo que estamos hablando de la estructura que almacena los datos, ¿no? no de la representación.
Lo de simplificar los datos lo tengo ya pensao, estoy en ello:P, quitar varios booleanos y comprobar con otras variables, me quito como 5 o 6 int por campo.
Lo de las máscaras imagino que se haria a traves de código, asi que lo que gano en tiempo de compilacion igual lo pierdo en tiempo de ejecucion asi que, por el momento, lo dejo en la lista de posibles.
La estructura solo almacena datos, el programa es el que se encarga luego de pintar por pantalla lo que representan esos datos.

Quote from: Drumpi on January 14, 2010, 11:35:27 PM
Para mirar el tema de punteros, tienes el extenso tutorial de OSK (recomendado) o los tutoriales de Windgate (creo que ha tratado ese tema ¿no?). Si no, tienes una ligera introducción que hice hace tiempo en un hilo:
http://forum.bennugd.org/index.php?topic=988.0
Espero que te sirva.
Le echaré u ojo. Gracias!:D

Quote from: Drumpi on January 14, 2010, 11:58:55 PM
Tambien puedes pensar (se me olvidó decírtelo antes) en usar varios arrays para almacenar la información. En mi sistema de tiles uso dos mapas: uno con los valores de los graphs y otro para las durezas, cada uno permite varias capas y va todo super bien.
Con eso no estaríamos en las mismas? es decir, si en vez de usar una matriz tocha, uso dos o tres matrices menos tochas, no tendría que compilar lo mismo, y por tanto, tardar lo mismo?

Quote from: Windgate on January 15, 2010, 02:52:53 AM
Lou, lo de tener varios .dcb es una "magia" que conoce Prg, mándale un privado para que se una a este hilo, yo también quiero aprender sobre el tema.

Ahora el mando un MP y le digo a ver si nos ilumina un poco ^^

Muchas gracias a todos!