I - Brainstorming
=================

Tengo que almacenar clusulas y acciones. Lo primero que tengo que hacer, para intentar disear un formato sencillo, comn y compacto, es ver cuntos tipos de clusulas y cuntos tipos de acciones necesito, y qu tipos de clusulas y acciones voy a tener. Esto es lo primero. Vayamos por partes...

El tema de las clusulas es que cada script se compondr por un montn de estas comprobaciones, que podrn ser lanzadas de dos formas: al pulsar SPACE (accin) o al entrar en la pantalla. Luego tendr que ver cmo lo organizo para que sea eficiente recorrer las listas. Pero antes, lo primero es lo primero. 

Una clusula, en pseudolenguaje, puede ser tal que as. Por ejemplo, en la pantalla 8 pulsamos FIRE al lado de un ordenador (en el tile 7, 4) para meter un diskette (ITEM 3). Esto deber abrir una puerta en la pantalla 15. Para esto, usamos el FLAG 1

PRESS_FIRE AT SCREEN 8          ; Pulsamos ACCIN en la pantalla 8
    IF PLAYER_HAS_ITEM 3        ; Si tenemos el ITEM 3
    IF PLAYER_IN_X 6, 8         ; Posicin del jugador:
    IF PLAYER_IN_Y 3, 5         ; Esto define un rectngulo centrado en el tile 7, 4
    THEN                        ; Si se cumple todo lo de arriba...
        SET ITEM 3, 0           ; Perdemos el ITEM 3
        SET FLAG 1, 1           ; Ponemos FLAG 1 a 1
    END                         ; Fin de las acciones
END                             ; Fin de las comprobaciones

En la pantalla 15, deberemos comprobar el estado del flag 1 para eliminar la puerta, que ocupa los tiles (8, 4) y (9, 4):

ENTERING SCREEN 15              ; Entramos en la pantalla 15
    IF FLAG 1 = 1               ; Si FLAG 1 vale 1
    THEN                        ; Si se cumple todo lo de arriba...
        SET TILE (8, 4) = 0     ;
        SET TILE (9, 4) = 0     ; Ponemos el tile 0 en lugar de la puerta que hay en el mapa.
    END
END
    
Otra cosa importante: el compilador adems generar el cdigo del intrprete de forma que slo genere las comprobaciones de las clusulas y acciones utilizadas en el script, para ahorrar memoria.

Especiales:

Seccin							Se codifica como
ENTERING ANY					ENTERING #MAX_PANTS
ENTERING GAME					ENTERING #(MAX_PANTS+1)
PRESS_FIRE AT ANY               FIRE #MAX_PANTS
PLAYER_GETS_COIN				FIRE #(MAX_PANTS+1)
PLAYER_KILLS_ENEMY				FIRE #(MAX_PANTS+2)

I.0. Items
==========

Se puede usar items y se puede hacer que el usuario los pueda seleccionar con la tecla "Z".
Todo se hace en una seccin que debe definirse 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.

I.1. Tipos de clusulas (IFs)
=============================

* 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
    
* IF FLAG x = n
    Descripcin: Evaluar a CIERTO si el flag "x" vale "n"
    Opcode: 10 x n
    
* IF FLAG x < n
    Descripcin: Evaluar a CIERTO si el flag "x" < n
    Opcode: 11 x n
    
* IF FLAG x > n
    Descripcin: Evaluar a CIERTO si el flag "x" > n
    Opcode: 12 x n
    
* IF FLAG x <> n
	Descripcin: Evaluar a CIERTO si el flag "x" <> n
    Opcode: 13 x n
    
* IF FLAG x = FLAG y
    Descripcin: Evaluar a CIERTO si el flag "x" = flag "y"
    Opcode: 14 x y
    
* IF FLAG x < FLAG y
    Descripcin: Evaluar a CIERTO si el flag "x" < flag "y"
    Opcode: 15 x y
    
* IF FLAG x > FLAG y
    Descripcin: Evaluar a CIERTO si el flag "x" > flag "y"
    Opcode: 16 x y
    
* IF FLAG x <> FLAG y
    Descripcin: Evaluar a CIERTO si el flag "x" <> flag "y"
    Opcode: 17 x y
    
* IF PLAYER_TOUCHES x, y
    Descripcin: Evaluar a CIERTO si el jugador est tocando el tile (x, y)
    Opcode: 20 x y
    
* IF PLAYER_IN_X x1, x2
    Descripcin: Evaluar a CIERTO si el jugador est horizontalmente entre los tiles x1, x2
    Opcode: 21 x1 x2

* IF PLAYER_IN_Y y1, y2
    Descripcin: Evaluar a CIERTO si el jugador est verticalmente entre los tiles y1, y2
    Opcode: 22 y1 y2
    
* IF ALL_ENEMIES_DEAD
	Descripcin: Evaluar a CIERTO si todos los enemigos estn muertos.
	Opcode: 30

* IF ENEMIES_KILLED_EQUALS n
	Descripcin: Evaluar a CIERTO si el nmero de enemigos eliminados es n.
	Opcode: 31 n

* IF PLAYER_HAS_OBJECTS
	Descripcin: Evaluar a CIERTO si el jugador tiene objetos.
	Opcode: 40
	
* IF OBJECT_COUNT = n
	Descripcin: Evaluar a CIERTO si el jugador tiene N objetos.
	Opcode: 41 n

* IF NPANT n
	Descripcion: Evaluar a CIERTO si el jugador est en la pantalla n
	Opcode: 50 n

* IF NPANT_NOT n
	Descripcion: Evaluar a CIERTO si el jugador NO est en la pantalla n
	Opcode: 51 n
		
* IF JUST_PUSHED
	Descripcin: viene de acabar de empujar (!)
	Opcode: 60
	
* IF TIMER >= x
	Descripcin: el timer >= x
	Opcode: 70 x
	
* IF TIMER <= x
	Opcode: 71 x
	
* IF LEVEL = n
	Descripcin: CIERTO si el nivel actual es n
	Opcode: 80 n
	
* IF TRUE
	Descripcin: Siempre CIERTO
	Opcode: F0
	
* THEN
    Descripcin: Termina las evaluaciones y comienza a ejecutar:
    Opcode: FF
    
I.2. Tipos de acciones
======================

* SET ITEM n = t
    Descripcin: Asigna el item t al slot n
    Opcode: 00 x n
    
* SET FLAG x = n
    Descripcin: Da el valor N al flag X.
    Opcode: 01 x n
    
* INC FLAG x, n
    Descripcin: Incrementa el valor del flag X en N.
    Opcode: 10 x n
    
* DEC FLAG x, n
    Descripcin: Decrementa el valor del flag X en N
    Opcode: 11 x n
    
* ADD FLAGS x, y
    Descripcin x = x + y
    Opcode: 12 x y
    
* SUB FLAGS x, y
    Descripcin: x = x - y
    Opcode: 13 x y
    
* FLIPFLOP x
	Descripcin: x = 1 - x
	Opcode: 15 x    
    
* SET TILE (x, y) = n
    Descripcin: Establece que el tile (x, y) de la pantalla sea el n
    Opcode: 20 x y n
    
* INC LIFE n
    Descripcin: Incrementa el valor de la vida en n
    Opcode: 30 n
    
* DEC LIFE n
    Descripcin: Decrementa el valor de la vida en n
    Opcode: 31 n

* FLICKER	
	Descripcin: El jugador pasa a estado flicker
	Opcode: 32
    
* INC OBJECTS n
	Descripcin: Aade n objetos ms.
	Opcode: 40 n
	
* DEC OBJECTS n
	Descripcin: Resta n objetos (si objects >= n; si no objects = 0).
	pcode: 41 n
  
* SWAP x, y
	Descripcin: intercambia el valor de los flags x e y
	Opcode: 14 x y
	
* PRINT_TILE_AT (x, y) = n
	Opcode: 50 x y n
	
* SET_FIRE_ZONE x1, y1, x2, y2
	Opcode: 51 x1 y1 x2 y2

* SHOW_COINS
	Opcode: 60
	
* HIDE_COINS
	Opcode: 61
	
* ENABLE_KILL_SLOWLY
	Opcode: 62
	
* DISABLE_KILL_SLOWLY
	Opcode: 63
	
* ENABLE_TYPE_6
	Opcode: 64
	
* DISABLE_TYPE_6
	Opcode: 65
	
* ENABLE_MAKE_TYPE_6
	Opcode: 66

* DISABLE_MAKE_TYPE_6
	Opcode: 67
	
* REENTER
	Drescripcin: Re-entra en la pantalla (con todo lo que ello significa)
	Opcode: 6F
	
* REDRAW
	Descripcin: Slo redibuja la pantalla.
	Opcode: 6E
	
* WARP_TO n,x,y
	Descripcin: Salta a la pantalla n,x,y
	Opcode: 6D n x y
	
* REPOSTN x, y
	Descripcin: REENTER a x, y sin respawn de enemigos.
	Opcode: 6C x y

* SETX x
	Opcode: 6B x

* SETY y
	Opcode: 6A y
	
* WARP_TO_LEVEL l, n_pant, x, y, silent
	Opcode: 69 l n x y s
	
* SET_TIMER a, b
	Descripcin: Timer = a, rate = b
	Opcode: 70 a b
	
* TIMER_START
	Descripcin: enciende el temporizador
	Opcode: 71

* TIMER_STOP
	Descripcin: apaga el temporizador
	Opcode: 72
	
* SOUND n
	Descripcin: peta_el_beeper (n);
	Opcode: E0 n
	      
* SHOW
	Descripcion: Actualiza la pantalla
	Opcode: E1
	
* RECHARGE
	Description: Recarga toda la vida
	Opcode: E2
	
* TEXT
	Descripcin: Imprime un texto
	Opcode:	E3 chars 255
	
* EXTERN n
	Descripcin: ejecuta una funcin "extern" pasndole como parmetro N
	Opcode: E4 n
	
* PAUSE n
	Descripcin: Espera "n" ticks.
	Opcode: E5 n
	
* MUSIC n
	Descripcin: Toca la msica "n"
	Opcode: E6 n
	
* REDRAW_ITEMS
	Descripcin: fuerza un redibujado de los items
	Opcode: E7
	
* GAME OVER
    Descripcin: Pierde el juego
    Opcode: F0

* WIN GAME
    Descripcin: Gana el juego
    Opcode: F1

* END
    Descripcin: Termina el bloque.
    Opcode: FF
    
II. IDEAS COMPILACIN

El cdigo compilado:

[code]defb 18                     ; Este bloque ocupa 18 bytes
defb 0x01                   ; Es del tipo "Press fire"
defb 0x01, 0x03             ; IF PLAYER_HAS_ITEM 3
defb 0x21, 0x06, 0x08       ; IF PLAYER_IN_X 6, 8 
defb 0x22, 0x03, 0x05       ; IF PLAYER_IN_Y 3, 5
defb 0xFF                   ; THEN
defb 0x00, 0x03, 0x00       ; SET ITEM 3, 0
defb 0x01, 0x01, 0x01       ; SET FLAG 1, 1
defb 0xFF                   ; END[/code]

El intrprete generado:

[code]
// Comprobaciones

continue = 0;
terminado = 0;
while (!terminado) {
    c = read_byte ();
    switch (c) {
        case 0x01:
            // IF PLAYER_HAS_ITEM x
            // Opcode: 01 x
            x = read_byte ();
            if (items [x].status == 0)
                terminado = 1;
            break;
            
        case 0x02: 
            // IF PLAYER_HASN'T_ITEM x
            // Opcode: 02 x
            x = read_byte ();
            if (items [x].status == 1)
                terminado = 1;
            break;
            
        case 0x10:
            // IF FLAG x = n
            // Opcode: 10 x n
            x = read_byte ();
            n = read_byte ();
            if (flags [x] != n)
                terminado = 1;
            break;
            
        // etctera
    
        case 0xFF:
            terminado = 1;
            continue = 1;       
    }
    
if (continue) {
    // Acciones
    terminado = 0;
    while (!terminado) {
        c = read_byte ();
        switch (c) {
            case 0x00:
                // SET ITEM x n
                // Opcode: 00 x n
                x = read_byte ();
                n = read_byte ();
                items [x] = n;
                break;
                
            case 0x10:
                // INC FLAG x, n
                // Opcode: 10 x n
                x = read_byte ();
                n = read_byte ();
                flags [x] += n;
                break;
                
            // etctera
            
            case 0xFF:
                terminado = 1;
        }
    }
}[/code]

