=======
3.99.3c
=======

Motor de Items
--------------

Se puede usar items y se puede hacer que el usuario los pueda seleccionar con la tecla "Z".
Para activarlos slo hay que tener activado el scripting y definir una seccin ITEMSET
al principio del script parecida a esta:

	ITEMSET
		# Nmero de huecos:
		SIZE 6
		
		# Posicin x, y
		LOCATION 1, 21
		
		# Horizonta/vertical, espaciado
		DISPOSITION HORZ, 3
		
		# Color y caracteres para pintar el selector
		SELECTOR 66, 8, 9
		
		# Flag que contiene qu hueco est seleccionado
		SLOT_FLAG 20
		
		# Flag que contiene qu objeto est en el hueco seleccionado
		ITEM_FLAG 21
	END

Luego tendremos comprobaciones y comandos destinadas a manejar los items:

* IF PLAYER_HAS_ITEM t      
    Descripcin: Evaluar a CIERTO si el jugador tiene el item de tile T en su inventario.
    Opcode: 01 x
    
* IF PLAYER_HASN'T_ITEM x
    Descripcin: Evaluar a CIERTO si el jugador NO tiene el item de tile T en su inventario.
    Opcode: 02 x
    
OJO! Las dos anteriores meten bastante cdigo de intrprete. Es mejor no usarlas si
se puede evitar. Hay formas mejores de gestionar el inventario:

* IF SEL_ITEM = t
	Descripcin: CIERTO si el item seleccionado es T
	Opcode: 10 ITEM_FLAG t
	El cdigo generado equivale a IF FLAG ITEM_FLAG = t
	
* IF SEL_ITEM <> t
	Descripcin: CIERTO si el item seleccionado no es T
	Opcode: 13 ITEM_FLAG t
	El cdigo generado equivale a IF FLAG ITEM_FLAG <> t
	
* IF ITEM n = t
	Descripcin: CIERTO si en el slot N est T
	Opcode: 04 n t
	
* IF ITEM n <> t
	Descripcin: CIERTO si en el slot N est T
	Opcode: 05 n t
	
* SET ITEM n = t
    Descripcin: Asigna el item t al slot n
    Opcode: 00 x n
    
* REDRAW_ITEMS
	Descripcin: fuerza un redibujado de los items
	Opcode: E7

Para ms info, visita este hilo del foro:

http://www.mojontwins.com/mojoniaplus/viewtopic.php?f=9&t=1581

Disparo / pisar enemigos deshabilitable
---------------------------------------

Se aade la posibilidad de habilitar el disparo / pisar enemigos segn el valor
de una flag (para poder usarlo, disparo / pisar enemigos deben estar activados
en el motor, of course):

#define PLAYER_CAN_KILL_FLAG   1
#define PLAYER_CAN_FIRE_FLAG   1

Por ejemplo, imaginemos que decides que el flag que controle este comportamiento 
es el flag 5. Primero definiramos esto en config.h:

	#define PLAYER_CAN_KILL_FLAG   5      

Luego, en el script, nos aseguraramos de que ese flag vale 0 al principio del juego
(o 1, si queremos que se pueda matar a los enemigos desde el principio):

	ENTERING GAME
	    IF TRUE
	    THEN
	        SET FLAG 5 = 0
	    END
	END

Imagina que queremos que el jugador pueda empezar a pisar a los enemigos cuando 
coja un objeto representado por el tile 24 y situado en la pantalla 6, posicin 
(7, 5). Podramos hacer algo parecido a esto:

	ENTERING SCREEN 6
	    # Si no hemos cogido el objeto lo dibujamos
	    IF FLAG 5 = 0
	    THEN
	        SET TILE (7, 5) = 24
	    END
	END
	
	PRESS_FIRE AT SCREEN 6
	    # Si pulsamos ACCION sobre el objeto...
	    IF FLAG 5 = 0
	    IF PLAYER_TOUCHES 7, 5
	    THEN
	        # Lo borramos de la pantalla
	        SET TILE (7, 5) = 0
	        # Activamos la habilidad de matar enemigos
	        SET FLAG 5 = 1
	    END
	END

=======
3.99.3b
=======

Mnima revisin. Se arregla lo necesario para poder tener juegos de 128K con un
slo nivel (es decir, usar MODE_128K sin COMPRESSED_LEVELS).

Ahora mismo hay dos ejemplos que te pueden ayudar si quieres hacer un juego de 128K:

- Goku Mal: 128K con niveles comprimidos. Ver este doc y los fuentes del juego.
- Las nuevas aventuras de Dogmole Tuppowsky: 128K con un slo nivel, ms info en
el foro de mojonia.

Adems, en spare he aadido el archivo extern-textos.h cuyo contenido podis usar
en extern.h si queris una forma sencilla de mostrar textos en pantalla mediante el
comando EXTERN n del script.

======
3.99.3
======

Tiles animados
--------------

Si se define:

#define ENABLE_TILANIMS			32		// If defined, animated tiles are enabled.
										// the value especifies firt animated tile pair.

En config.h, los tiles >= que el ndice especificado se consideran animados.
En el tileset, vienen por parejas. Si se define, por ejemplo, "46", entonces
la nica pareja de tiles 46 y 47 estar animada. El motor los detectar y cada
frame har que uno de los tiles 46 cambie de estado.

Puede haber un mximo de 64 tiles animados en la misma pantalla. Si pones ms,
petar.

Modo 128K
---------

Tienes que hacer mucho trabajo manual con esto. Lo siento, pero es as. En primer
lugar habr que crear un make.bat que construya todo lo que necesitas. Para ello
puedes basarte en el archivo spare/make128.bat y adecuarlo a tu proyecto.

El modo 128K es igual que el 48K pero usar WYZ Player y adems soporta varios niveles.
No podrs tener niveles ms largos, pero s podrs tener varios niveles. 

Para usarlo, necesitas activar tres cosas en config.h:

#define MODE_128K						// Experimental!
#define COMPRESSED_LEVELS				// use levels.h instead of mapa.h and enems.h (!)
#define MAX_LEVELS			4			// # of compressed levels

En MAX_LEVELS tienes que especificar el nmero de niveles que vas a usar.

En churromain.c hay que cambiar la posicin de la pila y colocarla por debajo
del binario principal:

#pragma output STACKPTR=24299

Luego hay que modificar levels128.h, que es donde se define la estructura de niveles
y que se incluye en modo 128K. Ah vers un array levels, con informacin sobre los
niveles. En principio se incluye muy poca informacin:

// Level struct
LEVEL levels [MAX_LEVELS] = {
	{3,2},
	{4,3},
	{5,4},
	{6,5}	
};

El primer valor es el nmero de recurso (ver ms adelante) que contiene el nivel. 
El segundo valor es el nmero de la cancin en WYZ PLAYER que debe sonar mientras
se juega al nivel.

Para preparar un nivel tienes que usar la nueva utilidad buildlevel.exe que hay
en /utils. Esta utilidad toma los siguientes parmetros:

$ buildlevel mapa.map map_w map_h lock font.png work.png spriteset.png 
extrasprites.bin enems.ene scr_ini x_ini y_ini max_objs enems_life behs.txt level.bin

   * mapa.map Es el mapa de mappy
   * map_w, map_h Son las dimensiones del mapa en pantallas.
   * lock 15 para autodetectar cerrojos, 99 si no hay cerrojos
   * font.png es un archivo de 256x16 con 64 caracteres ascii 32-95
   * work.png es un archivo de 256x48 con el tileset
   * spriteset.png es un archivo de 256x32 con el spriteset
   * extrasprites.bin lo encuentras en /levels
   * enems.ene el archivo con los enemigos/hotspots de colocador.exe
   * scr_ini, scr_x, scr_y, max_objs, enems_life valores del nivel
   * behs.txt un archivo con los tipos de tiles, separados por comas
   * level.bin es el nombre de archivo de salida.
   
Cuando tengamos todos los niveles construidos, hay que comprimirlos con apack:

$ /utils/apacke.exe level1.bin level1c.bin
...

Cuando tengamos todos los niveles comprimidos, habr que crear las imagenes
binarias que se cargarn en las pginas de RAM extra. Para eso usamos la utilidad
librarian que hay en la carpeta /bin. De hecho, es buena idea trabajar en la
carpeta /bin para esto.

La utilidad librarian utiliza una lista list.txt con los binarios comprimidos
que debe ir metiendo en las imagenes binarias que irn en las pginas extra de 
RAM. Lo primero que tendremos que meter sern los archivos title.bin, marco.bin
y ending.bin, en ese orden. Si no tienes marco.bin debes usar un archivo de
longitud 0, pero debes especificarlo. Luego aadiremos nuestros niveles. Por
ejemplo:

title.bin
marco.bin
ending.bin
level1c.bin
level2c.bin
level3c.bin
level4c.bin

Ah hemos aadido cuatro niveles comprimidos.

Al ejecutar librarian, ir rellenando imagenes de 16K destinadas para ir en la
RAM extra. Primero crear ram3.bin, luego ram4.bin y finalmente ram6.bin, segn
vaya necesitando ms espacio.

Tambin generar el archivo librarian.h, que tendremos que copiar en /dev. Aqu
podremos ver el nmero de recurso asociado a cada binario:

RESOURCE resources [] = {
   {3, 49152},   // 0: title.bin
   {3, 50680},   // 1: marco.bin
   {3, 50680},   // 2: ending.bin
   {3, 52449},   // 3: level1c.bin
   {3, 55469},   // 4: level2c.bin
   {3, 58148},   // 5: level3c.bin
   {3, 60842}   // 6: level4c.bin
};

Estos nmeros de recurso son los que tendremos que especificar en el array
levels que mencionamos ms arriba. En concreto, los recursos 3, 4, 5 y 6 son
los que contienen los cuatro niveles.

Con todo esto hecho y preparado, habr que montar la cinta. Para ello hay 
que crear un loader.bas adecuado (puedes ver un ejemplo en /spare/loader.bas)
y construir un .tap con cada bloque de RAM (de nuevo, el ejemplo en 
/spare/make.bat construye la cinta con binarios en RAM3 y RAM4).

Tambin necesitars RAM1.BIN para construir RAM1.TAP, conteniendo el player
de WYZ con las canciones. Para ello tendrs que modificar /mus/WYZproPlay47aZX.ASM
en /mus para que incluya tus canciones. Tienes un ejemplo en /spare.

Como ves, es un poco tedioso. Te recomiendo que construyas mini-proyectos en
48K segn vas haciendo los niveles, y que al final montes una versin 128K con
todo.

Adems, puedes usar el espacio extra para meter ms pantallas comprimidas, o
incluso cdigo para usar passwords para saltar directamente a los niveles.
Puedes ver ejemplos de todo esto en Goku Mal 128.

Hotspots tipo 3
===============

Hemos hecho esta modificacin, propuesta en el foro, fija a golpe de directiva.
Si defines

#define USE_HOTSPOTS_TYPE_3				// Alternate logic for recharges.

Las recargas aparecern nica y exclusivamente donde t las coloques, usando
el hotspot de tipo 3.

Pausa / Abortar
===============

Si se define

#define PAUSE_ABORT						// Add h=PAUSE, y=ABORT

Se aade cdigo para habilitar la tecla "h" para pausar el juego y la tecla
"y" para interrumpir la partida. Si quieres cambiar la asignacin tendrs que
tocar el cdigo en mainloop.h

Mensaje al coger objetos
========================

Se se define

#define GET_X_MORE						// Shows "get X more" 

Aparecer un mensaje con los objetos que te quedan cada vez que coges uno.

-------------------------------------------------------------------------------

=========
3.99.2mod
=========

Esta fue una versin especial con una cosa que nos pidi Radastan, los...

Tiles animados
==============

Todo se basa en tilanim.h. Este archivo se incluye si se define en config.h la 
directiva ENABLE_TILANIMS. Adems, el valor de esta directiva es el que define 
el nmero de tile menor que se considera animado.

En tilanim.h hay, adems de la definicin de datos, dos funciones:

void add_tilanim (unsigned char x, unsigned char y, unsigned char t) 
se llama desde la funcin que pinta la pantalla actual si detecta que el tile 
que va a pintar es >= ENABLE_TILANIMS. Aade un tile animado a la lista de 
tiles.

void do_tilanims (void) se llama desde el bucle principal. Bsicamente 
selecciona un tile animado al azar entre todos los almacenados, le cambia el 
frame (de 0 a 1, de 1 a 0) y lo dibuja.

Para usarlo slo tienes que definir en config.h la directiva ENABLE_TILANIMS 
con el tile animado menor. Por ejemplo, si tus cuatro ltimas parejas de 
tiles (8 en total) son los animados, pon el valor 40. Luego, en el mapa, se 
tiene que poner el tile menor de la pareja, o sea, el tile 40 para 40-41, el 
42 para 42-43... Si no lo haces as pasarn cosas divertidas. El cdigo es 
(tiene que ser) minimal, no se comprueba nada, as que cuidao.

Por cierto, esto no se ha probado. Si lo pones en tu gego y se peta, danos
un toque.

-------------------------------------------------------------------------------

======
3.99.2
======

Venga, las churreras van saliendo como churros. Estamos que lo rompemos, y
se nos ocurren cosas nuevas todos los das. Las iremos metiendo a medida que
se nos ocurran gegos que las lleven.

Estas son las cosas nuevas que hay en esta versin de la churrera:

Temporizadores
==============

Se aade a la churrera un temporizador que podemos usar de forma automtica
o desde el script. El temporizador toma un valor inicial, va contando hacia
abajo, puede recargarse, se puede configurar cada cuntos frames se decrementa
o decidir qu hacer cuando se agota.

#define TIMER_ENABLE

Con TIMER_ENABLE se incluye el cdigo necesario para manejar el temporizador.
Este cdigo necesitar algunas otras directivas que especifican la forma de
funcionar:

#define TIMER_INITIAL		99	
#define TIMER_REFILL		25
#define TIMER_LAPSE 		32

TIMER_INITIAL especifica el valor inicial del temporizador. Las recargas de
tiempo, que se ponen con el colocador como hotspots de tipo 5, recargarn el
valor especificado en TIMER_REFILL. El valor mximo del timer, tanto para el
inicial como al recargar, es de 99. Para controlar el intervalo de tiempo que
transcurre entre cada decremento del temporizador, especificamos en TIMER_LAPSE
el nmero de frames que debe transcurrir.

#define TIMER_START

Si se define TIMER_START, el temporizador estar activo desde el principio.

Tenemos, adems, algunas directivas que definen qu pasar cuando el temporiza-
dor llegue a cero. Hay que descomentar las que apliquen:

#define TIMER_SCRIPT_0	

Definiendo esta, cuando llegue a cero el temporizador se ejecutar una seccin
especial del script, ON_TIMER_OFF. Es ideal para llevar todo el control del
temporizador por scripting, como ocurre en Cadverin.

//#define TIMER_GAMEOVER_0

Definiendo esta, el juego terminar cuando el temporizador llegue a cero.

//#define TIMER_KILL_0
//#define TIMER_WARP_TO 0
//#define TIMER_WARP_TO_X 	1
//#define TIMER_WARP_TO_Y 	1

Si se define TIMER_KILL_0, se restar una vida cuando el temporizador llegue a
cero. Si, adems, se define TIMER_WARP_TO, adems se cambiar a la pantalla
espeficiada, apareciendo el jugador en las coordenadas TIMER_WARP_TO_X y 
TIMER_WARP_TO_Y.

//#define TIMER_AUTO_RESET

Si se define esta opcin, el temporizador volver al mximo tras llegar a
cero de forma automtica. Si vas a realizar el control por scripting, mejor
deja esta comentada.

#define SHOW_TIMER_OVER	

Si se define esta, en el caso de que hayamos definido o bien TIMER_SCRIPT_0 o
bien TIMER_KILL_0, se mostrar un cartel de "TIME'S UP!" cuando el temporizador
llegue a cero.

Scripting:
----------

Como hemos dicho, el temporizador puede administrarse desde el script. Es
interesante que, si decidimos hacer esto, activemos TIMER_SCRIPT_0 para que
cuando el temporizador llegue a cero se ejecute la seccin ON_TIMER_OFF de
nuestro script y que el control sea total. 

Adems, se definen estas comprobaciones y comandos:

Comprobaciones:
---------------

IF TIMER >= x
IF TIMER <= x

Que se cumplirn si el valor del temporizador es mayor o igual o menor o igual
que el valor especificado, respectivamente.

Comandos:
---------

SET_TIMER a, b

Sirve para establecer los valores TIMER_INITIAL y TIMER_LAPSE desde el script.

TIMER_START

Sirve para iniciar el temporizador.

TIMER_STOP

Sirve para parar el temporizador.

---

Control de bloques empujables
=============================

Hemos mejorado el motor para que se pueda hacer ms cosas con el tile 14 de
tipo 10 (tile empujable) que simplemente empujarlo o que detenga la trayectoria
de los enemigos. Ahora podemos decirle al motor que lance la seccin PRESS_FIRE
de la pantalla actual justo despus de empujar un bloque empujable. Adems, el
nmero del tile que se "pisa" y las coordenadas finales se almacenan en tres
flags que podemos configurar, para poderlas usar desde el script para hacer 
comprobaciones.

Este es el sistema que se emplea en el script de Cadverin para controlar que
coloquemos las estatuas sobre los pedestales, por poner un ejemplo.

Recordemos lo que tenamos hasta ahora:

#define PLAYER_PUSH_BOXES 				
#define FIRE_TO_PUSH					

La primera es necesaria para activar los tiles empujables. La segunda obliga al
jugador a pulsar FIRE para empujar y, por tanto, no es obligatoria. Veamos 
ahora las nuevas directivas:

#define ENABLE_PUSHED_SCRIPTING
#define MOVED_TILE_FLAG 		1
#define MOVED_X_FLAG 			2
#define MOVED_Y_FLAG 			3

Activando ENABLE_PUSHED_SCRIPTING, el tile que se pisa y sus coordenadas se 
almacenarn en los flags especificados por las directivas MOVED_TILE_FLAG,
MOVED_X_FLAG y MOVED_Y_FLAG. En el cdigo que se muestra, el tile pisado se
almacenar en el flag 1, y sus coordenadas en los flags 2 y 3.

#define PUSHING_ACTION

Si definimos esta, adems, se ejecutarn los scripts PRESS_FIRE AT ANY y
PRESS_FIRE de la pantalla actual.

Recomendamos estudiar el script de Cadverin, el cual, adems de ser un buen
ejemplo del uso del temporizador y del control del bloque empujable, resulta
ser un script bastante complejo que emplea un montn de tcnicas avanzadas.

---

Comprobar si nos salimos del mapa
=================================

Es aconsejable poner lmites en tu mapa para que el jugador no se pueda
salir, pero si tu mapa es estrecho puede que quieras aprovechar toda la 
pantalla. En ese caso, puedes activar:

#define PLAYER_CHECK_MAP_BOUNDARIES

Que aadir comprobaciones y no dejar que el jugador se salga del mapa.
Ojo! Si puedes evitar usarlo, mejor: ahorrars espacio.

---

Tipo de enemigo "custom" de regalo
==================================

Hasta ahora habamos dejado sin cdigo los enemigos de tipo 6, pero 
hemos pensado que no nos cuesta poner uno, de ejemplo. Se comporta como
los murcilagos de Cheril the Goddess. Para usarlos, ponlos en el colo-
cador de enemigos como tipo 6 y usa estas directivas:

#define ENABLE_CUSTOM_TYPE_6			
#define TYPE_6_FIXED_SPRITE 	2		
#define SIGHT_DISTANCE			96

La primera los activa, la segunda define qu sprite va a usar (menos 1,
si quieres el sprite del enemigo 3, pon un 2. Sorry por la guarrada,
pero ahorro bytes). La tercera dice cuntos pxels ve de lejos el bicho.
Si te ve, te persigue. Si no, vuelve a su sitio (donde lo hayas puesto
con el colocador).

Esta implementacin, adems, utiliza dos directivas de los enemigos de
tipo 5 para funcionar:

#define FANTY_MAX_V             256	
#define FANTY_A                 12	

Define ah la aceleracin y la velocidad mxima de tus tipo 6. Si vas a 
usar tambin tipo 5 y quieres otros valores, s un hombre y modifica el
motor.

---

Configuracin de teclado / joystick para dos botones
====================================================

Hay gegos de vista lateral que se juegan mejor con dos botones. Si activas
esta directiva:

#define USE_TWO_BUTTONS

El teclado ser el siguiente, en vez del habitual:

A izquierda
D derecha
W arriba
S abajo
N salto
M disparo

Si se elige joystick, FIRE y M disparan, y N salta.

---

Disparos hacia arriba y en diagonal para vista lateral
======================================================

Ahora podrs permitir que el jugador dispare hacia arriba o en diagonal.
Para ello define esto:

#define CAN_FIRE_UP	

Esta configuracin funciona mejor con USE_TWO_BUTTONS, ya que as separamos
"arriba" del botn de salto.

Si no pulsas "arriba", el personaje disparar hacia donde est mirando. Si
pulsas "arriba" mientras disparas, el personaje disparar hacia arriba. Si,
adems, ests pulsando una direccin, el personaje disparar en la diagonal
indicada.

---

Balas enmascaradas
==================

Por velocidad, las balas no llevan mscaras. Esto funciona bien si el fondo
sobre el que se mueven es oscuro (pocos pixels INK activos). Sin embargo, 
hay situaciones en las que esto no ocurre y se ve mal. En ese caso, podemos
activar mscaras para las balas:

#define MASKED_BULLETS

