Página 1 de 1

Tamaño zona de juego Churrera

Publicado: Jue, 23 Ene 2014, 19:34
por elborra
Buenas again,
Como creo que esta propuesta/consulta es genérica la saco de mi hilo :cheer:

Hay veces que quearmos que la zona de juego (cada pantalla) sea de un tamaño menor a la definida en la churrera (sobre todo para juegos en vista "genital" :P de los que se estan cociendo por aquí tipo mazmorra), ya que nuestros mapas serán de menos tiles por pantalla.

El caso es que yo he estado modificando del engine lo justo para poder definir cualquier otro tamaño en lugar del 15x10. Probando con otros tamaños me gustaba la combinación 13x9 que a priori no reduce mucho la pantalla pero son 33 tiles menos por cada pantalla que no son nada despreciables :D

La cuestión es que esto me ha llevado a darme cuenta que tanto la utilidad de mapcnv como las rutinas del motor no estan preparadas para los casos donde el mapa sea packed y el ancho*alto de la pantalla sea un número inpar de tiles (13x9=117). El problema de hacer el mapa packed es que cada byte representa 2 tiles esto implica que una pantalla formada por un número impar de tiles compartiría el último byte para el último tile de esa pantalla y el primero de la siguiente; o quizás despreciar el medio byte sobrante. Pero ninguno de los dos casos se contempla en la aplicación mapcnv (a pesar de que si acepta cualquier valor de entrada, aunque ya se que no fué pensada para encontrarse con un garrulo como yo); independientemente también habría que cambiar parte del motor para gestionarlo. Teniendo en cuenta que podemos generar un mapa.h con alguna de estas dos características (yo lo estoy haciendo en php que es lo que tenía más a mano :oops:, pero he acabado generando el mismo mapa que me crearía mapcnv :?: ). Respecto a la marte de motor no me queda muy claro como gestionarlo en el juego, creo que no habría que cambiar nada o meterle muy poca mano.

El lío de monte Pío esta aqui:$this->bbcode_second_pass_code('', '// Mapa tipo PACKED
if (!(gpit & 1)) {
gpc = *map_pointer ++;
gpd = gpc >> 4;
} else {
gpd = gpc & 15;
}')Pero tengo que decir que me pierdo un poco...más que nada en compresión entre tanto código y tanto nombre de variable (no sólo por el trocito este) al final acabo hacíendome un lio, podriaís decirme que quereis decir con gpit, gpc y gpd (y no me digas que son variables jajaja, lo que me refiero es que representan)... Ej: gpit: "gráfico para individuos tontunos", ya me entendeís (ya tengo una idea pero saber exactamente la nomenclatura me ayudará para otras partes del código. Respecto a este trozo entiendo que compueba si es un número par o impar de tile para tomar el valor alto o bajo del byte apuntado por map_pointer y calcular su valor según su "peso". Por cierto:$this->bbcode_second_pass_code('', 'gpc = *map_pointer ++;')es simplemente que gpc es igual al valor apuntado por map_pointer+1 y map_pointer sale incrementado, ¿no?

En cualquier caso ya me decis que opinais o si los maestros me dicen de alguna aproximación mejor al problema.

Por si alguién se anima también encontré a posteriori (sino se si hay versión más nueva) las fuentes de las utilidades de la churrera en un hilo del foro aquí.

Seguiré a ello cuanto saque un poquito de tiempo y sino al finde que llevo una semana. En cuanto saque algo semi-definitivo pasaré por aquí el engine.h y config.h modificados para tamaños de zona de juego genéricos para testearlo (yo no me fio de mi ni un pelo) y hagais lo que os venga en gana con él.

Re: Tamaño zona de juego Churrera

Publicado: Jue, 23 Ene 2014, 20:25
por na_th_an
En el motor de la churrera se quebranta la regla número uno de la programación estructurada por doquier: casi todas las variables son globales y además se reutilizan para diferentes cosas. Esto es una patada a todo lo que el señor Dyjkstra perdió la vida intentando establecer, pero es necesario cuando tienes pocos megahertzios y poca memoria. El acceso a una variable global es más rápido y genera menos código que el acceso a una variable local, ya que una variable global no es más que un espacio en memoria (que se referencia con su dirección) y una variable local es un valor para el que hay que hacer sitio en la pila y luego acceder indirectamente.

Esas variables de ahí se reutilizan por todo el código y quieren decir cosas muy diferentes dependiendo de donde se estén usando.

En concreto, en la parte que desempaqueta la pantalla y la dibuja a la vez, es muy sencillo:

$this->bbcode_second_pass_code('', ' if (!(gpit & 1)) {
gpc = *map_pointer ++;
gpd = gpc >> 4;
} else {
gpd = gpc & 15;
}')

"gpit" itera de 0 a 149, ya que la pantalla tiene 150 tiles. Es el índice del bucle principal de desempaquetado / dibujado.

Como estamos guardando dos tiles por cada byte, tengo que ver cómo extraer el actual. "gpit & 1" vale 0 si gpit es par, o 1 si es impar. Si es impar, extraigo un nuevo byte de map_pointer, lo guardo en gpc, e incremento map_pointer, en ese orden:

$this->bbcode_second_pass_code('', 'gpc = *map_pointer ++;')

Aquí el postincremento (++) de map_pointer tiene menos prioridad que el acceso (*), así que primero se accede a lo que hay en map_pointer, y luego se incrementa. Es como si hiciésemos en BASIC algo así como LET gpc = PEEK map_pointer: LET map_pointer = map_pointer + 1.

En el caso de estar en posición par, se extrae el tile de la parte alta del dato leído y se almacena en gpd:

$this->bbcode_second_pass_code('', 'gpd = gpc >> 4;')

Eso se queda con los cuatro bits más altos que hemos leído de map_pointer.

La siguiente vuelta del bucle, (gpit & 1) valdrá 1 y entrará en la otra rama del if. En este caso, se extrae el tile de la parte baja del dato leído y se almacena en gpd:

$this->bbcode_second_pass_code('', 'gpd = gpc & 15;')

Si te fijas, sólo se lee de map_pointer y se incrementa a la hora de leer los datos pares. De esa forma map_pointer avanza a la mitad de velocidad que gpit: mientras gpit cuenta de 0 a 149, map_pointer sólo se incrementará 75 veces, que son los bytes que ocupa cada pantalla empaquetada.

Luego se utiliza gpd para pintar el tile y rellenar el par de buffers necesarios.

Soy consciente de que el código es bastante ilegible, pero es que está optimizado hasta niveles insanos. Tendrías que ver la última versión sobre la que estamos trabajando...

Re: Tamaño zona de juego Churrera

Publicado: Jue, 23 Ene 2014, 20:26
por na_th_an
Por cierto, aquí tienes el código fuente de las utilidades de la churrera: viewtopic.php?p=41536#p41536

Re: Tamaño zona de juego Churrera

Publicado: Jue, 23 Ene 2014, 21:07
por radastan
¿Sería posible una zona de juego de 10x10 tiles? es para un mini proyecto que tengo en mente...

Re: Tamaño zona de juego Churrera

Publicado: Vie, 24 Ene 2014, 01:47
por elborra
$this->bbcode_second_pass_quote('elborra', 'R')especto a este trozo entiendo que compueba si es un número par o impar de tile para tomar el valor alto o bajo del byte apuntado por map_pointer y calcular su valor según su "peso". Por cierto:
Código:
gpc = *map_pointer ++;
es simplemente que gpc es igual al valor apuntado por map_pointer+1 y map_pointer sale incrementado, ¿no?
$this->bbcode_second_pass_quote('na_th_an', '
')...
....
Soy consciente de que el código es bastante ilegible, pero es que está optimizado hasta niveles insanos. Tendrías que ver la última versión sobre la que estamos trabajando...
Ya me lo imaginaba, pero quizás tenian algún significado, thanks por verificarmelo igualmente. En cuestión del código sólo me quedaba la duda de si *map_pointer se incrementaba antes o después de la operación. Si no recuerdo ahora mal en C o C++ se podía hacer ++var para resolver primero el incremento pero no se si con punteros (++*map_pointer) es válido o una salvajada.

Más que nada, y por falta de sueño (la verdad es que el post me salió un poco extraño), lo que preguntaba es si una vez creada una utilidad que genere un mapa.h válido para pantallas de tiles impares (de cualquiera de las 2 formas sugeridas) habría que modificar mucho o poco de ese código y ante tan eventualidad queria asegurarme que entendía perfectamente cada una de las lineas de p a pa.

$this->bbcode_second_pass_quote('radastan', 'Â')¿Sería posible una zona de juego de 10x10 tiles? es para un mini proyecto que tengo en mente...
No habría ningún problema, además al tratarse de un número par de tiles no existiría el problema que estoy planteando. En mi caso, como llegué al punto donde el mapa.h generado no era válido no he verificado el movimiento de los enemigos ni las balas respecto al cambio de tamaño de la pantalla; y sólo para 48K y vista cenital (lo cual implica que tampoco he probado saltos); pero el resto está funcional (aunque con tiempo adaptaré el resto del código para los demás casos). Actualmente he añadido 5 constantes en config.h$this->bbcode_second_pass_code('', '#define SCR_W 13 // Ancho pantalla en tiles
#define SCR_H 9 // Alto pantalla en tiles
#define SCR_WH 117 // Alto*ancho
#define PLAYER_MAX_X 12288 // x máxima zona de juego ( (SCR_W-1)*16 ) * 64
#define PLAYER_MAX_Y 8192 // y máxima zona de juego ( (SCR_H-1)*16 ) * 64')las 3 últimas por el momento las definí porque la intuición me dijo que era mejor definirlas como constantes que ir realizando las operaciones a cada iteración.

Re: Tamaño zona de juego Churrera

Publicado: Vie, 24 Ene 2014, 08:00
por na_th_an
Lo principal que tendrías que modificar sería el cálculo de dónde empezar a leer la pantalla. Al principio de draw_scr_background:

$this->bbcode_second_pass_code('', '#ifdef UNPACKED_MAP
map_pointer = mapa + (n_pant * 150);
#else
map_pointer = mapa + (n_pant * 75);
#endif')

75 bytes sale de dividir 150/2 porque aprovecho todo. En tu caso, que es impar, sería X/2+1 para tomar en cuenta el último byte, que está relleno hasta la mitad sólamente, con X el número de tiles (SCR_W * SCR_H).

Por otro lado, las operaciones con constantes siguen siendo constantes, así que el compilador se encarga de resolverlas y colocar ahí un número. Poner "SCR_W*SCR_H" por ejemplo no hace que el programa tenga que multiplicar cada vez.

Sobre los incrementos, para incrementar antes y luego leer se podría poner *(++ pointer), por ejemplo, aunque he visto compiladores que se lo tragan sin paréntesis. No sé si el compilador de z88dk es capaz, porque nunca lo he probado :D

@Radas: lo que dice elborra: Al ser un número par de tiles puedes usarlo sin problemas en modo packed o unpacked siempre que cambies el código del motor para tener en cuenta el ancho menor.

Re: Tamaño zona de juego Churrera

Publicado: Vie, 24 Ene 2014, 10:11
por elborra
$this->bbcode_second_pass_quote('na_th_an', 'L')o principal que tendrías que modificar sería el cálculo de dónde empezar a leer la pantalla. Al principio de draw_scr_background:
$this->bbcode_second_pass_code('', '#ifdef UNPACKED_MAP
map_pointer = mapa + (n_pant * 150);
#else
map_pointer = mapa + (n_pant * 75);
#endif')
75 bytes sale de dividir 150/2 porque aprovecho todo. En tu caso, que es impar, sería X/2+1 para tomar en cuenta el último byte, que está relleno hasta la mitad sólamente, con X el número de tiles (SCR_W * SCR_H).
Joer, como se ve que estoy espesito.. claaaaro. Ya lo tenía pasado a genérico con map_pointer = mapa + (n_pant * SCR_WH>>1); le añadiré el +1...
$this->bbcode_second_pass_quote('na_th_an', '
')Por otro lado, las operaciones con constantes siguen siendo constantes, así que el compilador se encarga de resolverlas y colocar ahí un número. Poner "SCR_W*SCR_H" por ejemplo no hace que el programa tenga que multiplicar cada vez.
Ok, esto no lo sabía. Entonces para:$this->bbcode_second_pass_code('', '#define PLAYER_MAX_X 12288 // x máxima zona de juego ( (SCR_W-1)*16 ) * 64
#define PLAYER_MAX_Y 8192 // y máxima zona de juego ( (SCR_H-1)*16 ) * 64')¿También se quedaría como constante al compilar? supongo que si...de todas formas lo probaré y listo

Re: Tamaño zona de juego Churrera

Publicado: Vie, 24 Ene 2014, 11:07
por na_th_an
Sí, se quedaría como constante. Yo lo uso constantemente.

Vale, es un chiste muy malo :lol:

Re: Tamaño zona de juego Churrera

Publicado: Sab, 25 Ene 2014, 10:52
por elborra
Todo perfecto y rulando ^^. Gracias una vez más :D

$this->bbcode_second_pass_quote('na_th_an', 'S')í, se quedaría como constante. Yo lo uso constantemente.

Vale, es un chiste muy malo :lol:
Despues de este chiste voy a necesitar 1024 Gigapeutas ... :ayayay:


Edito:
Voy a ir dejando por este hilo los archivos definitivos que he ido modificando con el fin de gestionar con la Churrera un tamaño de zona de juego distinta, dichas modificaciones no alteran el resultado para anteriores juegos (zona de juego 15x10):

MapCnv.zip (generador de mapas) Fuentes + ejecutable
Añadido el caso para mapas packed formados por pantallas con un numero impar de tiles)

msc.zip (motor de clausulas) Fuentes + ejecutable
Modificado el tratamiento de SET_TILE para map_buffer y map_attrib

En cualquier caso además se necesitará modificar otros ficheros en /dev. Como hasta ahora sólo he modificado las carácterísticas de la churrera que voy a usar en el juego que estoy desarrolando no se hasta que punto soportaría el resto de ellas. Hasta que no haya hecho las suficientes pruebas y testeos no subiré "oficialmente" las modificaciones. En cualquier caso si no me equivoco lo único que se me ha quedado fuera es el modo128K y los saltos.