PongPong; 20160201

Soy King Disperso.

Llevo tiempo queriendo hacer esto, y voy a ver si lo puedo hacer rápido: juego fácil, rápido y divertido construido como si fuese un hack chino de Sir Ababol para NES. Y poco más. Me inventé un título y lo traduje a chino, y ahora se me ha olvidado qué significaba, lo que hace que esto sea aún mejor.

He hecho algunos gráficos y un poco de mapa. Si consigo montar eso con el motor de SA tal cual, tendré el primer hito. Luego tendré que cambiar mucho el gameplay.

Vamos al lío.

~~

Como siempre, montar un proyecto nuevo es mucho trabajo (muchas cosas que hay que dejar listas antes de ponerse a compilar, pero que, por suerte, sólo hay que hacer una vez). Ahora mismo lo tengo todo patas arriba porque, además, he decidido hacerlo todo con las últimas versiones de cc65/neslib que tengo para así ahorrar algún que otro ciclo y algún que otro byte.

Pero creo que ya vale por hoy… Y por unos cuantos días. Este proyecto es mi on – hold – rellenador. Pero es que he hecho unos tiles y unos sprites la mar de chulos.

~~

Ideas apunten (antes de echar el cierre por hoy): Aunque el area de scroll mapeado efectiva es de 10 tiles de alto, el resto de la pantalla la rellenaré con tiles a través de las dos nametables: las primeras lineas, por encima del area de juego, serán cielo. Las lineas inferiores, por debajo del area de juego, tierra. Si pre-relleno las dos nametables con esta mierda, luego scrollearán con la parte del mapaque sí se actualiza y dará todo el pegow.

Luego haré que el ATTR por arriba siempre salga 0 para que podamos “salirnos” del mapa por arriba – O, mejor aún (aunque creo que esto era así, me acaba de venir el flash): ATTR(x, y) con y < 0 vale lo mismo que ATTR(x,0). Así, del tirón.

Intentaré hacerlo como con Super Uwol, en un #define, aunque aquí la expresión es algo más compleja.

Sea x en metatiles, hay que mirar en la columna # x / 2 del mapa. Esto tiene su orden paranoia. La función original en Sir Ababol es esta:

unsigned char __fastcall__ attr (unsigned char x, unsigned char y) {
	// This function gets called a lot, but I can't think on a way to 
	// make this run faster :-/
	
	if (y > 10) y = 0;		// Don't ask ... :~)
	if (y > 9) return 0;
	
	// Calculate address in map data.
	precalc1 = (x >> 1);
	work_idx = (unsigned char *) (
		map_plus_offset + 
		(precalc1 << 4) + (precalc1 << 3) + precalc1
	);
	work_idx += (x & 1) + (y << 1);
	
	// Get metatile
	t = (*work_idx);
	
	// Return metatile behaviour
	return behaviours [t];
}

Pues sí, estaba hecho: si y > 10 -> y = 0. Al ser “y” un unsigned char, bajando de 0 se pasa a 0xff, etc. Si nos hemos salido por abajo, según los valores de las ecuaciones de movimiento, y no puede ser otro que 10, ya que justo ahí se detecta el cambio de tira (aunque en este juego NO HAY cambio de tira y eso nos lo podemos fumar).

Luego precalcula x / 2, y a partir de ahí multiplica por 25 para obtener el número de columna. A eso último suma el desplazamiento dentro de la columna.

No sé si hacer un inline con esto no será un poco overkill. La expresión podría ser bastante heavy. De hecho, no me sale.

El __fastcall__ es una cagada porque la función es en C. Si la hiciese en ensamblador, a lo mejor, pero aún no me atrevo a hacer ese tipo de kung fu. O puedo dejarlo para más adelante, por si acaso saliese.

En el paso de parámetros se pierde bastante tiempo. Como el motor de movimiento lo voy a cambiar porque usa el modelo antiguo y lento de pasar a tiles y comprobar los tiles dependiendo si estamos alineados o no (MK1), quizá pueda fumarme el paso de parámetros. Si hago que siempre quiera comprobar los atributos sobre tx, ty (por ejemplo), precalculando tx y ty (que tengo que hacerlo), llamo a calc_attr () sin atributos y obtengo el resultado.

En todas las colisiones, que yo recuerde, se comprueban dos puntos. Puedo hacer así:

void attr (void) {
	precalc1 = (tx1 >> 1);
	at1 = behaviours [*((unsigned char*) (
		map_plus_offset + 
		(precalc1 << 4) + (precalc1 << 3) + precalc1 + 
		(tx1 & 1) + 
		(ty1 << 1) 	))]; 	precalc1 = (tx2 >> 1);
	at2 = behaviours [*((unsigned char*) (
		map_plus_offset + 
		(precalc1 << 4) + (precalc1 << 3) + precalc1 + 
		(tx2 & 1) + 
		(ty2 << 1)
	))];
}

Me ahorro todo el paso de parámetros y luego sólo tengo que usar at1 y at2 en las comprobaciones. Creo que así lo aceleraré bastante.

El scroll también lo voy a acelerar. Incluso siguiendo el mismo paradigma, usando las escritras secuenciales que tiene ahora neslib seguro que ahorro un montón de ciclos. De hecho, podría plantearme dejarme de zarandajas y ordenes raros y pintar las tiras enteras de arriba a abajo, que sería más rápido. Con los atributos precalculados y almacenados en el mapa, podría ser trivial.

No, si al final me fliparé y terminaré reescribiéndolo todo XD

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s