Tamaño zona de juego Churrera

Chit chat general. Habla con los MojonTwins y con los amigos de los MojonTwins. Reza a Vah-ka. Delinque. Aviso: está PROHIBIDO tirarse peos fuerte. Si les cortas el pescuezo, vale.

Moderador: na_th_an

Avatar de Usuario
elborra
Mensajes: 209
Registrado: Dom, 12 Ene 2014, 14:37

Tamaño zona de juego Churrera

Mensajepor elborra » Jue, 23 Ene 2014, 19:34

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.
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Tamaño zona de juego Churrera

Mensajepor na_th_an » Jue, 23 Ene 2014, 20:25

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...
Como diría Rorshach: "Urm..."
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: Tamaño zona de juego Churrera

Mensajepor na_th_an » Jue, 23 Ene 2014, 20:26

Por cierto, aquí tienes el código fuente de las utilidades de la churrera: viewtopic.php?p=41536#p41536
Como diría Rorshach: "Urm..."
Avatar de Usuario
radastan
Mensajes: 692
Registrado: Vie, 20 Ago 2010, 12:54
Contactar:

Re: Tamaño zona de juego Churrera

Mensajepor radastan » Jue, 23 Ene 2014, 21:07

¿Sería posible una zona de juego de 10x10 tiles? es para un mini proyecto que tengo en mente...
Avatar de Usuario
elborra
Mensajes: 209
Registrado: Dom, 12 Ene 2014, 14:37

Re: Tamaño zona de juego Churrera

Mensajepor elborra » Vie, 24 Ene 2014, 01:47

$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.