Imported contents: kraptor_final_apr_03_2004.tar.gz
authorMiriam Ruiz <miriam@debian.org>
Wed, 3 Dec 2008 10:59:37 +0000 (3 11:59 +0100)
committerMiriam Ruiz <miriam@debian.org>
Wed, 3 Dec 2008 10:59:37 +0000 (3 11:59 +0100)
Downloaded from http://kraptor.sourceforge.net/
Author: Bruno Diaz <kronopio@users.sourceforge.net>

131 files changed:
bin/alleg40.dll [new file with mode: 0644]
bin/allegro.cfg [new file with mode: 0644]
bin/cinem02.dat [new file with mode: 0644]
bin/cinem03.dat [new file with mode: 0644]
bin/cinem04.dat [new file with mode: 0644]
bin/cinem05.dat [new file with mode: 0644]
bin/cinem06.dat [new file with mode: 0644]
bin/cinem07.dat [new file with mode: 0644]
bin/cinem08.dat [new file with mode: 0644]
bin/cinem09.dat [new file with mode: 0644]
bin/cinem10.dat [new file with mode: 0644]
bin/final.dat [new file with mode: 0644]
bin/gameover.dat [new file with mode: 0644]
bin/ia.dat [new file with mode: 0644]
bin/intro.dat [new file with mode: 0644]
bin/keyboard.dat [new file with mode: 0644]
bin/krapmain.dat [new file with mode: 0644]
bin/krapmnu.dat [new file with mode: 0644]
bin/kraptor.cfg [new file with mode: 0644]
bin/kraptor.exe [new file with mode: 0644]
bin/kraptor_w32.exe [new file with mode: 0644]
bin/language.dat [new file with mode: 0644]
bin/level1.dat [new file with mode: 0644]
bin/level10.dat [new file with mode: 0644]
bin/level2.dat [new file with mode: 0644]
bin/level3.dat [new file with mode: 0644]
bin/level4.dat [new file with mode: 0644]
bin/level5.dat [new file with mode: 0644]
bin/level6.dat [new file with mode: 0644]
bin/level7.dat [new file with mode: 0644]
bin/level8.dat [new file with mode: 0644]
bin/level9.dat [new file with mode: 0644]
bin/remove.me [new file with mode: 0644]
extras/ai/leeme.txt [new file with mode: 0644]
extras/ai/parse_ia.c [new file with mode: 0644]
extras/doc/es/cinemati.txt [new file with mode: 0644]
extras/doc/es/general.txt [new file with mode: 0644]
extras/doc/es/ia.txt [new file with mode: 0644]
extras/doc/es/language.txt [new file with mode: 0644]
extras/doc/es/license.txt [new file with mode: 0644]
extras/doc/es/premios.txt [new file with mode: 0644]
extras/mapedit/eneedit.c [new file with mode: 0644]
extras/mapedit/leeme.txt [new file with mode: 0644]
extras/mapedit/makefile [new file with mode: 0644]
extras/mapedit/makegrid.c [new file with mode: 0644]
extras/mapedit/mapedit.c [new file with mode: 0644]
extras/shader/leeme.txt [new file with mode: 0644]
extras/shader/makefile [new file with mode: 0644]
extras/shader/shader.c [new file with mode: 0644]
fix.bat [new file with mode: 0644]
fix.sh [new file with mode: 0755]
include/azar.h [new file with mode: 0644]
include/bomba.h [new file with mode: 0644]
include/captura.h [new file with mode: 0644]
include/cinema.h [new file with mode: 0644]
include/clima.h [new file with mode: 0644]
include/combo.h [new file with mode: 0644]
include/config.h [new file with mode: 0644]
include/data.h [new file with mode: 0644]
include/datafind.h [new file with mode: 0644]
include/enemigo.h [new file with mode: 0644]
include/error.h [new file with mode: 0644]
include/explos.h [new file with mode: 0644]
include/filedata.h [new file with mode: 0644]
include/game.h [new file with mode: 0644]
include/global.h [new file with mode: 0644]
include/guiprocs.h [new file with mode: 0644]
include/guitrans.h [new file with mode: 0644]
include/humo.h [new file with mode: 0644]
include/ia.h [new file with mode: 0644]
include/joymnu.h [new file with mode: 0644]
include/jugador.h [new file with mode: 0644]
include/kfbuffer.h [new file with mode: 0644]
include/krstring.h [new file with mode: 0644]
include/main.h [new file with mode: 0644]
include/mapa.h [new file with mode: 0644]
include/menu.h [new file with mode: 0644]
include/partic.h [new file with mode: 0644]
include/pmask.h [new file with mode: 0644]
include/premio.h [new file with mode: 0644]
include/rvideo.h [new file with mode: 0644]
include/savedlg.h [new file with mode: 0644]
include/shopping.h [new file with mode: 0644]
include/sombras.h [new file with mode: 0644]
include/sonido.h [new file with mode: 0644]
include/wordwrap.h [new file with mode: 0644]
install [new file with mode: 0644]
license [new file with mode: 0644]
makefile [new file with mode: 0644]
makefile.all [new file with mode: 0644]
obj/djgpp/remove.me [new file with mode: 0644]
obj/linux/remove.me [new file with mode: 0644]
obj/mingw32/remove.me [new file with mode: 0644]
readme [new file with mode: 0644]
src/azar.c [new file with mode: 0644]
src/bomba.c [new file with mode: 0644]
src/captura.c [new file with mode: 0644]
src/cinema.c [new file with mode: 0644]
src/clima.c [new file with mode: 0644]
src/combo.c [new file with mode: 0644]
src/config.c [new file with mode: 0644]
src/data.c [new file with mode: 0644]
src/datafind.c [new file with mode: 0644]
src/enemigo.c [new file with mode: 0644]
src/error.c [new file with mode: 0644]
src/explos.c [new file with mode: 0644]
src/filedata.c [new file with mode: 0644]
src/game.c [new file with mode: 0644]
src/global.c [new file with mode: 0644]
src/guiprocs.c [new file with mode: 0644]
src/guitrans.c [new file with mode: 0644]
src/humo.c [new file with mode: 0644]
src/ia.c [new file with mode: 0644]
src/joymnu.c [new file with mode: 0644]
src/jugador.c [new file with mode: 0644]
src/kfbuffer.c [new file with mode: 0644]
src/krstring.c [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/mapa.c [new file with mode: 0644]
src/menu.c [new file with mode: 0644]
src/partic.c [new file with mode: 0644]
src/pmask.c [new file with mode: 0644]
src/premio.c [new file with mode: 0644]
src/rvideo.c [new file with mode: 0644]
src/savedlg.c [new file with mode: 0644]
src/shopping.c [new file with mode: 0644]
src/sombras.c [new file with mode: 0644]
src/sonido.c [new file with mode: 0644]
src/wordwrap.c [new file with mode: 0644]
test.c [new file with mode: 0644]
version [new file with mode: 0644]

diff --git a/bin/alleg40.dll b/bin/alleg40.dll
new file mode 100644 (file)
index 0000000..ccfcc68
Binary files /dev/null and b/bin/alleg40.dll differ
diff --git a/bin/allegro.cfg b/bin/allegro.cfg
new file mode 100644 (file)
index 0000000..269ae32
--- /dev/null
@@ -0,0 +1,2 @@
+[system]
+language = en
diff --git a/bin/cinem02.dat b/bin/cinem02.dat
new file mode 100644 (file)
index 0000000..a44bc47
Binary files /dev/null and b/bin/cinem02.dat differ
diff --git a/bin/cinem03.dat b/bin/cinem03.dat
new file mode 100644 (file)
index 0000000..9d8063b
Binary files /dev/null and b/bin/cinem03.dat differ
diff --git a/bin/cinem04.dat b/bin/cinem04.dat
new file mode 100644 (file)
index 0000000..2ca0694
Binary files /dev/null and b/bin/cinem04.dat differ
diff --git a/bin/cinem05.dat b/bin/cinem05.dat
new file mode 100644 (file)
index 0000000..e268360
Binary files /dev/null and b/bin/cinem05.dat differ
diff --git a/bin/cinem06.dat b/bin/cinem06.dat
new file mode 100644 (file)
index 0000000..3e6b9b1
Binary files /dev/null and b/bin/cinem06.dat differ
diff --git a/bin/cinem07.dat b/bin/cinem07.dat
new file mode 100644 (file)
index 0000000..f78aa83
Binary files /dev/null and b/bin/cinem07.dat differ
diff --git a/bin/cinem08.dat b/bin/cinem08.dat
new file mode 100644 (file)
index 0000000..09224ec
Binary files /dev/null and b/bin/cinem08.dat differ
diff --git a/bin/cinem09.dat b/bin/cinem09.dat
new file mode 100644 (file)
index 0000000..429d4d3
Binary files /dev/null and b/bin/cinem09.dat differ
diff --git a/bin/cinem10.dat b/bin/cinem10.dat
new file mode 100644 (file)
index 0000000..9d0bb2e
Binary files /dev/null and b/bin/cinem10.dat differ
diff --git a/bin/final.dat b/bin/final.dat
new file mode 100644 (file)
index 0000000..820fbfd
Binary files /dev/null and b/bin/final.dat differ
diff --git a/bin/gameover.dat b/bin/gameover.dat
new file mode 100644 (file)
index 0000000..e496894
Binary files /dev/null and b/bin/gameover.dat differ
diff --git a/bin/ia.dat b/bin/ia.dat
new file mode 100644 (file)
index 0000000..6aa7503
Binary files /dev/null and b/bin/ia.dat differ
diff --git a/bin/intro.dat b/bin/intro.dat
new file mode 100644 (file)
index 0000000..4c2f83e
Binary files /dev/null and b/bin/intro.dat differ
diff --git a/bin/keyboard.dat b/bin/keyboard.dat
new file mode 100644 (file)
index 0000000..7832efa
Binary files /dev/null and b/bin/keyboard.dat differ
diff --git a/bin/krapmain.dat b/bin/krapmain.dat
new file mode 100644 (file)
index 0000000..059f6f0
Binary files /dev/null and b/bin/krapmain.dat differ
diff --git a/bin/krapmnu.dat b/bin/krapmnu.dat
new file mode 100644 (file)
index 0000000..6644190
Binary files /dev/null and b/bin/krapmnu.dat differ
diff --git a/bin/kraptor.cfg b/bin/kraptor.cfg
new file mode 100644 (file)
index 0000000..1fd6ab1
--- /dev/null
@@ -0,0 +1,30 @@
+[kraptor_keyboard]
+arr = 84
+abj = 85
+izq = 82
+der = 83
+sht = 26
+wpn = 24
+bmb = 3
+
+[kraptor_detalle]
+nivel_detalle = 10
+quiere_videos = -1
+detalle_automatico = 0
+
+[kraptor_snd]
+quiere_snd = -1
+volumen_sonido = 255
+quiere_musica = -1
+volumen_musica = 255
+
+[KRONO_QUIERE_DEBUG]
+KRONO_QUIERE_DEBUG = 0
+
+[kraptor_joystick]
+quiere_usar_joystick = 0
+numero_de_joystick = 0
+
+[kraptor_mouse]
+quiere_usar_mouse = -1
+mouse_velocidad = 32
diff --git a/bin/kraptor.exe b/bin/kraptor.exe
new file mode 100644 (file)
index 0000000..16fb522
Binary files /dev/null and b/bin/kraptor.exe differ
diff --git a/bin/kraptor_w32.exe b/bin/kraptor_w32.exe
new file mode 100644 (file)
index 0000000..fd3f25a
Binary files /dev/null and b/bin/kraptor_w32.exe differ
diff --git a/bin/language.dat b/bin/language.dat
new file mode 100644 (file)
index 0000000..f74e6f8
Binary files /dev/null and b/bin/language.dat differ
diff --git a/bin/level1.dat b/bin/level1.dat
new file mode 100644 (file)
index 0000000..6e81558
Binary files /dev/null and b/bin/level1.dat differ
diff --git a/bin/level10.dat b/bin/level10.dat
new file mode 100644 (file)
index 0000000..368dd13
Binary files /dev/null and b/bin/level10.dat differ
diff --git a/bin/level2.dat b/bin/level2.dat
new file mode 100644 (file)
index 0000000..ead83b6
Binary files /dev/null and b/bin/level2.dat differ
diff --git a/bin/level3.dat b/bin/level3.dat
new file mode 100644 (file)
index 0000000..b230c9f
Binary files /dev/null and b/bin/level3.dat differ
diff --git a/bin/level4.dat b/bin/level4.dat
new file mode 100644 (file)
index 0000000..9900994
Binary files /dev/null and b/bin/level4.dat differ
diff --git a/bin/level5.dat b/bin/level5.dat
new file mode 100644 (file)
index 0000000..a199da2
Binary files /dev/null and b/bin/level5.dat differ
diff --git a/bin/level6.dat b/bin/level6.dat
new file mode 100644 (file)
index 0000000..c823c71
Binary files /dev/null and b/bin/level6.dat differ
diff --git a/bin/level7.dat b/bin/level7.dat
new file mode 100644 (file)
index 0000000..65af980
Binary files /dev/null and b/bin/level7.dat differ
diff --git a/bin/level8.dat b/bin/level8.dat
new file mode 100644 (file)
index 0000000..34f7607
Binary files /dev/null and b/bin/level8.dat differ
diff --git a/bin/level9.dat b/bin/level9.dat
new file mode 100644 (file)
index 0000000..3a39f17
Binary files /dev/null and b/bin/level9.dat differ
diff --git a/bin/remove.me b/bin/remove.me
new file mode 100644 (file)
index 0000000..99e8d22
--- /dev/null
@@ -0,0 +1 @@
+This file can be safely removed
\ No newline at end of file
diff --git a/extras/ai/leeme.txt b/extras/ai/leeme.txt
new file mode 100644 (file)
index 0000000..a7201ff
--- /dev/null
@@ -0,0 +1,12 @@
+Aqui va el compilador de IA de Kraptor
+Ver ia.txt para mas info.
+
+Uso:
+parse_ia [entrada.txt]  [salida.ia]
+
+Sintaxis de entrada.txt:
+[x1],[x2],[y1],[y2],[weapon],[loop]
+
+Por Kronoman
+En memoria de mi querido padre.
+Copyright (c) 2003, Kronoman
diff --git a/extras/ai/parse_ia.c b/extras/ai/parse_ia.c
new file mode 100644 (file)
index 0000000..2d89e7c
--- /dev/null
@@ -0,0 +1,111 @@
+/*----------------------\r
+Aqui va el compilador de IA de Kraptor\r
+Ver ia.txt para mas info.\r
+\r
+Uso:\r
+parse_ia [entrada.txt]  [salida.ia]\r
+\r
+Sintaxis de entrada.txt:\r
+[x1],[x2],[y1],[y2],[weapon],[loop]\r
+\r
+Por Kronoman\r
+En memoria de mi querido padre.\r
+Copyright (c) 2003, Kronoman\r
+---------------------*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+// Esta funcion hace la joda de parsear y compilar\r
+// in, out son archivo de entrada y salida\r
+void do_parsing(char *in, char *out)\r
+{\r
+FILE *fin, *fout;\r
+int nlinea =0; // numero de linea, para debugging del programador\r
+char linea[300]; // buffer de texto\r
+char *ret; // para strtok\r
+int params[6]; // contenedor de parametros, temporal\r
+int idx; // indice para params[]\r
+       \r
+       fin = fopen(in, "r");\r
+       if (fin == NULL) \r
+       {\r
+       printf("ERROR:\nNo se pudo abrir %s\n\n", in);\r
+       return;\r
+    }\r
+       \r
+       fout = fopen(out, "w");\r
+       if (fout == NULL) \r
+       {\r
+       printf("ERROR:\nNo se pudo abrir %s\n\n", out);\r
+       return;\r
+    }\r
+\r
+       while (fgets(linea, 256, fin) !=  NULL) // tomar linea\r
+       {\r
+     nlinea++;\r
+     printf("[%04d] '%s'\n\n", nlinea, linea);\r
+        \r
+     // Realizar el parsing adecuado, es decir, separar la linea en sus parametros\r
+               \r
+               ret = strtok(linea,",");\r
+               \r
+               idx = 0;\r
+               while (ret != NULL)\r
+               {\r
+                       params[idx] = atoi(ret); // convertir a entero\r
+                       printf("-> %s = %d \n", ret, params[idx]);\r
+\r
+                       ret = strtok(NULL, ",");\r
+                       idx ++;\r
+                       if (idx > 6)\r
+                       {\r
+                         printf("ERROR!\nDemasiados parametros!\n");\r
+                         return;\r
+                       }\r
+               }\r
+                        if (idx < 6)\r
+                       {\r
+                          printf("ERROR!\nInsuficientes parametros!\n");\r
+                         return;\r
+                       }\r
+               \r
+               // escribir, los parametros del bytecode (x1,x2,y1,y2,weapon,loop)\r
+               for (idx=0; idx<6;idx++)\r
+                     {\r
+                     // escribo los enteros como strings, por PORTABILIDAD!\r
+                     sprintf(linea,"%d", params[idx]);!\r
+                    fputs(linea, fout); // como esto convierte en UTF-8, no la uso\r
+                     \r
+                     putc(',', fout); // separador logico\r
+                    }\r
+       }; \r
+\r
+       // listo\r
+       fclose(fout);\r
+       fclose(fin);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+int main(int argc, char *argv[] )\r
+{\r
+\r
+       \r
+  if (argc < 2)\r
+  {\r
+    printf("ERROR:\nNo especifico [entrada.txt] y [salida.ia]\n\n");\r
+    return -1;\r
+  }\r
+\r
+  printf( "%s -> %s \n", argv[1], argv[2] );\r
+  do_parsing(argv[1], argv[2]);\r
+  \r
+\r
+return 0;\r
+}\r
+\r
diff --git a/extras/doc/es/cinemati.txt b/extras/doc/es/cinemati.txt
new file mode 100644 (file)
index 0000000..283f336
--- /dev/null
@@ -0,0 +1,213 @@
+Engine de cinematicas mediante scripting y bitmaps y animaciones\r
+Por Kronoman\r
+En memoria de mi querido padre\r
+Copyright (c) Septiembre de 2002\r
+---------------------------------------------------------------------\r
+Algunas ideas:\r
+\r
+El texto del script es leido desde un campo ->dat de un objeto\r
+DATAFILE de Allegro.\r
+Se lee como una cadena de chars, donde cada linea termina con un\r
+caracter 10 (LF, guarda compatibilidad con archivos de Linux!)\r
+Se va interpretando linea a linea.\r
+Por cada linea obtenida, se separa en parametros, y luego, el 1er parametro\r
+es tomado y se llama a la funcion que lo interpreta.\r
+Para listar las funciones se tiene una estructura con la instruccion (char)\r
+y el puntero a la funcion que la interpreta.\r
+Se busca en esta lista la instruccion ingresada.\r
+La funcion devuelve 0 si OK, -1 en falla.\r
+La funcion no recibe parametros. Los parametros de la linea estan\r
+almacenados en matrices globales.\r
+Son 3 matrices globales que contienen diferentes interpretaciones\r
+de los parametros.\r
+1) Parametros interpretados como enteros int\r
+2) Parametros interpretados como strings de char\r
+3) Todo lo que quedo despues de la primera instruccion (linea completa\r
+   sin 1era instruccion)\r
+Ademas, cada matriz contiene la cantidad de parametros interpretados,\r
+para poder comprobar si el usuario se olvido algun parametro.\r
+---------------------------------------------------------------------\r
+Multimedia:\r
+\r
+Las animaciones son archivos FLIC (fli/flc), y el texto subtitulado\r
+sincronizado va en un objeto aparte sincronizado con los frames del FLIC\r
+Las imagenes fijas son bitmaps\r
+Los sonidos son samples\r
+La musica es MOD (para DUMB) \r
+La musica por AHORA NO ESTA IMPLEMENTADA, POR COMPLICACIONES CON EL \r
+poll que precisa la musica en DUMB!!!\r
+---------------------------------------------------------------------\r
+Bitmap de buffer:\r
+\r
+El engine dibuja a un bitmap de buffer de 640x480, donde luego\r
+es enviado a pantalla cuando esta listo [ajustando la proporcion\r
+a la resolucion de pantalla].\r
+---------------------------------------------------------------------\r
+Sintaxis:\r
+\r
+TODAS LAS INSTRUCCIONES Y PARAMETROS DEBEN IR SEPARADOS POR UN (1) ESPACIO!\r
+EL ENGINE ES SENSIBLE A MAYUSCULAS/MINUSCULAS\r
+Todo lo que comienze con # es comentario y esa linea es IGNORADA.\r
+Las instrucciones son del tipo \r
+    [instruccion] [parametro] [parametro] [etc]\r
+NOTAR el espacio entre [parametro] y [parametro], etc...\r
+---------------------------------------------------------------------\r
+Juego de instrucciones para el script principal:\r
+El script principal indica la secuencia de eventos que deben producirse,\r
+es decir, que animaciones reproducir, que sonidos tocar, etc.\r
+NOTAR que los parametros NO son opcionales, olvidarselos puede ocurrir\r
+en resultados IMPREDECIBLES! (no hay comprobacion de errores...)\r
+\r
+# comentario\r
+   Toda linea que comienze con # es IGNORADA (se considera un comentario)\r
+   OK\r
+   \r
+cls [r] [g] [b]\r
+    Limpia la pantalla a color [r] [g] [b] (color RGB 0..255 c/u)\r
+    OK\r
+\r
+fade_out [velocidad]\r
+   Realiza una transicion a color negro \r
+   [velocidad] 1..64 (lento-rapido)\r
+   OK\r
+\r
+fade_out_color [r] [g] [b] [velocidad]\r
+   Realiza una transicion al color [r] [g] [b]\r
+   [velocidad] 1..64 (lento-rapido)\r
+   OK\r
+    \r
+rect [x] [y] [x2] [y2] [r] [g] [b]\r
+   Dibuja un rectangulo desde [x] [y] a [x2] [y2]\r
+   [r] [g] [b] es el color, en valores RGB 0..255\r
+   OK\r
+    \r
+rectfill [x] [y] [x2] [y2] [r] [g] [b]\r
+   Dibuja un rectangulo LLENO desde [x] [y] a [x2] [y2]\r
+   [r] [g] [b] es el color, en valores RGB 0..255\r
+   OK\r
+    \r
+line [x] [y] [x2] [y2] [r] [g] [b]\r
+   Dibuja una linea desde [x] [y] a [x2] [y2]\r
+   [r] [g] [b] es el color, en valores RGB 0..255\r
+   OK\r
+    \r
+locate [x] [y] [w]\r
+    Posiciona la salida de texto en [x] [y] con ancho [w]\r
+    Setea el borde [w] como 'filo' o 'borde' para las salidas de texto (echo)\r
+    Al llegar el texto a esa posicion, hace word-wrap\r
+    OK\r
+    \r
+text_color [r] [g] [b]\r
+   Setea el color del texto a colocar en futuras llamadas\r
+   [r] [g] [b] es el color, en valores RGB 0..255\r
+   OK\r
+   \r
+text_back [r] [g] [b]\r
+   Setea el color del FONDO del  texto a colocar en futuras llamadas\r
+   [r] [g] [b] es el color, en valores RGB 0..255\r
+   Si algun  [r] [g] [b] es < 0 (ej: -1) el fondo del texto es transparente\r
+   OK\r
+\r
+text_font [font]\r
+   Cambia la fuente de las salidas de echo; si no se pone [font],\r
+   se volvera al font original de la BIOS.\r
+   [font] debe ser un objeto de tipo 'font' contenido en el archivo\r
+   de la cinematica.\r
+   OK\r
+\r
+echo [texto]\r
+    Escribe el [texto] en pantalla, con word-wrap al borde seteado\r
+    Desplaza la coordenada [y] hacia abajo y [x] al origen anterior (salto de linea)\r
+    OK\r
+\r
+echo_centre_x [texto]\r
+    Escribe el [texto] centrado en [x] en pantalla, con word-wrap al borde seteado\r
+    Desplaza la coordenada [y] hacia abajo y [x] al origen anterior (salto de linea)\r
+    OK\r
+\r
+echo_centre_xy [texto]\r
+    Escribe el [texto] centrado en [x] e [y] en pantalla, con word-wrap al borde seteado\r
+    Desplaza la coordenada [y] hacia abajo y [x] al origen anterior (salto de linea)\r
+    OK\r
+\r
+rest [milisegundos]\r
+     Espera [milisegundos] antes de continuar la interpretacion...\r
+     Si [milisegundos] <= 0, espera por una tecla...\r
+     OK\r
+     \r
+set_palette [paleta_256_colores]\r
+   Setea la paleta de colores actual al objeto PALETA [paleta_256_colores]\r
+   Esto es lento, porque ademas, calcula la tabla RGB para la paleta\r
+   OK\r
+\r
+set_palette_default\r
+   Setea la paleta default de la placa VGA\r
+   OK\r
+   \r
+blit [x] [y] [bitmap]\r
+   Coloca el [bitmap] en [x] [y]\r
+   OK\r
+   \r
+sprite [x] [y] [sprite]\r
+   Coloca el [sprite] en [x] [y] filtrando el color de mascara\r
+   OK\r
+   \r
+stretch_blit [x] [y] [w] [h] [bitmap]\r
+   Coloca el [bitmap] en [x] [y] estirandolo a ancho [w] y alto [h]\r
+   OK\r
+\r
+play_sample [sample] [vol] [pan] [freq]\r
+    Lanza un sonido con el volumen, paneo y frecuencia. \r
+    El volumen y paneo van desde 0 (min/izq) hasta 255 (max/derecho), \r
+    127 es la mitad del parlante. \r
+    Frecuencia es relativa mas que absoluta: 1000 representa la frecuencia a la que \r
+    el sonido fue grabado, 2000 es el doble, 3000 el triple, 500 la mitad, etc   \r
+    OK\r
+\r
+clear_fli_back [r] [g] [b]\r
+       Esto es una 'bandera' que permite que cuando se ejecute un FLI,\r
+       antes de mostrar el primero cuadro, se limpie a color [r] [g] [b]\r
+       Coloque [r] [g] [b] = -1 para que no se limpie la pantalla\r
+       El default es limpiar a negro...\r
+    OK\r
+\r
+keyboard_cancel_fli [valor]\r
+       Esto permite que el usuario cancele una animacion fli al apretar una tecla\r
+       El default es 0 [NO]\r
+       Cualquier valor <> que 0, indica que si. (Usar -1 por las dudas)\r
+    OK\r
+\r
+play_fli [x] [y] [w] [h] [loop] [objeto_fli] [script_fli]\r
+    Ejecuta una animacion FLI contenida en el DAT. \r
+       NOTA: esto modifica la paleta de colores! si hubiera algo dibujado, podria\r
+       verse raro, e incluso, el fondo puede cambiar si el flag clear_fli_back no esta seteado\r
+    [x] [y] son las coordenadas de la esquina superior izquierda \r
+            donde deben ponerse los cuadros.\r
+    [w] [h] es el ancho y alto del fli (se estirara!)\r
+    [loop]   Indica la cantidad de veces que deben repetirse los cuadros.\r
+          *NOTA* Al llegar al final, el script cuenta de nuevo desde el primer frame\r
+                por lo tanto, el [script_fli] comienza de nuevo.\r
+    [objeto_fli] Indica el objeto de tipo FLI a reproducir, contenido en el DAT.\r
+    [script_fli] Indica el script (objeto de tipo TXT) que contiene el sonido,\r
+                 subtitulos, etc del FLI.\r
+                 Ver mas adelante la documentacion para saber como es el formato.\r
+       OK\r
+---------------------------------------------------------------------\r
+Formato del [scrip_fli] para el comando "play_fli"\r
+\r
+Es un objeto de texto tipo TXT que indica los sonidos, y subtitulos frame x frame\r
+[NOTA DEBUG: los subtitulos NO estan implementados todavia]\r
+NOTA: los frames se comienzan contando desde 1\r
+\r
+El formato es asi:\r
+[FRAME_n]\r
+snd = [sample]\r
+\r
+----------\r
+Ejemplo:\r
+\r
+[FRAME_11]\r
+snd = explosion\r
+\r
+[FRAME_48]\r
+snd = final\r
diff --git a/extras/doc/es/general.txt b/extras/doc/es/general.txt
new file mode 100644 (file)
index 0000000..943421d
--- /dev/null
@@ -0,0 +1,457 @@
+Kraptor\r
+-------\r
+Por Kronoman - \r
+Comenzado en Agosto 2002\r
+En memoria de mi querido padre\r
+\r
+Engine de juego de aviones/naves\r
+Hecho en C, con Allegro y DUMB\r
+\r
+Kraptor: especificaciones tecnicas\r
+----------------------------------\r
+\r
+Fondos:\r
+600x4000 [grilla de 40x40]\r
+Matriz de 15x100 indica si explota o no el fondo, un numero > 0 indica\r
+que esa area es explosiva, al tocar un disparo esa area, descuenta del mapa\r
+y finalmente explota, junto con los adyacentes.\r
+\r
+Matriz de 15x100 tiene un numero, > 0 indica que debe aparecer un enemigo\r
+de esa clase-1, 0 = neutro. O sea, por ejemplo: el numero 1 indica que\r
+debe aparecer un enemigo de clase 0, 2 de clase 1, etc (o sea, n-1, siendo 0 neutro)\r
+\r
+NOTA: usar siempre compresion individual de objetos en los datos, no global,\r
+      ya que ralentiza mucho el tiempo de carga.\r
+\r
+Archivos DATAFILES:\r
+-------------------------------------------------------\r
+\r
+Datos principales del programa\r
+--> krapmain.dat\r
+\r
+    Contiene los datos principales del juego, tales como enemigos,\r
+    jugador, armamento, sonido, pirotecnia, premios y secuencia de niveles.\r
+    Ademas, debe contener los datos opcionales mencioados\r
+    en los scripts (tales como sprites, sonidos, etc).\r
+    NO contiene los archivos de cada nivel independiente.\r
+\r
+    Contenido:\r
+    =========\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    Objetos sueltos necesarios:\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    hud_font\r
+\r
+        Font para dibujar el 'hud', es decir la informacion\r
+        de puntaje y cantidad de balas.\r
+        Si no existe, se usa el font de la BIOS\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    pal_game\r
+\r
+        Paleta de 256 colores usada durante TODO el juego\r
+        Los enemigos, explosiones, particulas, fondos, etc DEBEN ajustarse\r
+        a esta paleta. Esto NO afecta las cinematicas o los menues.\r
+        SI afecta a la imagen de fondo del shopping\r
+        RESPETAR LAS MINUSCULAS EN EL NOMBRE, pal_game!\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    shop_bmp\r
+\r
+        Imagen de fondo del shopping\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    burn_0\r
+    burn_1\r
+    burn_2\r
+        Sprites de 40x40 para quemar el fondo.\r
+        Deben representar un hoyo de quemazon, en escala de grises\r
+        inversa, el color negro sera transparente, y los tonos\r
+        de blanco indican profundidad de quemado, siendo 255,255,255(RGB)\r
+        el mas profundo.\r
+        Deben estar hechos para poder ser rotados arbitrariamente\r
+        al azar (para dar mas variedad)\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    humo\r
+        Sprite de unos 100x100 que sera usado para generar el efecto de humo.\r
+        Esto es _opcional_, ya que todavia no funciona muy bien el efecto.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    explo_bmp_0\r
+    explo_bmp_1\r
+    explo_bmp_2\r
+    \r
+        Sprites de explosiones, todas del MISMO tama~o, usadas para renderear\r
+        explosiones.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    explo_snd_0\r
+    explo_snd_1\r
+    explo_snd_2\r
+\r
+        Sonido de explosiones.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    chispa_0\r
+    chispa_1\r
+    chispa_2\r
+\r
+        Chispas que las naves arrojan al explotar (bolitas de fuego peque~as).\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    gamescript\r
+\r
+        Objeto de texto que contiene un script que indica la sucesion de niveles\r
+        del juego de manera descriptiva como un archivo de configuracion de Allegro\r
+        Se van leyendo las secciones [NIVEL_x] hasta que no se encuentra la proxima,\r
+        con lo cual se asume que el juego termino (el jugador gano).\r
+        Las cinematicas se pueden suprimir colocando valor `null` (sin las `)\r
+\r
+\r
+        La seccion [GAME_INTRO] contiene la cinematica cuando el jugador inicia un juego nuevo.\r
+        La seccion [GAME_OVER] contiene la cinematica cuando el jugador pierde.\r
+\r
+        Comienza a contar de nivel 1\r
+        Todo lo que tiene # es comentario\r
+\r
+    Ejemplo (script de 2 niveles):\r
+\r
+        [GAME_INTRO]\r
+        cine = intro.dat\r
+\r
+        [GAME_OVER]\r
+        cine = gameover.dat\r
+\r
+        [NIVEL_1]\r
+        # Titulo del nivel\r
+        titulo = Primera Batalla\r
+    \r
+        # Explicacion, hasta 256 caracteres, usa word-wrap\r
+        texto = Te aproximas al primer combate, buena suerte!\r
+    \r
+        # Cinematica de comienzo de nivel\r
+        cine_in = intro01.dat\r
+    \r
+        # Esto especifica el nivel conteniendo datos de juego\r
+        level_dat = level1.dat\r
+    \r
+        # Cinematica de fin de nivel\r
+        cine_out = null\r
+\r
+        # Referente al efecto climatico, es opcional\r
+        # densidad del clima en particulas 0..300\r
+        clima_c = 100\r
+        # tipo de clima: 0 = lluvia, 1 = nieve\r
+        clima_t = 0\r
+        # direccion de caida: 0 = izq, 1 = der\r
+        clima_d = 0\r
+\r
+        [NIVEL_2]\r
+        # Titulo del nivel\r
+        titulo = Final\r
+    \r
+        # Explicacion, hasta 256 caracteres, usa word-wrap\r
+        texto = Este es el final, mi unico amigo!\r
+    \r
+        # Cinematica de comienzo de nivel\r
+        cine_in = null\r
+    \r
+        # Esto especifica el nivel conteniendo datos de juego\r
+        level_dat = level1.dat\r
+    \r
+        # Cinematica de fin de nivel\r
+        cine_out = fin.dat\r
+    \r
+        # Al buscar el 3er nivel, el juego finaliza, y va a la tabla de puntos.\r
+\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    jugador\r
+           \r
+    Esto contiene una definicion de los sprites, armas y sonidos del jugador\r
+    Ejemplo:\r
+\r
+    # Configuracion del jugador\r
+    [JUGADOR]\r
+    # Sprites del jugador izq,med,der\r
+    # DEBEN ser del MISMO tama~o y contenidos en este mismo archivo DAT\r
+    spr_0 = jugador_0\r
+    spr_1 = jugador_1\r
+    spr_2 = jugador_2\r
+\r
+    # dinero inicial con que cuenta al comenzar a jugar\r
+    init_money = 500\r
+\r
+    # bombas iniciales con que cuenta al comenzar a jugar\r
+    init_bombas = 1\r
+\r
+    # Referente a la reparacion de la nave en el shopping\r
+    [JUGADOR_REPARAR]\r
+    # Cantidad de unidades que da cada reparacion\r
+    cantidad = 10\r
+    # Precio cada reparacion de la nave \r
+    precio = 100\r
+    # Descripcion\r
+    desc = Reparar el 10% de los desperfectos de la nave\r
+    # Bitmap que representa la reparacion, de 116x124 preferentemente (se estirara)\r
+    bmp = bitmap_reparar\r
+\r
+    # Referente a la bomba especial de la nave en el shopping\r
+    [JUGADOR_BOMBA_ESPECIAL]\r
+    # cantidad de bombas de cada compra\r
+    cantidad = 1\r
+    # precio de cada item de bomba especial\r
+    precio = 100\r
+    # descripcion\r
+    desc = Bomba de pulso de energia\r
+    # Bitmap que representa en el shopping,  de 116x124\r
+    bmp = bitmap_bomba\r
+    # sonido de lanzamiento de la bomba (OJO, cuando explota, toca sonido de explosion; esto deberia ser un speech, tipo "bomb fire" o algo asi!)\r
+    bomba_sonido = speech_bomb_fire\r
+\r
+    # cantidad maxima que se puede comprar\r
+    max_ammo = 5\r
+\r
+    # Armamento disponible para el jugador (el arma 0 esta siempre y nunca se acaba)\r
+    # Va de ARMA_0 hasta  ARMA_x [x es un numero]\r
+    [ARMA_0]\r
+    # Referente al modo 'shopping' del arma\r
+    # bitmap de 116x124 preferentemente (se estirara)\r
+    arma = dibujo_del_arma_en_el_shop_bitmap\r
+    # descripcion del arma para el shop: maximo 2048 caracteres\r
+    desc = Descripcion del arma\r
+    # descripcion corta para el HUD del juego: max 20 caracteres\r
+    desc_short = Wpn #0\r
+    # precio, cuidar que sea relativo a lo que 'gana' el jugador\r
+    precio = 12345\r
+    # cantidad de 'balas' por paquete de compra\r
+    cant_ammo = 100\r
+    # cantidad maxima de 'balas'\r
+    cant_ammo_max = 999\r
+\r
+    # Referente al disparo del arma en si\r
+    spr = sprite_del_disparo\r
+    snd_0 = sonido_al_disparar_o_null\r
+    snd_1 = sonido_al_impactar_o_null\r
+    vx = 0\r
+    vy = -0.5\r
+    vida = 480\r
+    punch = 3\r
+    firerate = 100\r
+    t = 0\r
+\r
+    # Estela del disparo, esto es opcional (si no aparece, no abra estela)\r
+    # Vida\r
+        est_vida_min = 1\r
+        est_vida_max = 10\r
+    # Cantidad\r
+        est_cant_min = 5\r
+        est_cant_max = 10\r
+    # color RGB\r
+        est_color_r_min = 128\r
+        est_color_r_max = 255\r
+        est_color_g_min = 0\r
+        est_color_g_max = 0\r
+        est_color_b_min = 0\r
+        est_color_b_max = 0\r
+    # escala aceleracion: 100 = 0.01 \r
+        est_dx_min = -100\r
+        est_dx_max = 100\r
+        est_dy_min = 100\r
+        est_dy_max = 300\r
+    # tipo de particula\r
+        est_tipo_min = 3\r
+        est_tipo_max = 3\r
+    # radio de la particula (si es aplicable)\r
+       est_rad_min = 1\r
+       est_rad_max = 3\r
+    # usar transparencia? (-1 = si, 0 = no)\r
+       est_transp = 0\r
+\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    enemigos\r
+\r
+    Esto contiene una definicion de los enemigos asi como de sus\r
+    tipos de armamento, y la IA que utilizan (Ver ia.txt).\r
+    Ejemplo:\r
+\r
+    # clases de enemigos\r
+    [ENEMIGO_0]\r
+    # vida enemigo\r
+    vida = 100\r
+    # peso del enemigo (sirve para proporcion de explosion e impacto de colision)\r
+    peso = 50\r
+\r
+    # string de ID de programa en bytecodes de IA (ver ia.txt)\r
+    tipo_ia = ia_1\r
+    # la IA debe comenzar en un punto arbitrario del bytecode (al azar = -1, default: 0 = no)\r
+    ia_azar = 0\r
+\r
+    # este flag indica que el enemigo es un BOSS, de esa manera, el enemigo\r
+    # no se va NUNCA hacia abajo de 1/2  de pantalla (como hacen los boss)\r
+    # (default 0 = no;  -1 = si)\r
+    ia_boss = 0\r
+\r
+    # sprites de animacion,\r
+    # se pueden obviar; hay un maximo de 4 (0..3)\r
+    # si utiliza uno solo, se puede poner spr = dibujo y listo\r
+    spr_0 = enemigo0_0\r
+    spr_1 = enemigo0_1\r
+    spr_2 = enemigo0_2\r
+    spr_3 = enemigo0_3\r
+\r
+    # delay de animacion de los sprites (30 = 1 segundo)\r
+    spr_delay = 10\r
+\r
+    # dinero que paga matar a este enemigo\r
+    dinero = 50\r
+\r
+    # premio (indice del premio) que suelta este enemigo (-1 = ninguno)\r
+    premio_idx = 1\r
+    # probabilidad de soltar el premio al morir (0..100 %)\r
+    premio_prob = 95\r
+\r
+    # clases de armas\r
+    [ARMA_0]\r
+    # dibujo del disparo\r
+    spr = laser2\r
+    # sonido al disparar\r
+    snd_0 = sonido_al_disparar_o_null\r
+    # sonido al impactar\r
+    snd_1 = sonido_al_impactar_o_null\r
+    # velocidad x\r
+    vx = 0\r
+    # velocidad y\r
+    vy = 2\r
+    # duracion del disparo en tics (30 = 1 segundo)\r
+    vida = 400\r
+    # golpe del disparo\r
+    punch = 20\r
+    # tipo de arma\r
+    t = 2\r
+\r
+    # Estela del disparo, esto es opcional (si no aparece, no abra estela)\r
+    # Vida\r
+        est_vida_min = 1\r
+        est_vida_max = 10\r
+    # Cantidad\r
+        est_cant_min = 5\r
+        est_cant_max = 10\r
+    # color RGB\r
+        est_color_r_min = 128\r
+        est_color_r_max = 255\r
+        est_color_g_min = 0\r
+        est_color_g_max = 0\r
+        est_color_b_min = 0\r
+        est_color_b_max = 0\r
+    # ( escala aceleracion: 100 = 0.01)\r
+        est_dx_min = -100\r
+        est_dx_max = 100\r
+        est_dy_min = 100\r
+        est_dy_max = 300\r
+    # tipo de particula\r
+        est_tipo_min = 3\r
+        est_tipo_max = 3\r
+    # radio de la particula (si es aplicable)\r
+       est_rad_min = 1\r
+       est_rad_max = 3\r
+    # usar transparencia? (-1 = si, 0 = no)\r
+       est_transp = 0\r
+\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    premios\r
+\r
+    Este script configura los premios.\r
+    Ver el archivo premio.txt para mas informacion.\r
+\r
+    -------------------------------------------------------------------------\r
+Menues:\r
+Nota: los archivos de texto para presentar en pantalla \r
+      (ej: help, about) deben estar codificados en UTF-8\r
+      para ello, usar el utilitario de Allegro "textconv.exe"\r
+\r
+--> krapmnu.dat:\r
+\r
+    Esto contiene el fondo del menu y otros items utiles.\r
+\r
+    main_menu_bmp     <- bitmap de 640x480 que es el fondo del menu\r
+    main_menu_pal     <- paleta de 256 colores del menu\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    help_txt\r
+\r
+        Es un archivo de texto guardado tal cual (modo binario)\r
+        para mostrar en el menu Ayuda / Ayuda...\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    about_txt\r
+\r
+        Es un archivo de texto guardado tal cual (modo binario)\r
+        para mostrar en el menu Ayuda / Acerca de...\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
+    about_bmp\r
+\r
+        Es una imagen de tipo BITMAP, que se mostrara en Ayuda / Acerca de...\r
+        ajustarse a main_menu_pal!\r
+        Tama~o:  144x168 pixels!\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+\r
+    -------------------------------------------------------------------------\r
+\r
+Niveles:\r
+--> level*.dat:\r
+\r
+    Esto contiene el fondo (bitmap) y su correspondiente matrices de mapas\r
+    para los diferentes niveles de dificultad.\r
+    Se van cargando dinamicamente a medida que avanza el juego.\r
+\r
+    Contenido:\r
+    =========\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    mapa_fondo\r
+\r
+        Esto es la imagen del juego, de  600x4000 pixels.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    mapa_g\r
+\r
+        Informacion binaria (matriz) con los sectores explosivos del mapa.\r
+        0 indica sector no explosivo, > 0 indica energia de ese sector,\r
+        al llegar a 0, explota y queda 'quemada' el area.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    enem_g   -> opcional, dificultad unica\r
+    enem_g_0 -> dificultad FACIL\r
+    enem_g_1 -> dificultad MEDIA\r
+    enem_g_2 -> dificultad DIFICIL\r
+\r
+        Informacion binaria (matriz) con las posiciones de aparicion de enemigos.\r
+        Contiene 0 donde no aparecen enemigo, > 0 donde aparecen enemigos.\r
+        El numero indica el indice de clase de enemigo a aparecer, y se le\r
+        restara 1, asique enemigo 1 en enem_g representa ENEMIGO_0 en\r
+        las clases de enemigos.\r
+        Nota, el engine busca el enem_g_[dificultad]\r
+        Si no existe, intenta obtener enem_g, y si no existe, aborta el programa.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    musica\r
+\r
+        Musica IT, XM o S3M, opcional, se escucha de fondo durante el nivel. :^P\r
+        En formato IT, XM o S3M, para mas info, ver la documentacion de DUMB\r
+        (como cargar musica desde un DAT)\r
+        Debe ser un objeto binario de tipo "IT  ", "XM  " o "S3M "\r
+        Los espacios adicionales no son necesarios, el grabber los pone solo.\r
+        La musica debe durar aproximadamente 133 segundos (2 mins 13 segs)\r
+        porque es lo que dura un nivel aproximadamente (4000/30 pixels x segundo)\r
+    -------------------------------------------------------------------------\r
+Cinematicas:\r
+--> cine*.dat\r
+\r
+    Esto contiene las cinematicas del juego, se cargan dinamicamente a\r
+    medida que se necesitan.\r
+\r
+    NOTA: el 'lenguaje' usado en el script de cinematicas esta explicado\r
+          en el archivo cinemati.txt!!\r
+\r
+    Contenido:\r
+    =========\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    El unico contenido obligatorio es el objeto de texto (TXT)\r
+    llamado 'guion_txt' que contiene los comandos\r
+    especificados en cinemati.txt para poder mover la cinematica\r
+    NOTA: se buscara el guion acorde al lenguaje actual primero,\r
+    por ejemplo, si es espa~ol, se buscara guion_txt_es primero,\r
+    y si no existe, se usara guion_txt, y si no existe,\r
+    se intentara cargar guion_txt_en, y si no existe, se ignorara\r
+    la animacion.\r
+    O sea, para internacionalizar el juego, crear un guion_txt_es (espa~ol)\r
+    y un guion_txt_en (ingles) y los demas que sean necesarios.\r
+    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r
+    -------------------------------------------------------------------------\r
diff --git a/extras/doc/es/ia.txt b/extras/doc/es/ia.txt
new file mode 100644 (file)
index 0000000..c8e0ba8
--- /dev/null
@@ -0,0 +1,78 @@
+Kraptor - Sistema de Inteligencia Artificial
+
+
+Por Kronoman
+En memoria de mi querido padre.
+
+--------------------------------------------------------------------------
+Este documento describe como funciona el sistema de inteligencia artificial.
+
+
+Espacio fisico en disco:
+
+Los archivos de IA son _objetos binarios_ (DAT_BINARY) 
+con la propiedad tipo "IA" (mayusculas), guardados en el archivo de "grabber", "ia.dat", 
+usando compresion _individual_ de objetos.
+Recomiendo que cada objeto tenga el prefijo ia_[nombre]
+y que su nombre no supere los 256 caracteres, ya que sera la ID
+para identificarlo al cargar las clases de enemigos.
+Ejemplo: ia_agresiva, ia_simple, etc...
+
+--------------------------------------------------------------------------
+Mantenimiento en RAM:
+
+Al principio del juego, se carga el archivo krap_ia.dat,
+y entonces, se crea un cache donde van todas los scripts,
+ya traducidos de binario al formato de la plataforma.
+Todo esto se hace con memoria dinamica y listas enlazadas.
+Luego, cada vez que se carga una clase de enemigo,
+se le asigna un puntero a la IA correspondiente en la lista 
+enlazada previamente cargada.
+
+Es decir:
+- cargar krap_ia.dat
+- copiar y traducir los scripts a una nueva lista
+- descargar krap_ia.dat
+- cargar clase de enemigos, y para cada clase, asignarle
+  el puntero a la IA asignada.
+
+--------------------------------------------------------------------------
+Del lenguaje de scripting:
+
+Las instrucciones se escriben en un archivo de texto plano, 
+luego se pasan por el compilador, el cual las convierte 
+a un fichero semi-binario (es un archivo de texto con formato simple), 
+el cual es agregado usando "grabber" al archivo krap_ia.dat
+Lo interesante es que el "lenguaje" para el script 
+contiene UNA sola instruccion, ya que es muy especializada
+para el manejo de los enemigos, la cual contiene
+el movimiento por ciclo del enemigo (30 ciclos = 1 segundo).
+
+NOTA: el "compilador" es extremadamente BASICO, por lo tanto
+      NO EXISTEN COMENTARIOS, NO PONER ESPACIOS EXTRA, 
+      NI NADA "RARO"; SOLO PONER LAS LINEAS CON LA SINTAXIS
+      ESPECIFICADA!
+
+La sintaxis para el codigo de texto plano es la siguiente:
+[x1],[x2],[y1],[y2],[weapon],[loop]
+
+Donde:
+[x1],[x2] son rangos de movimiento en X para el enemigo
+          por ejemplo, 1,2 indica un movimiento entre +1 y +2
+          -5, 5 indica un movimiento entre -5 y +5 (-4,-3...0,1,etc)             
+[y1],[y2] funcionan igual a [x1],[x2], pero en el eje Y
+[weapon] indica que el enemigo debe disparar ese numero de clase de arma.
+         un valor de -1 indica NO disparar.
+
+[loop] indica la cantidad de veces que se debe repetir esta accion
+       la duracion de cada instruccion es 1/30 de segundo, asique
+       un valor de 30, repetira la accion 1 segundo completo.
+       
+Luego, el texto plano se pasa por un compilador, el cual
+interpreta la secuencia y la salva a disco en un archivo semi-binario.
+El archivo semi-binario tiene el formato de texto ASCII, donde
+se colocan los numeros separados por comas, todos en una sola linea larga,
+lo que permite parsearlo en tiempo de ejecucion facilmente.
+ej:
+1,2,3,4,5,6,7,8,9,0,1,2 [...]
+--------------------------------------------------------------------------
diff --git a/extras/doc/es/language.txt b/extras/doc/es/language.txt
new file mode 100644 (file)
index 0000000..2a3c3b4
--- /dev/null
@@ -0,0 +1,30 @@
+Kraptor\r
+-------\r
+Por Kronoman - Agosto 2002 - En memoria de mi querido padre\r
+\r
+Engine de juego de aviones/naves\r
+Licencia GNU GPL\r
+Hecho en C, con Allegro y DUMB\r
+\r
+Soporte de diferentes teclados de Kraptor\r
+-----------------------------------------\r
+Incluir el archivo keyboard.dat que trae Allegro. :^)\r
+\r
+Modo de soporte de multiples lenguajes de Kraptor\r
+--------------------------------------------------\r
+\r
+Kraptor soporta multiples lenguajes gracias a las facilidades de Allegro.\r
+El archivo language.dat debe estar presente (viene con Allegro)\r
+y cada objeto interno debe contener los textos adecuados para cada idioma.\r
+El idioma de base es el ingles, asique, los textos en el codigo fuente\r
+deben estar en ingles.\r
+La GUI esta dise~ada para auto-traducirse 'al vuelo', es decir,\r
+cada vez que se dibuja, busca el nuevo lenguaje.\r
+\r
+El archivo kraptor.cfg debe contener\r
+\r
+[system]\r
+language = es\r
+\r
+Donde language puede ser: es, en, etc (es decir, el codigo de 2 letras\r
+del lenguaje a usar).\r
diff --git a/extras/doc/es/license.txt b/extras/doc/es/license.txt
new file mode 100644 (file)
index 0000000..54f0bb7
--- /dev/null
@@ -0,0 +1,16 @@
+Kraptor Game Engine
+Kraptor Game Datafiles
+\r
+Copyright (c) 2002, 2003, Kronoman\r
+In loving memory of my father.\r
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+\r
+Distributed under The MIT License\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
diff --git a/extras/doc/es/premios.txt b/extras/doc/es/premios.txt
new file mode 100644 (file)
index 0000000..6e6f2a4
--- /dev/null
@@ -0,0 +1,39 @@
+Premios del juego\r
+-----------------\r
+\r
+Los premios que sueltan los enemigos estan definidos en un script\r
+de texto "premios" contenido en el archivo krapmain.dat\r
+\r
+\r
+El archivo tiene este formato:\r
+\r
+[PREMIO_n]\r
+premiar = [indice del objeto que premia tomar este premio, ver mas abajo]\r
+cantidad = [cantidad que da tomar ese premio]\r
+sprite = [imagen que lo representa (sprite) ]\r
+vida = [vida del premio antes de desaparecer si el jugador no lo agarra]\r
+sonido = [sonido al tomarlo ]\r
+\r
+Explicacion\r
+-----------\r
+\r
+[PREMIO_n] indica el indice del premio, como sera referenciado en\r
+el campo premio_idx del script de enemigos.\r
+Va de 0..[ver codigo fuente]\r
+\r
+"premiar" es un indice que va desde -2 a [max armas jugador]\r
+siendo:\r
+-2 = premiar con bombas extra\r
+-1 = premiar con energia extra\r
+0 en adelante = premiar con armamento correspondiente a ese indice (MAX_ARM_CLASS en jugador.h)\r
+\r
+"cantidad" es la cantidad de premio que se le dara;\r
+por ejemplo, si es 5 y premiar es -1, se le sumaran 5 puntos de energia\r
+al jugador.\r
+\r
+"sprite" es el nombre del bitmap que lo representa, debe estar contenido\r
+en krapmain.dat.\r
+\r
+"vida" es la duracion del premio antes de desaparecer de escena (30 = 1 segundo)\r
+\r
+"sonido" es un sample que se tocara cuando se junte el premio
\ No newline at end of file
diff --git a/extras/mapedit/eneedit.c b/extras/mapedit/eneedit.c
new file mode 100644 (file)
index 0000000..42dcefc
--- /dev/null
@@ -0,0 +1,353 @@
+/*\r
+  Editor de la matriz de enemigos para Kraptor\r
+  NOTA: si se ejecuta con krapmain.dat presente en el mismo directorio, _MUESTRA_ los enemigos\r
+  con sprites, en vez de usar los numeros. [cool!]\r
+  \r
+  Kronoman 2003\r
+  En memoria de mi querido padre\r
+  Teclas:\r
+  DELETE = casilla a 0\r
+  BARRA = situar valor seleccionado\r
+  FLECHAS = mover cursor\r
+  + y - del keypad: alterar valor en +1\r
+  1 y 2 : alterar valor en +10\r
+  0 : valor a 0\r
+  C : limpiar grilla a ceros\r
+  S : salvar grilla\r
+  L : cargar grilla\r
+  V : ver fondo sin grilla\r
+  R : agregar enemigos del tipo seleccionado al azar
+  ESC : salir\r
+\r
+ NOTA: los mapas se guardan con las funciones especiales de Allegro\r
+ para salvar los integers en un formato standard, de esa manera,\r
+ me ahorro los problemas con diferentes tama~os de enteros segun\r
+ la plataforma.\r
+\r
+  */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <allegro.h>\r
+\r
+/* Tama¤o del fondo */\r
+#define W_FONDO  600\r
+#define H_FONDO  4000\r
+\r
+/* Grilla WxH */\r
+#define W_GR 40\r
+#define H_GR 40\r
+\r
+/* Grilla */\r
+long grilla[W_FONDO / W_GR][H_FONDO / H_GR];\r
+\r
+/* En vgrilla pasar -1 para dibujarla, o 0 para ver el bitmap suelto */\r
+int vgrilla = -1;\r
+\r
+int xp = 0, yp = 0, vp = 1; /* x,y, valor a colocar */\r
+\r
+// cache de sprites de los enemigos, para mostrarlos en pantalla... :)\r
+// funciona si esta presenta krapmain.dat en el lugar\r
+#define MAX_SPR 100 // sprites cargados 0..MAX_SPR - 1\r
+BITMAP *sprite[MAX_SPR];\r
+DATAFILE *data = NULL; // datafile\r
+/* Bitmap cargado en RAM del fondo */\r
+BITMAP *fnd;\r
+PALETTE pal; /* paleta */\r
+\r
+/* Buffer de dibujo */\r
+BITMAP *buffer;\r
+\r
+\r
+// Esto carga de disco el cache de sprites\r
+// COOL!\r
+void cargar_cache_sprites()\r
+{\r
+DATAFILE *p = NULL; // punteros necesarios\r
+int i; // para el for\r
+char str[1024]; // string de uso general\r
+\r
+       for (i = 0; i < MAX_SPR; i++)   sprite[i] = NULL;\r
+       \r
+       data = load_datafile("krapmain.dat");\r
+       \r
+       if (data == NULL) return; // no esta presente el archivo - DEBUG, informar, o algo... :P        \r
+       \r
+       p = find_datafile_object(data, "enemigos");\r
+       if (p == NULL) \r
+       {\r
+               unload_datafile(data);\r
+               data = NULL;\r
+               return;\r
+       }\r
+       set_config_data((char *)p->dat, p->size);\r
+       \r
+       for (i=0; i < MAX_SPR; i++)\r
+       {\r
+       /* Seccion ENEMIGO_n */\r
+        sprintf(str,"ENEMIGO_%d", i);\r
+        \r
+               // buscar el 1er cuadro de animacion del enemigo unicamente...\r
+               p = find_datafile_object(data, get_config_string(str, "spr", "null"));\r
+               \r
+               if (p == NULL)  p = find_datafile_object(data, get_config_string(str, "spr_0", "null"));\r
+               \r
+               if (p != NULL) sprite[i] = (BITMAP *)p->dat;    \r
+               \r
+       }\r
+       \r
+       // NO se debe descargar el datafile, porque suena todo! [los sprites deben permanecer en RAM]\r
+}\r
+\r
+// Limpia la grilla con ceros\r
+void limpiar_grilla() {\r
+     int xx, yy;\r
+      /* limpio la grilla a ceros */\r
+     for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+     for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+         grilla[xx][yy] = 0;\r
+}\r
+\r
+// Redibuja la pantalla\r
+void redibujar() {\r
+   int iy, ix;\r
+\r
+   clear(buffer);\r
+   blit(fnd, buffer, 0, yp * H_GR,0,0,600,480);\r
+\r
+   /* grilla */\r
+   if (vgrilla)\r
+   {\r
+   for (ix=0; ix < W_FONDO / W_GR; ix ++ )\r
+        line(buffer, ix*W_GR, 0, ix*W_GR, 480, makecol(255,255,255));\r
+\r
+   for (iy=0; iy < H_FONDO / H_GR; iy ++ )\r
+        line(buffer, 0, iy*H_GR, fnd->w, iy*H_GR, makecol(255,255,255));\r
+   }\r
+\r
+   /* cursor */\r
+   line(buffer, xp * W_GR, 0, (xp * W_GR) + W_GR, H_GR, makecol(255, 255, 255));\r
+   line(buffer, xp * W_GR, H_GR, (xp * W_GR) + W_GR, 0, makecol(255, 255, 255));\r
+   \r
+   /* mostrar los valores (o sprite, si esta disponible) que contiene la matriz */\r
+   text_mode(makecol(0,0,0));\r
+   for (ix=0; ix < W_FONDO / W_GR; ix ++ )\r
+   {\r
+      for (iy=0; iy < H_FONDO / H_GR; iy ++ )\r
+       {     \r
+           if (yp + iy < H_FONDO / H_GR )\r
+           {\r
+                    if (grilla[ix][yp+iy] != 0)\r
+                    {\r
+                       // ver si hay un sprite disponible...   \r
+                       if ( (grilla[ix][yp+iy] > 0) && (grilla[ix][yp+iy] < MAX_SPR) )\r
+                       {\r
+                               if ( sprite[grilla[ix][yp+iy]-1] != NULL )\r
+                               {\r
+                                       if (vgrilla)\r
+                                               stretch_sprite(buffer, sprite[grilla[ix][yp+iy]-1], ix*W_GR, iy*H_GR, W_GR, H_GR);\r
+                                       else\r
+                                               draw_sprite(buffer, sprite[grilla[ix][yp+iy]-1], \r
+                                                           (W_GR / 2) - (sprite[grilla[ix][yp+iy]-1]->w / 2) + (ix*W_GR), \r
+                                                           (H_GR / 2) - (sprite[grilla[ix][yp+iy]-1]->h / 2) + (iy*H_GR));\r
+                               }\r
+                       }\r
+                    \r
+                    // valor numerico  \r
+                    textprintf(buffer, font,\r
+                               (ix*W_GR)+(W_GR/2), (iy*H_GR)+(H_GR/2), makecol(255,255,255),\r
+                               "%d", (int)grilla[ix][yp+iy]);\r
+                    }\r
+          }          \r
+        }\r
+   }\r
+   \r
+\r
+/* panel de informacion */\r
+text_mode(-1); // texto (-1=trans, 1 solido)\r
+textprintf(buffer, font, 600,0,makecol(255,255,255),\r
+           "x:%d", xp);\r
+\r
+textprintf(buffer, font, 600,20,makecol(255,255,255),\r
+           "y:%d", yp);\r
+\r
+textprintf(buffer, font, 600,40,makecol(255,255,255),\r
+           "v:%d", vp);\r
+\r
+if  ((vp > 0) && (vp < MAX_SPR))\r
+       if (sprite[vp-1] != NULL)\r
+               stretch_sprite(buffer, sprite[vp-1], 600, (text_height(font)*2)+40, 40, 40);\r
+\r
+/* mandar a pantalla */\r
+scare_mouse();\r
+blit(buffer, screen, 0,0, 0,0,SCREEN_W, SCREEN_H);\r
+unscare_mouse();\r
+}\r
+\r
+\r
+void editar_mapa() {\r
+   int k;\r
+   char salvar[1024]; /* archivo a salvar */;\r
+   salvar[0] = '\0';\r
+   \r
+   redibujar();\r
+   \r
+\r
+   while (1) {\r
+    k = readkey() >> 8;\r
+    \r
+    if (k == KEY_UP) yp--;\r
+    if (k == KEY_DOWN) yp++;\r
+    if (k == KEY_LEFT) xp--;\r
+    if (k == KEY_RIGHT) xp++;\r
+    if (k == KEY_SPACE) grilla[xp][yp] = vp;\r
+    if (k == KEY_DEL) grilla[xp][yp] = 0;\r
+    if (k == KEY_PLUS_PAD) vp++;\r
+    if (k == KEY_MINUS_PAD) vp--;\r
+    if (k == KEY_0) vp = 0;\r
+    if (k == KEY_1) vp += 10;\r
+    if (k == KEY_2) vp -= 10;\r
+\r
+    if (k == KEY_V) vgrilla = !vgrilla;\r
+    
+    if (k == KEY_R) {
+        // agregar 1 enemigo al azar... :P
+        // en una casilla vacia solamente
+        int xd, yd;
+        xd = rand()% (W_FONDO / W_GR);
+        yd = rand()% (H_FONDO / H_GR);
+        if (grilla[xd][yd] == 0) 
+       {
+           grilla[xd][yd] = vp;
+           yp = yd; xp = xd; // feedback al user
+       }
+       
+    }
+\r
+    if (k == KEY_ESC) {\r
+      if ( alert("Salir de la edicion.", "Esta seguro", "Se perderan los datos no salvados", "Si", "No", 'S', 'N') == 1) return;\r
+    }\r
+\r
+    if (k == KEY_C) {\r
+     if ( alert("Limpiar grilla.", "Esta seguro", NULL, "Si", "No", 'S', 'N') == 1)\r
+        { limpiar_grilla(); alert("La grilla se reinicio a ceros (0)", NULL, NULL, "OK", NULL, 0, 0); }\r
+    }\r
+    \r
+    if (k == KEY_S) {\r
+       if (file_select_ex("Archivo de grilla a salvar?", salvar, NULL, 512, 0, 0))\r
+       {\r
+        PACKFILE *fp;\r
+        int xx, yy;\r
+        if ((fp = pack_fopen(salvar, F_WRITE)) != NULL) {\r
+\r
+          // escribo la grilla en formato Intel de 32 bits\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                  pack_iputl(grilla[xx][yy], fp);\r
+         \r
+         pack_fclose(fp);\r
+\r
+         alert("Archivo salvado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        } else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       };\r
+    }\r
+\r
+    if (k == KEY_L)\r
+    {\r
+       if (file_select_ex("Archivo a cargar?", salvar, NULL, 512, 0, 0))\r
+       {\r
+        PACKFILE *fp;\r
+        int xx, yy;\r
+        if ((fp = pack_fopen(salvar, F_READ)) != NULL) {\r
+     \r
+          // leo la grilla en formato Intel de 32 bits\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                  grilla[xx][yy] = pack_igetl(fp);\r
+                  \r
+         pack_fclose(fp);\r
+\r
+         alert("Archivo cargado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+        else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       };\r
+    }\r
+\r
+    if (yp < 0) yp =0;\r
+    if (yp > (H_FONDO / H_GR)-1) yp = (H_FONDO / H_GR)-1;\r
+\r
+    if (xp < 0) xp =0;\r
+    if (xp > (W_FONDO / W_GR)-1) xp = (W_FONDO / W_GR)-1;\r
+\r
+    redibujar();\r
+    \r
+   }\r
+\r
+}\r
+\r
+\r
+\r
+int main() {\r
+   RGB_MAP tmp_rgb; /* acelera los calculos de makecol, etc */\r
+   char leerbmp[1024]; /* fondo a cargar */\r
+\r
+   \r
+   int card = GFX_AUTODETECT, w = 640 ,h = 480 ,color_depth = 8; /* agregado por Kronoman */\r
+\r
+   allegro_init();\r
+   install_timer();\r
+   install_keyboard();\r
+   install_mouse();\r
+\r
+   srand(time(0));\r
+\r
+   set_color_depth(color_depth);\r
+   if (set_gfx_mode(card, w, h, 0, 0)) {\r
+      allegro_message("set_gfx_mode(%d x %d x %d bpp): %s\n", w,h, color_depth, allegro_error);\r
+      return 1;\r
+   }\r
+\r
+   leerbmp[0] = '\0';\r
+   \r
+   if (!file_select_ex("Cargue el fondo por favor.", leerbmp, NULL, 512, 0, 0)) return 0;\r
+\r
+   fnd = load_bitmap(leerbmp, pal);\r
+   if (fnd == NULL || fnd->w != W_FONDO || fnd->h != H_FONDO) {\r
+      allegro_message("No se pueden cargar o es invalido \n %s!\n", leerbmp);\r
+      return 1;\r
+   }\r
+\r
+     set_palette(pal);\r
+     clear(screen);\r
+\r
+     cargar_cache_sprites(); // cargar la cache de sprites... COOL!\r
+\r
+     gui_fg_color = makecol(255,255,255);\r
+     gui_bg_color = makecol(0,0,0);\r
+     set_mouse_sprite(NULL);\r
+\r
+     /* esto aumenta un monton los fps (por el makecol acelerado... ) */\r
+     create_rgb_table(&tmp_rgb, pal, NULL); /* rgb_map es una global de Allegro! */\r
+     rgb_map = &tmp_rgb;\r
+\r
+     buffer=create_bitmap(SCREEN_W, SCREEN_H);\r
+     clear(buffer);\r
+     show_mouse(screen);\r
+\r
+\r
+     limpiar_grilla();\r
+     /* Rock & Roll! */\r
+     editar_mapa();\r
+\r
+if (data != NULL) unload_datafile(data);\r
+data = NULL;\r
+\r
+return 0;\r
+}\r
+END_OF_MAIN();\r
diff --git a/extras/mapedit/leeme.txt b/extras/mapedit/leeme.txt
new file mode 100644 (file)
index 0000000..3d6e88e
--- /dev/null
@@ -0,0 +1,4 @@
+Aqui esta el editor de las 'capas' de los mapas\r
+Kronoman\r
+En memoria de mi querido padre\r
+Agosto 2002\r
diff --git a/extras/mapedit/makefile b/extras/mapedit/makefile
new file mode 100644 (file)
index 0000000..e4e03cc
--- /dev/null
@@ -0,0 +1,3 @@
+all: mapedit.c\r eneedit.c
+       gcc mapedit.c -o mapedit.exe -lalleg -mwindows -O3 -Wall
+       gcc eneedit.c -o eneedit.exe -lalleg -mwindows -O3 -Wall
\ No newline at end of file
diff --git a/extras/mapedit/makegrid.c b/extras/mapedit/makegrid.c
new file mode 100644 (file)
index 0000000..82fcb27
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+Este programa fabrica la grilla en un bmp  \r
+  */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <allegro.h>\r
+\r
+/* Tama¤o del fondo */\r
+#define W_FONDO  600\r
+#define H_FONDO  4000\r
+\r
+/* Grilla WxH */\r
+#define W_GR 40\r
+#define H_GR 40\r
+\r
+\r
+int main() {\r
+   BITMAP *bmp;\r
+   PALETTE pal;\r
+   int iy, ix;\r
+\r
+   int card = GFX_AUTODETECT, w = 640 ,h = 480 ,color_depth = 8; /* agregado por Kronoman */\r
+\r
+   allegro_init();\r
+   install_timer();\r
+   install_keyboard();\r
+   install_mouse();\r
+\r
+   set_color_depth(color_depth);\r
+   if (set_gfx_mode(card, w, h, 0, 0)) {\r
+      allegro_message("set_gfx_mode(%d x %d x %d bpp): %s\n", w,h, color_depth, allegro_error);\r
+      return 1;\r
+   }\r
+\r
+   set_palette(default_palette);\r
+   clear(screen);\r
+\r
+   get_palette(pal);\r
+   bmp = create_bitmap(W_FONDO, H_FONDO);\r
+   clear(bmp);\r
+\r
+   for (ix=0; ix < W_FONDO / W_GR; ix ++ )\r
+        line(bmp, ix*W_GR, 0, ix*W_GR, H_FONDO, makecol(255,255,255));\r
+\r
+   for (iy=0; iy < H_FONDO / H_GR; iy ++ )\r
+        line(bmp, 0, iy*H_GR, W_FONDO, iy*H_GR, makecol(255,255,255));\r
+\r
+\r
+   save_bitmap("grilla.pcx", bmp, pal);\r
+   destroy_bitmap(bmp);\r
+    \r
+return 0;\r
+}\r
+END_OF_MAIN();\r
diff --git a/extras/mapedit/mapedit.c b/extras/mapedit/mapedit.c
new file mode 100644 (file)
index 0000000..f9391c7
--- /dev/null
@@ -0,0 +1,254 @@
+/*\r
+  Editor de la matriz de mapa para Kraptor\r
+  Kronoman 2002\r
+  En memoria de mi querido padre\r
+  Teclas:\r
+  DELETE = casilla a 0\r
+  BARRA = situar valor seleccionado\r
+  FLECHAS = mover cursor\r
+  + y - del keypad: alterar valor en +1\r
+  1 y 2 : alterar valor en +10\r
+  0 : valor a 0\r
+  C : limpiar grilla a ceros\r
+  S : salvar grilla\r
+  L : cargar grilla\r
+  V : ver fondo sin grilla\r
+  ESC : salir\r
+\r
+ NOTA: los mapas se guardan con las funciones especiales de Allegro\r
+ para salvar los integers en un formato standard, de esa manera,\r
+ me ahorro los problemas con diferentes tama~os de enteros segun\r
+ la plataforma.\r
+\r
+  */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <allegro.h>\r
+\r
+/* Tama¤o del fondo */\r
+#define W_FONDO  600\r
+#define H_FONDO  4000\r
+\r
+/* Grilla WxH */\r
+#define W_GR 40\r
+#define H_GR 40\r
+\r
+/* Grilla */\r
+long grilla[W_FONDO / W_GR][H_FONDO / H_GR];\r
+\r
+/* En vgrilla pasar -1 para dibujarla, o 0 para ver el bitmap suelto */\r
+int vgrilla = -1;\r
+\r
+\r
+int xp = 0, yp = 0, vp = 30; /* x,y, valor a colocar */\r
+\r
+/* Bitmap cargado en RAM del fondo */\r
+BITMAP *fnd;\r
+PALETTE pal; /* paleta */\r
+\r
+/* Buffer de dibujo */\r
+BITMAP *buffer;\r
+\r
+void limpiar_grilla() {\r
+     int xx, yy;\r
+      /* limpio la grilla a ceros */\r
+     for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+     for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+         grilla[xx][yy] = 0;\r
+}\r
+\r
+void redibujar() {\r
+   int iy, ix;\r
+\r
+   clear(buffer);\r
+   blit(fnd, buffer, 0, yp * H_GR,0,0,600,480);\r
+\r
+   /* grilla */\r
+   if (vgrilla)\r
+   {\r
+   for (ix=0; ix < W_FONDO / W_GR; ix ++ )\r
+        line(buffer, ix*W_GR, 0, ix*W_GR, 480, makecol(255,255,255));\r
+\r
+   for (iy=0; iy < H_FONDO / H_GR; iy ++ )\r
+        line(buffer, 0, iy*H_GR, fnd->w, iy*H_GR, makecol(255,255,255));\r
+\r
+\r
+   /* cursor */\r
+   line(buffer, xp * W_GR, 0, (xp * W_GR) + W_GR, H_GR, makecol(255, 255, 255));\r
+   line(buffer, xp * W_GR, H_GR, (xp * W_GR) + W_GR, 0, makecol(255, 255, 255));\r
+   \r
+   /* mostrar los valores que contiene la matriz */\r
+   text_mode(makecol(0,0,0));\r
+   for (ix=0; ix < W_FONDO / W_GR; ix ++ )\r
+      for (iy=0; iy < H_FONDO / H_GR; iy ++ )\r
+           if (yp + iy < H_FONDO / H_GR )\r
+                    if (grilla[ix][yp+iy] != 0)\r
+                    textprintf(buffer, font,\r
+                               (ix*W_GR)+(W_GR/2), (iy*H_GR)+(H_GR/2), makecol(255,255,255),\r
+                               "%d", (int)grilla[ix][yp+iy]);\r
+   }\r
+/* Informacion */\r
+text_mode(-1); // texto (-1=trans, 1 solido)\r
+textprintf(buffer, font, 600,0,makecol(255,255,255),\r
+           "x:%d", xp);\r
+\r
+textprintf(buffer, font, 600,20,makecol(255,255,255),\r
+           "y:%d", yp);\r
+\r
+textprintf(buffer, font, 600,40,makecol(255,255,255),\r
+           "v:%d", vp);\r
+\r
+/* mandar a pantalla */\r
+scare_mouse();\r
+blit(buffer, screen, 0,0, 0,0,SCREEN_W, SCREEN_H);\r
+unscare_mouse();\r
+}\r
+\r
+\r
+void editar_mapa() {\r
+   int k;\r
+   char salvar[1024]; /* archivo a salvar */;\r
+   salvar[0] = '\0';\r
+   \r
+   redibujar();\r
+   \r
+\r
+   while (1) {\r
+    k = readkey() >> 8;\r
+    \r
+    if (k == KEY_UP) yp--;\r
+    if (k == KEY_DOWN) yp++;\r
+    if (k == KEY_LEFT) xp--;\r
+    if (k == KEY_RIGHT) xp++;\r
+    if (k == KEY_SPACE) grilla[xp][yp] = vp;\r
+    if (k == KEY_DEL) grilla[xp][yp] = 0;\r
+    if (k == KEY_PLUS_PAD) vp++;\r
+    if (k == KEY_MINUS_PAD) vp--;\r
+    if (k == KEY_0) vp = 0;\r
+    if (k == KEY_1) vp += 10;\r
+    if (k == KEY_2) vp -= 10;\r
+\r
+    if (k == KEY_V) vgrilla = !vgrilla;\r
+\r
+    if (k == KEY_ESC) {\r
+      if ( alert("Salir de la edicion.", "Esta seguro", "Se perderan los datos no salvados", "Si", "No", 'S', 'N') == 1) return;\r
+    }\r
+\r
+    if (k == KEY_C) {\r
+     if ( alert("Limpiar grilla.", "Esta seguro", NULL, "Si", "No", 'S', 'N') == 1)\r
+        { limpiar_grilla(); alert("La grilla se reinicio a ceros (0)", NULL, NULL, "OK", NULL, 0, 0); }\r
+    }\r
+    \r
+    if (k == KEY_S) {\r
+       if (file_select_ex("Archivo de grilla a salvar?", salvar, NULL, 512, 0, 0))\r
+       {\r
+        PACKFILE *fp;\r
+        int xx, yy;\r
+        if ((fp = pack_fopen(salvar, F_WRITE)) != NULL) {\r
+\r
+          // escribo la grilla en formato Intel de 32 bits\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                  pack_iputl(grilla[xx][yy], fp);\r
+         \r
+         pack_fclose(fp);\r
+\r
+         alert("Archivo salvado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        } else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       };\r
+    }\r
+\r
+    if (k == KEY_L)\r
+    {\r
+       if (file_select_ex("Archivo a cargar?", salvar, NULL, 512, 0, 0))\r
+       {\r
+        PACKFILE *fp;\r
+        int xx, yy;\r
+        if ((fp = pack_fopen(salvar, F_READ)) != NULL) {\r
+          // leo la grilla en formato Intel de 32 bits\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                  grilla[xx][yy] = pack_igetl(fp);\r
+                  \r
+         pack_fclose(fp);\r
+\r
+         alert("Archivo cargado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+        else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       };\r
+    }\r
+\r
+    if (yp < 0) yp =0;\r
+    if (yp > (H_FONDO / H_GR)-1) yp = (H_FONDO / H_GR)-1;\r
+\r
+    if (xp < 0) xp =0;\r
+    if (xp > (W_FONDO / W_GR)-1) xp = (W_FONDO / W_GR)-1;\r
+\r
+    redibujar();\r
+    \r
+   }\r
+\r
+}\r
+\r
+\r
+\r
+int main() {\r
+   RGB_MAP tmp_rgb; /* acelera los calculos de makecol, etc */\r
+   char leerbmp[1024]; /* fondo a cargar */\r
+\r
+   \r
+   int card = GFX_AUTODETECT, w = 640 ,h = 480 ,color_depth = 8; /* agregado por Kronoman */\r
+\r
+   allegro_init();\r
+   install_timer();\r
+   install_keyboard();\r
+   install_mouse();\r
+\r
+   srand(time(0));\r
+\r
+   set_color_depth(color_depth);\r
+   if (set_gfx_mode(card, w, h, 0, 0)) {\r
+      allegro_message("set_gfx_mode(%d x %d x %d bpp): %s\n", w,h, color_depth, allegro_error);\r
+      return 1;\r
+   }\r
+\r
+   leerbmp[0] = '\0';\r
+   \r
+   if (!file_select_ex("Cargue el fondo por favor.", leerbmp, NULL, 512, 0, 0)) return 0;\r
+\r
+   fnd = load_bitmap(leerbmp, pal);\r
+   if (fnd == NULL || fnd->w != W_FONDO || fnd->h != H_FONDO) {\r
+      allegro_message("No se pueden cargar o es invalido \n %s!\n", leerbmp);\r
+      return 1;\r
+   }\r
+\r
+     set_palette(pal);\r
+     clear(screen);\r
+\r
+gui_fg_color = makecol(255,255,255);\r
+gui_bg_color = makecol(0,0,0);\r
+set_mouse_sprite(NULL);\r
+\r
+     /* esto aumenta un monton los fps (por el makecol acelerado... ) */\r
+     create_rgb_table(&tmp_rgb, pal, NULL); /* rgb_map es una global de Allegro! */\r
+     rgb_map = &tmp_rgb;\r
+\r
+     buffer=create_bitmap(SCREEN_W, SCREEN_H);\r
+     clear(buffer);\r
+     show_mouse(screen);\r
+\r
+\r
+     limpiar_grilla();\r
+     /* Rock & Roll! */\r
+     editar_mapa();\r
+     \r
+return 0;\r
+}\r
+END_OF_MAIN();\r
diff --git a/extras/shader/leeme.txt b/extras/shader/leeme.txt
new file mode 100644 (file)
index 0000000..f85ac52
--- /dev/null
@@ -0,0 +1,6 @@
+Shader\r
+\r
+\r
+Programa utilitario de ayuda para generar las sombras\r
+de los edificios de los mapas de Kraptor.\r
+\r
diff --git a/extras/shader/makefile b/extras/shader/makefile
new file mode 100644 (file)
index 0000000..f4374ed
--- /dev/null
@@ -0,0 +1,4 @@
+all: shader.exe\r
+\r
+shader.exe: shader.c\r
+       gcc shader.c -o shader.exe -lalleg -mwindows -O3 -Wall
\ No newline at end of file
diff --git a/extras/shader/shader.c b/extras/shader/shader.c
new file mode 100644 (file)
index 0000000..623800a
--- /dev/null
@@ -0,0 +1,385 @@
+/*\r
+  shader.c\r
+  Sombreador automatico para los mapas de Kraptor\r
+  Copyright (c) 2002, Kronoman\r
+  NOTA: el codigo es una porqueria, repetitivo, no optimizado, etc\r
+        lo escribi en 15" para resolver un problema especifico\r
+\r
+  Teclado:\r
+    Arr, Abj = scroll del mapa\r
+    V = ver grilla + info, si/no\r
+    Q,W = color de la sombra\r
+    O,P = grosor de la sombra\r
+    T = ajustar a grilla on/off\r
+    ESC = salir\r
+    S = salvar bmp\r
+    L = cargar bmp\r
+  Mouse:\r
+   click izquierdo: los 2 primeros setean el rectangulo de sombreado\r
+                    el 3 click sombrea (confirma primero)\r
+\r
+   click derecho: limpia el rectangulo de seleccion\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <allegro.h>\r
+\r
+/* Grilla WxH */\r
+#define W_GR 40\r
+#define H_GR 40\r
+\r
+/* ancho de la sombra */\r
+int w_sombra = 10;\r
+// oscuridad de sombra (0 = negro, 255 = blanco)\r
+int c_sombra = 16;\r
+\r
+// scroll del mapa\r
+int yp = 0;\r
+\r
+// area del rectangulo a sombrear\r
+// -1 indica area no seleccionada\r
+int xr1 = -1;\r
+int yr1 = -1;\r
+int xr2 = -1;\r
+int yr2 = -1;\r
+\r
+\r
+/* En vgrilla pasar -1 para dibujarla, o 0 para ver el bitmap suelto */\r
+int vgrilla = -1;\r
+\r
+/* ajustar a grilla? */\r
+int snapgrid = -1;\r
+\r
+/* Bitmap cargado en RAM del fondo */\r
+BITMAP *fnd;\r
+PALETTE pal; /* paleta */\r
+RGB_MAP tmp_rgb; /* acelera los calculos de makecol, etc */\r
+COLOR_MAP trans_table; /* mapa de transparencia */\r
+\r
+/* Doble buffer */\r
+BITMAP *buffer;\r
+\r
+\r
+void redibujar() {\r
+   int iy, ix;\r
+\r
+   clear(buffer);\r
+   blit(fnd, buffer, 0, yp,0,0,fnd->w,SCREEN_H);\r
+\r
+   /* grilla */\r
+   if (vgrilla)\r
+   {\r
+   for (ix=0; ix < fnd->w / W_GR; ix ++ )\r
+        line(buffer, ix*W_GR, 0, ix*W_GR, 480, makecol(255,255,255));\r
+\r
+   for (iy=0; iy < fnd->h / H_GR; iy ++ )\r
+        line(buffer, 0, iy*H_GR, fnd->w, iy*H_GR, makecol(255,255,255));\r
+\r
+    /* Informacion */\r
+    text_mode(-1); // texto (-1=trans, 1 solido)\r
+\r
+    textprintf(buffer, font, 600,0,makecol(255,255,255),\r
+               "%d", yp);\r
+\r
+     if (xr1 >= 0 )\r
+        {\r
+         textprintf(buffer, font, 600,20,makecol(255,255,255),\r
+                    "x1:%d",xr1);\r
+         textprintf(buffer, font, 600,40,makecol(255,255,255),\r
+                    "y1:%d",yr1);\r
+        }\r
+\r
+     if (xr2 >= 0)\r
+        {\r
+         textprintf(buffer, font, 600,60,makecol(255,255,255),\r
+                    "x2:%d",xr2);\r
+         textprintf(buffer, font, 600,80,makecol(255,255,255),\r
+                    "y2:%d",yr2);\r
+        }\r
+\r
+     textprintf(buffer, font, 600,100,makecol(255,255,255),\r
+                "g[%s]", (snapgrid) ? "*" : " " );\r
+\r
+     textprintf(buffer, font, 600,120,makecol(255,255,255),\r
+                "w:%d", w_sombra);\r
+\r
+     textprintf(buffer, font, 600,140,makecol(255,255,255),\r
+                "c:%d", c_sombra);\r
+   }\r
+\r
+   /* rectangulo de seleccion */\r
+   if (xr1 >= 0 )\r
+   {\r
+    if (xr2 >= 0)\r
+    {\r
+    rect(buffer, xr1,  yr1-yp, xr2, yr2-yp, makecol(0,255,255) );\r
+    line(buffer, xr1,  yr1-yp, xr2, yr2-yp, makecol(0,255,255) );\r
+    line(buffer, xr2,  yr1-yp, xr1, yr2-yp, makecol(0,255,255) );\r
+\r
+      // preview de como queda la sombra\r
+      line(buffer, xr1,  yr2-yp, xr1-w_sombra, yr2-yp+w_sombra, makecol(0,255,255) );\r
+      line(buffer, xr1,  yr1-yp, xr1-w_sombra, yr1-yp+w_sombra, makecol(0,255,255) );\r
+      line(buffer, xr2,  yr2-yp, xr2-w_sombra, yr2-yp+w_sombra, makecol(0,255,255) );\r
+\r
+      line(buffer, xr1-w_sombra, yr1-yp+w_sombra, xr1-w_sombra, yr2-yp+w_sombra,makecol(0,255,255) );\r
+      line(buffer, xr1-w_sombra, yr2-yp+w_sombra, xr2-w_sombra, yr2-yp+w_sombra, makecol(0,255,255) );\r
+\r
+      circle(buffer, xr1, yr1-yp, 5, makecol(255,0,255));\r
+      circle(buffer, xr2, yr2-yp, 5, makecol(255,255,0));\r
+    }\r
+    else\r
+    {\r
+      line(buffer, xr1,  yr1-yp-5, xr1, yr1-yp+5, makecol(0,255,255) );\r
+      line(buffer, xr1-5,  yr1-yp, xr1+5, yr1-yp, makecol(0,255,255) );\r
+      circle(buffer, xr1, yr1-yp, 5, makecol(255,0,255));\r
+    }\r
+   }\r
+\r
+\r
+/* mandar a pantalla */\r
+scare_mouse();\r
+ blit(buffer, screen, 0,0, 0,0,SCREEN_W, SCREEN_H);\r
+unscare_mouse();\r
+}\r
+\r
+\r
+void editar_mapa() {\r
+   int k;\r
+   char salvar[1024]; /* archivo a salvar */;\r
+   salvar[0] = '\0';\r
+\r
+   static void reset_vars()\r
+   {\r
+       yp = 0;\r
+       xr1 = -1;\r
+       yr1 = -1;\r
+       xr2 = -1;\r
+       yr2 = -1;\r
+   }\r
+\r
+   reset_vars();\r
+   redibujar();\r
+\r
+   while (1) {\r
+\r
+    while (!keypressed() && mouse_b == 0);\r
+\r
+    if (mouse_b == 0)\r
+       k = readkey() >> 8;\r
+      else\r
+       k = 0;\r
+\r
+    // Selecciono boton?\r
+    if (mouse_b & 1) // boton normal, seleccionar\r
+       {\r
+       int s; // lo uso mas abajo...\r
+\r
+        if (xr1 < 0) // asignar primer esquina\r
+        {\r
+          if (snapgrid)\r
+          {\r
+               xr1 = (mouse_x / W_GR) * W_GR;\r
+               yr1 = ((mouse_y + yp) / H_GR) * H_GR;\r
+          }\r
+          else\r
+          {\r
+              xr1 = mouse_x;\r
+              yr1 = mouse_y + yp;\r
+          }\r
+        }\r
+        else\r
+        {\r
+          if (xr2 < 0) // asignar 2nda esquina\r
+          {\r
+              if (snapgrid)\r
+              {\r
+                   xr2 = (mouse_x / W_GR) * W_GR;\r
+                   yr2 = ((mouse_y + yp) / H_GR) * H_GR;\r
+              }\r
+              else\r
+              {\r
+                  xr2 = mouse_x;\r
+                  yr2 = mouse_y + yp;\r
+              }\r
+          }\r
+          else // Sombrear\r
+          {\r
+          if ( alert("Sombrear seleccion", "Esta seguro?", "No hay UNDO!", "Si", "No", 'S', 'N') == 1)\r
+           {\r
+            int c;\r
+\r
+            drawing_mode(DRAW_MODE_TRANS, NULL, 0,0);\r
+            c = makecol(c_sombra,c_sombra,c_sombra);\r
+            for (s = 0; s < w_sombra; s++)\r
+            {\r
+              line(fnd, xr1-s, yr1+s, xr1-s, yr2+s, c);\r
+              line(fnd, xr1-s+1, yr2+s, xr2-s, yr2+s, c);\r
+            }\r
+            solid_mode();\r
+           }\r
+          }\r
+        }\r
+\r
+        while (mouse_b);\r
+\r
+            if (xr1 > xr2 && xr2 > -1)\r
+              {\r
+               s = xr2;\r
+               xr2 = xr1;\r
+               xr1 = s;\r
+              }\r
+\r
+            if (yr1 > yr2  && yr2 > -1)\r
+              {\r
+               s = yr2;\r
+               yr2 = yr1;\r
+               yr1 = s;\r
+              }\r
+       }\r
+\r
+    if (mouse_b & 2) // boton derecho, de-seleccionar\r
+      {\r
+          xr1 = -1;\r
+          yr1 = -1;\r
+          xr2 = -1;\r
+          yr2 = -1;\r
+\r
+          while (mouse_b);\r
+      }\r
+\r
+    // Teclado...\r
+    if (k == KEY_UP)    yp -= 40;\r
+    if (k == KEY_DOWN)  yp += 40;\r
+\r
+    if (k == KEY_V) vgrilla = !vgrilla;\r
+\r
+    if (k == KEY_Q) c_sombra++;\r
+    if (k == KEY_W) c_sombra--;\r
+\r
+    if (k == KEY_O) w_sombra++;\r
+    if (k == KEY_P) w_sombra--;\r
+\r
+    w_sombra %=  256; //ajustar a rango 0..255\r
+    if (w_sombra < 0) w_sombra = 255;\r
+    c_sombra %=  256; //ajustar a rango 0..255\r
+    if (c_sombra < 0) c_sombra = 255;\r
+\r
+    if (k == KEY_T) snapgrid = !snapgrid;\r
+\r
+    if (k == KEY_ESC) {\r
+      if ( alert("Salir de la edicion.", "Esta seguro", "Se perderan los datos no salvados", "Si", "No", 'S', 'N') == 1) return;\r
+    }\r
+    \r
+    if (k == KEY_S) {\r
+       if (file_select_ex("Archivo a salvar?", salvar, NULL, 512, 0, 0))\r
+       {\r
+        if (!save_bitmap(salvar, fnd, pal)) { // DEBUG:falta hacer\r
+         alert("Archivo salvado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        } else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       };\r
+    }\r
+\r
+    if (k == KEY_L) {\r
+       if (file_select_ex("Cargue la imagen por favor.", salvar, NULL, 512, 0, 0))\r
+       {\r
+        BITMAP *tmp;\r
+        tmp = load_bitmap(salvar, pal);\r
+        if (tmp != NULL)\r
+        {\r
+            destroy_bitmap(fnd);\r
+            fnd = tmp;\r
+            set_palette(pal);\r
+            clear(screen);\r
+gui_fg_color = makecol(255,255,255);\r
+gui_bg_color = makecol(0,0,0);\r
+set_mouse_sprite(NULL);\r
+        \r
+            /* esto aumenta un monton los fps (por el makecol acelerado... ) */\r
+            create_rgb_table(&tmp_rgb, pal, NULL); /* rgb_map es una global de Allegro! */\r
+            rgb_map = &tmp_rgb;\r
+        \r
+            create_trans_table(&trans_table, pal, 128, 128, 128, NULL); // transparencias\r
+            color_map = &trans_table;\r
+\r
+            alert("Archivo cargado.", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+        else\r
+        {\r
+         alert("Fallo la apertura del archivo!", salvar, NULL, "OK", NULL, 0, 0);\r
+        }\r
+       }\r
+    }\r
+\r
+    if (yp < 0) yp =0;\r
+    if (yp > fnd->h - SCREEN_H) yp = fnd->h - SCREEN_H;\r
+\r
+    redibujar();\r
+    \r
+   }\r
+\r
+}\r
+\r
+\r
+\r
+int main() {\r
+   char leerbmp[1024]; /* fondo a cargar */\r
+\r
+   int card = GFX_AUTODETECT, w = 640 ,h = 480 ,color_depth = 8;\r
+\r
+   allegro_init();\r
+   install_timer();\r
+   install_keyboard();\r
+   install_mouse();\r
+\r
+   srand(time(0));\r
+\r
+   set_gfx_mode(GFX_SAFE, 0,0,0,0);\r
+\r
+   gfx_mode_select_ex(&card, &w, &h, &color_depth);\r
+\r
+   set_color_depth(color_depth);\r
+   if (set_gfx_mode(card, w, h, 0, 0)) {\r
+      allegro_message("set_gfx_mode(%d x %d x %d bpp): %s\n", w,h, color_depth, allegro_error);\r
+      return 1;\r
+   }\r
+\r
+\r
+   set_trans_blender(128, 128, 128, 128);\r
+\r
+   leerbmp[0] = '\0';\r
+   \r
+   if (!file_select_ex("Cargue la imagen por favor.", leerbmp, NULL, 512, 0, 0)) return 0;\r
+\r
+   fnd = load_bitmap(leerbmp, pal);\r
+   if (fnd == NULL) {\r
+      allegro_message("No se pueden cargar o es invalido \n %s!\n", leerbmp);\r
+      return 1;\r
+   }\r
+\r
+     set_palette(pal);\r
+     clear(screen);\r
+gui_fg_color = makecol(255,255,255);\r
+gui_bg_color = makecol(0,0,0);\r
+set_mouse_sprite(NULL);\r
+\r
+     /* esto aumenta un monton los fps (por el makecol acelerado... ) */\r
+     create_rgb_table(&tmp_rgb, pal, NULL); /* rgb_map es una global de Allegro! */\r
+     rgb_map = &tmp_rgb;\r
+\r
+     create_trans_table(&trans_table, pal, 128, 128, 128, NULL); // transparencias\r
+     color_map = &trans_table;\r
+\r
+     buffer=create_bitmap(SCREEN_W, SCREEN_H);\r
+     clear(buffer);\r
+     show_mouse(screen);\r
+\r
+     /* Rock & Roll! */\r
+     editar_mapa();\r
+     \r
+return 0;\r
+}\r
+END_OF_MAIN();\r
diff --git a/fix.bat b/fix.bat
new file mode 100644 (file)
index 0000000..7bfe8d8
--- /dev/null
+++ b/fix.bat
@@ -0,0 +1,97 @@
+@echo off\r
+\r
+rem Sets makefile source code for the different platforms\r
+rem Based on fix.bat of Allegro.\r
+rem Modified By Kronoman - In loving memory of my father.\r
+\r
+\r
+echo Kraptor Engine\r
+echo --------------\r
+echo.\r
+echo By Kronoman - In loving memory of my father\r
+echo.\r
+echo.\r
+\r
+if [%1] == [linux]   goto linux\r
+if [%1] == [djgpp]   goto djgpp\r
+if [%1] == [mingw32] goto mingw32\r
+if [%1] == [test] goto test\r
+goto help\r
+\r
+\r
+:test\r
+REM REMEMBER TO ALTER THIS TEST TO SUIT YOUR NEEDS!!!\r
+\r
+REM You first need to configure the platform\r
+if exist target.os goto targetok\r
+    echo Before test, you first must configure your platform.\r
+goto help\r
+\r
+:targetok\r
+\r
+echo Testing, please wait...\r
+make test\r
+\r
+if not errorlevel 0 goto testfail\r
+if not exist test.run goto testfail\r
+\r
+    echo.\r
+    echo * SUCESS *\r
+    echo Congratulations, the test compiled!\r
+    echo.\r
+\r
+goto testdone\r
+\r
+:testfail\r
+    echo.\r
+    echo * ERROR *\r
+    echo.\r
+    echo The compilation returned a error!\r
+    echo Check that:\r
+    echo (*) You have all compiler tools installed (gcc,make,etc)\r
+    echo (*) You have Allegro library properly installed (http://alleg.sf.net/)\r
+    echo (*) You have DUMB Music library properly installed (http://dumb.sf.net/)\r
+    echo.\r
+\r
+:testdone\r
+    echo Cleaning the test...\r
+    make cleantest\r
+    \r
+goto done\r
+\r
+:djgpp\r
+echo Configuring for DOS/djgpp...\r
+echo # Warning! This file will be overwritten by configuration routines! > target.os\r
+echo TARGET=DJGPP>> target.os\r
+goto done\r
+\r
+\r
+:mingw32\r
+echo Configuring for Windows/Mingw32...\r
+echo # Warning! This file will be overwritten by configuration routines! > target.os\r
+echo TARGET=MINGW32>> target.os\r
+goto done\r
+\r
+\r
+:linux\r
+echo Configuring for Linux/GCC...\r
+echo # Warning! This file will be overwritten by configuration routines! > target.os\r
+echo TARGET=LINUX>> target.os\r
+goto done\r
+\r
+\r
+:help\r
+echo Usage: fix platform\r
+echo.\r
+echo Where platform is one of: djgpp, mingw32 or linux. \r
+echo.\r
+echo NOTICE:\r
+echo You can also call: fix test\r
+echo to check if your system can compile this programs.\r
+echo.\r
+goto end\r
+\r
+:done\r
+echo Done!\r
+\r
+:end
\ No newline at end of file
diff --git a/fix.sh b/fix.sh
new file mode 100755 (executable)
index 0000000..b0a56fb
--- /dev/null
+++ b/fix.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+#
+# Sets makefile source code for the different platforms
+# Based on fix.sh of Allegro.
+# Modified By Kronoman - In loving memory of my father.
+
+echo "Kraptor Engine"
+echo "--------------"
+echo
+echo "By Kronoman - In loving memory of my father"
+echo
+echo
+
+
+# REMEMBER TO ALTER THIS TEST TO SUIT YOUR NEEDS!!!
+proc_test()
+{
+    # You first need to configure the platform
+    if [ ! -e target.os ]; then
+       echo "Before test, you first must configure your platform."
+       proc_help;
+    else
+       echo Testing, please wait...
+       make test
+       
+       if [ $? -eq 0 -a -e test.run ]; then
+           echo
+           echo "* SUCESS *"
+           echo "Congratulations, the test compiled!"
+           echo
+       else
+           echo
+           echo "* ERROR *"
+           echo
+           echo "The compilation returned a error or can't be runned!"
+           echo "Check that:"
+           echo "(*) You have all compiler tools installed (gcc,make,etc)"
+           echo "(*) You have Allegro library properly installed (http://alleg.sf.net/)"
+           echo "(*) You have DUMB Music library properly installed (http://dumb.sf.net/)"
+           echo
+       fi
+
+       echo "Cleaning the test..."
+       make cleantest
+    fi 
+}
+
+proc_help()
+{
+   echo "Usage: fix platform"
+   echo
+   echo "Where platform is one of: djgpp, mingw32 or linux. "
+   echo
+   echo "NOTICE:"
+   echo "You can also call: fix test"
+   echo "to check if your system can compile this programs."
+   echo
+   echo
+}
+
+proc_fix()
+{
+   echo "Configuring for $1..."
+
+   if [ "$2" != "none" ]; then
+      echo "# Warning! This file will be overwritten by configuration routines!" > target.os
+      echo "TARGET=$2" >> target.os
+   fi
+}
+
+
+# prepare for the given platform.
+
+case "$1" in
+   "djgpp"   ) proc_fix "DOS (djgpp)"       "DJGPP";;
+   "mingw32" ) proc_fix "Windows (Mingw32)" "MINGW32";;
+   "linux"   ) proc_fix "Linux (GCC)"       "LINUX";;
+   "test"    ) proc_test;;
+   "help"    ) proc_help;;
+   *         ) proc_help;;
+esac
+
+echo "Done!"
diff --git a/include/azar.h b/include/azar.h
new file mode 100644 (file)
index 0000000..fafc9e0
--- /dev/null
@@ -0,0 +1,20 @@
+// azar.h\r
+// Macro para numeros al azar\r
+// Elige un numero entre min y max\r
+// Tomado de la internet\r
+\r
+#ifndef AZAR_H\r
+#define AZAR_H\r
+\r
+#include <stdlib.h>\r
+\r
+/*\r
+Esta funcion explota si min - max da 0, sorry, pero la cambie...\r
+*/\r
+// #define rand_ex( min, max )   ( (rand() % (max - min)) + min )\r
+\r
+\r
+/* Prototipo */\r
+int rand_ex(int min, int max);\r
+\r
+#endif\r
diff --git a/include/bomba.h b/include/bomba.h
new file mode 100644 (file)
index 0000000..5d8b034
--- /dev/null
@@ -0,0 +1,22 @@
+// -------------------------------------------------------- \r
+// bomba.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Este modulo contiene todo lo relacionado con las bombas\r
+// del jugador...\r
+// -------------------------------------------------------- \r
+#ifndef BOMBA_H\r
+#define BOMBA_H\r
+\r
+extern int bomba_esta_activa;\r
+extern int bomba_detonacion;\r
+extern SAMPLE *bomba_sonido;\r
+\r
+// Prototipos\r
+void mover_bomba();\r
+void dibujar_bomba();\r
+void detonar_totalmente_el_piso(int y);\r
+\r
+#endif\r
diff --git a/include/captura.h b/include/captura.h
new file mode 100644 (file)
index 0000000..10839f1
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+ --------------------------------------------------------\r
+ captura.h \r
+ -------------------------------------------------------- \r
+ Copyright (c) Kronoman \r
+ En memoria de mi querido padre \r
+ -------------------------------------------------------- \r
+ Funcion para tomar una captura de pantalla\r
+ Automaticamente la salva en archivoxxx.pcx, etc\r
+ -------------------------------------------------------- \r
+*/\r
+#ifndef CAPTURAR_H\r
+#define CAPTURAR_H\r
+\r
+#include <stdio.h>\r
+#include "allegro.h"\r
+\r
+/* Esta funcion captura la pantalla, usando el prefijo para el archivo\r
+   Salva un PCX de 8 bits de color.\r
+*/\r
+void capturar_la_pantalla(char *prefijo);\r
+\r
+#endif\r
+\r
+\r
diff --git a/include/cinema.h b/include/cinema.h
new file mode 100644 (file)
index 0000000..46ab6c0
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ --------------------------------------------------------\r
+ cinema.h\r
+ --------------------------------------------------------\r
+ Copyright (c) Septiembre 2002, Kronoman\r
+ En memoria de mi querido padre\r
+ --------------------------------------------------------\r
+ Engine de cinematicas mediante scripts y datafiles\r
+ -------------------------------------------------------- */\r
+\r
+#ifndef CINEMA_H\r
+#define CINEMA_H\r
+\r
+\r
+/* Estructura que contiene la lista de funciones que puede\r
+   utilizar el script,\r
+   contiene  el comando, y un puntero a la funcion...\r
+   el ultimo item debe contener NULL en todos los parametros */\r
+typedef struct CMD_SCRIPT_TYPE\r
+{\r
+  char *comando;    /* comando que ejecuta el procedimiento */\r
+  int (*proc)();    /* procedimiento que es llamado, devuelve -1 si pasa un error, -666 si se debe cancelar la cinematica */\r
+  int min_params;   /* cantidad minima de parametros que precisa */\r
+} CMD_SCRIPT_TYPE;\r
+\r
+/* Cantidad maxima de parametros que se pueden leer de un solo 'saque' */\r
+#define MAX_PARAMS  100\r
+/* Largo maximo de linea a interpretar */\r
+#define MAX_LINEA 2048\r
+\r
+/* Prototipos */\r
+/* Funciones propias */\r
+void ejecutar_cinematica(char *file);\r
+void ejecutar_script(const char *txt_script, const int size, DATAFILE *archivo);\r
+int parsear_y_ejecutar_linea();\r
+\r
+/* Prototipos de funciones de interpretacion */\r
+int cmd_cls();\r
+int cmd_rect();\r
+int cmd_rectfill();\r
+int cmd_line();\r
+int cmd_fade_out();\r
+int cmd_fade_out_color();\r
+int cmd_locate();\r
+int cmd_text_color();\r
+int cmd_text_back();\r
+int cmd_text_font();\r
+int cmd_echo();\r
+int cmd_echo_centre_x();\r
+int cmd_echo_centre_xy();\r
+int cmd_rest();\r
+int cmd_set_palette();\r
+int cmd_set_palette_default();\r
+int cmd_blit();\r
+int cmd_sprite();\r
+int cmd_stretch_blit();\r
+int cmd_play_sample();\r
+int cmd_play_fli();\r
+int cmd_clear_fli_back();\r
+int cmd_keyboard_cancel_fli();\r
+#endif\r
diff --git a/include/clima.h b/include/clima.h
new file mode 100644 (file)
index 0000000..e7a9919
--- /dev/null
@@ -0,0 +1,31 @@
+// ------------------------------------\r
+// clima.h\r
+// ------------------------------------\r
+// Modulo de efectos climaticos\r
+// Por Kronoman\r
+// En memoria de mi querido padre\r
+// Copyright (c) 2002, Kronoman\r
+// ------------------------------------\r
+#ifndef CLIMA_H\r
+#define CLIMA_H\r
+\r
+#include <allegro.h>\r
+\r
+// Estructura de particula de clima, para ser usada como una array\r
+typedef struct CLIMA_P {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int col, r;   /* color y radio */\r
+    int t, d; // tipo y direccion de caida\r
+} CLIMA_P;\r
+\r
+// Cantidad maxima de particulas climaticas\r
+#define MAX_CLIMA_P 300\r
+\r
+\r
+// Prototipos\r
+void init_clima(BITMAP *bmp, int c, int t, int d);\r
+void mover_clima(BITMAP *bmp);\r
+void dibuja_clima(BITMAP *bmp);\r
+\r
+#endif\r
diff --git a/include/combo.h b/include/combo.h
new file mode 100644 (file)
index 0000000..b2116fa
--- /dev/null
@@ -0,0 +1,28 @@
+// -------------------------------------------------------- \r
+// combo.c \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Esto contiene combos para agregar explosiones+particulas\r
+// y tocar los sonidos, musica, etc\r
+// -------------------------------------------------------- \r
+#ifndef COMBO_H\r
+#define COMBO_H\r
+\r
+#include "explos.h"\r
+\r
+/* prototipos */\r
+void poner_explosion_nave(int x, int y, int c, int r, int bmpp);\r
+void poner_muchas_particulas( int x,  int y,\r
+                              int dx, int dy,\r
+                              int vida,\r
+                              int col, int r, int t,\r
+                              BITMAP *spr,\r
+                              int cant );\r
+\r
+void pone_explo_pixel(EXPLOSION **explo,\r
+                      int x, int y,\r
+                      int r, int v,\r
+                      fixed v2);\r
+#endif\r
diff --git a/include/config.h b/include/config.h
new file mode 100644 (file)
index 0000000..a1f0d56
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef KRAPTOR_CONFIG_H\r
+#define KRAPTOR_CONFIG_H\r
+void cargar_configuracion();\r
+void salvar_configuracion();\r
+\r
+#endif\r
diff --git a/include/data.h b/include/data.h
new file mode 100644 (file)
index 0000000..946d47b
--- /dev/null
@@ -0,0 +1,23 @@
+// -------------------------------------------------------- \r
+// data.h \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Esto se encarga de cargar y poner en memoria\r
+// los datos leidos de disco.\r
+// -------------------------------------------------------- \r
+#ifndef DATA_H\r
+#define DATA_H\r
+\r
+\r
+/* Globales exportadas */\r
+extern DATAFILE *krapmain;\r
+extern DATAFILE *datmapa;\r
+extern DATAFILE *datmenu;\r
+\r
+/* Prototipos */\r
+void cargar_datos_principales();\r
+int cargar_nivel(int nivel, int solo_verificar);\r
+\r
+#endif\r
diff --git a/include/datafind.h b/include/datafind.h
new file mode 100644 (file)
index 0000000..4adc0fb
--- /dev/null
@@ -0,0 +1,21 @@
+// -------------------------------------------------------- \r
+// datafind.h\r
+// Funciones de busqueda avanzada de objetos dentro de un archivo DAT\r
+// -------------------------------------------------------- \r
+// Copyright (c) 2002, Kronoman\r
+// Escrito por Kronoman - Republica Argentina\r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Funcion para buscar un objeto en un datafile.\r
+// Busca primero el verdadero, si no existe, busca por aproximacion!!!\r
+// COOL!\r
+// --------------------------------------------------------\r
+\r
+#ifndef _KRONO_DATAFIND_H\r
+#define _KRONO_DATAFIND_H\r
+\r
+DATAFILE *fuzzy_find_datafile_object(AL_CONST DATAFILE *dat, AL_CONST char *objectname);\r
+DATAFILE *find_datafile_object_type(AL_CONST DATAFILE *dat, AL_CONST char *objectname, int type_required);\r
+DATAFILE *fuzzy_find_datafile_object_type(AL_CONST DATAFILE *dat, AL_CONST char *objectname, int type_required);\r
+\r
+#endif\r
diff --git a/include/enemigo.h b/include/enemigo.h
new file mode 100644 (file)
index 0000000..c262616
--- /dev/null
@@ -0,0 +1,151 @@
+// -------------------------------------------------------- \r
+// enemigo.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Todo lo relacionado con los enemigos\r
+// --------------------------------------------------------\r
+#ifndef ENEMIGO_H\r
+#define ENEMIGO_H\r
+\r
+#include "allegro.h"\r
+#include "ia.h"\r
+#include "pmask.h"\r
+\r
+/* friccion X,Y  */\r
+#define FRC_X_E  0.1\r
+#define FRC_Y_E  0.1\r
+\r
+/* velocidad maxima X, Y */\r
+#define MAX_VEL_E_X 15\r
+#define MAX_VEL_E_Y 15\r
+\r
+/* Cantidad maxima de tipos de enemigos/armas, con 100 es mas que suficiente */\r
+#define MAX_E_CLASS 100\r
+\r
+/* Esta bandera indica cuando el enemigo esta muerto\r
+   DEBE ser un valor NEGATIVO, ej: -150\r
+   Es para que agonize en llamas... :^P\r
+   Para los monstruos (boss) se multiplica x 2 <- DEBUG: NO IMPLEMENTADO! */\r
+#define ENE_MUERTO -200             \r
+\r
+/* Tipo de datos que contiene la definicion de armas de los enemigos */\r
+typedef struct ARMA_ENE {\r
+   BITMAP *spr;  /* sprite que representa el disparo */\r
+   struct PMASK *mask;  /* mascara de choque */\r
+   SAMPLE *snd[2]; /* 0 = sonido al dispararlo, 1 = sonido al impactar */\r
+\r
+   fixed vx, vy;  /* velocidad x, y */\r
+   int vida;      /* duracion del disparo, si es < 1, el tipo de arma no existe */\r
+   int punch;     /* `golpe` del arma */\r
+\r
+   int t; /* tipo de disparo:\r
+             0 = recto [sale del centro]\r
+             1 = direccion al azar\r
+             2 = abanico triple\r
+             3 = doble recto \r
+             4 = 1 direccionado hacia el jugador (sale hacia el jugador)\r
+             5 = 5 tiros direccionados (apunta al jugador, solo en X)\r
+             6 = cuadruple al azar\r
+             7 = 20 a 30 al azar (ideal para boss)\r
+             8 = 20 direccionados (ideal para boss)\r
+             9 = 20 a 30 en todas direcciones (ideal para boss)\r
+             10 = 5 a 30 en todas direcciones (ideal para boss)\r
+             11 = 4 a 8 en todas direcciones (para un enemigo)\r
+          */\r
+\r
+   /* Esto es referente a la estela de particulas que\r
+      el arma puede dejar, o no.\r
+      Cada parametro tiene 2 indices, el valor minimo y maximo que puede tomar\r
+      respectivamente (para variacion al azar)\r
+      Cabe aclarar que la dx, dy es un numero decimal multiplicado por 100 (100 = 0.01)\r
+      Si vida[0] <= 0, no deja ninguna estela */\r
+   int est_vida[2]; /* vida de la particula */\r
+   int est_cant[2]; /* cantidad de particulas x frame */\r
+   int est_color[3][2]; /* color, el primer indice indica RGB, y el 2ndo min-max */\r
+   int est_dx[2]; /* aceleracion x inicial (100 = 0.01) */\r
+   int est_dy[2]; /* aceleracion y inicial */\r
+   int est_tipo[2]; /* tipo(s) de particula */\r
+   int est_rad[2]; /* radio */\r
+   int est_transp; /* transparencia */\r
+} ARMA_ENE;\r
+\r
+/* Tipo de datos que contiene los tipos de enemigos */\r
+typedef struct ENEM_T {\r
+    int vida; /* vida inicial, si es < 1, la clase de enemigo no existe */\r
+\r
+    int peso; /* esto indica el 'peso' del enemigo, o sea, cuanta energia\r
+                 le quita al jugador en caso de colision */\r
+    \r
+    BITMAP *spr[4];         // sprites 0..3 = frames de animacion\r
+    BITMAP *spr_shadow[4]; // sombra (autogenerada al cargar data)\r
+    int spr_delay;          // delay de animacion en tics (30 = 1 segundo)\r
+\r
+    PMASK *mask[4];  /* mascara de colision de cada sprite*/\r
+\r
+    int dinero; /* dinero que vale matar a este enemigo */\r
+    \r
+    int premio_idx, premio_prob; /* indice de premio y probabilidad de darlo (%) */\r
+     \r
+    // Referente a la IA del enemigo - DEBUG, nuevo!\r
+    int ia_azar; // la IA del enemigo debe comenzar al azar? (es decir, comienza por bytecode 0 o por cualquiera?)\r
+    IA_NODE *ia_node; // nodo con bytecodes de la IA a ejecutar para esta clase de enemigo\r
+    int ia_boss; // es un BOSS? -1 = si\r
+} ENEM_T;\r
+\r
+/* Nodos que contienen los enemigos, en lista enlazada */\r
+typedef struct ENEMIGO {\r
+    fixed x,  y;     /* posicion */\r
+\r
+    int vida;      /* vida que le queda */\r
+\r
+    int ene_t; /* tipo de enemigo (se fija en la matriz ENEM_T) */\r
+\r
+    int spr_delay; // contador para la animacion\r
+    int spr_actual; // sprite actual de animacion\r
+    \r
+    int arma_actual; // lo uso como referencia para disparar\r
+    \r
+    // Referente a la IA\r
+    int bytecode_actual; // bytecode en ejecucion (indice [])\r
+    int bytecode_loop;   // contador para realizar los bytecodes con loop (parametro "loop")\r
+    IA_NODE *ia_node; // nodo de IA a ejecutar, se iguala a la clase de enemigo, es para evitar sintaxis complicadas... :)\r
+    IA_BYTECODE bytecode_exe; // copia del bytecode ejecutandose (para los loops)\r
+\r
+    /* puntero al siguiente */\r
+    struct ENEMIGO *next;\r
+} ENEMIGO;\r
+\r
+/* Nodo de disparo del enemigo, en lista enlazada */\r
+typedef struct DISP_ENE  {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int vida;        /* vida que le queda */\r
+\r
+    int arma; /* indice de la matriz ARMA_ENE que indica el tipo de disparo, etc */\r
+\r
+    /* puntero al siguiente */\r
+    struct DISP_ENE *next;\r
+} DISP_ENE;\r
+\r
+\r
+/* GLOBALES EXPORTADAS */\r
+extern ARMA_ENE arma_ene[MAX_E_CLASS]; \r
+extern ENEM_T enem_t[MAX_E_CLASS]; \r
+extern ENEMIGO *enemigo_1; \r
+extern DISP_ENE *disp_ene_1; \r
+extern int cant_enemigos_debug;\r
+\r
+/* Prototipos de funciones */\r
+void agregar_enemigo(int x, int y, int tipo );\r
+void IA_enemigo(ENEMIGO *ene);\r
+void mover_enemigos(int fy);\r
+void liberar_lista_enemigos();\r
+void dibujar_enemigos(BITMAP *bmp, int x, int y);\r
+\r
+void agregar_disparo_ene(ENEMIGO *ene);\r
+void mover_disparos_ene(int fy);\r
+void dibujar_disp_ene(BITMAP *bmp, int x, int y);\r
+void liberar_lista_disparos_ene();\r
+#endif\r
diff --git a/include/error.h b/include/error.h
new file mode 100644 (file)
index 0000000..24c6d1f
--- /dev/null
@@ -0,0 +1,14 @@
+// -------------------------------------------------------- \r
+// error.h \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Mensajes de error en modo texto.\r
+// --------------------------------------------------------\r
+#ifndef ERROR_H\r
+#define ERROR_H\r
+\r
+void levantar_error(char *msg);\r
+\r
+#endif\r
diff --git a/include/explos.h b/include/explos.h
new file mode 100644 (file)
index 0000000..58570cc
--- /dev/null
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------\r
+ explos.h\r
+ -------------------------------------------------------- \r
+ Copyright (c) 2002, Kronoman \r
+ En memoria de mi querido padre\r
+ Agosto - 2002\r
+ -------------------------------------------------------- \r
+ Engine de explosiones usando una lista enlazada\r
+ muy sencilla, sirve para muchas capas de explosiones\r
+ mediante el uso de punteros.\r
+ --------------------------------------------------------*/ \r
+\r
+#ifndef EXPLOS_H\r
+#define EXPLOS_H\r
+\r
+#include "allegro.h"\r
+\r
+\r
+/* estructura de datos  */\r
+typedef struct EXPLOSION {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int vida;      /* vida que le queda */\r
+    fixed r, dr;   /* radio y decremento de radio por ciclo */\r
+    BITMAP *spr;     /* sprite que lo representa */\r
+    int rot; /* rotacion del bitmap */\r
+\r
+    /* puntero al siguiente */\r
+    struct EXPLOSION *next;\r
+} EXPLOSION;\r
+\r
+\r
+\r
+extern int cant_explosion_debug; /* Innecesaria, para testear performance solamente */\r
+\r
+/* Cache de imagenes y sonidos, para el combo de explosion */\r
+extern BITMAP *explo_cache_bmp[3];\r
+extern SAMPLE *explo_cache_snd[3];\r
+\r
+/* punteros */\r
+extern EXPLOSION *ptr_explo_fondo;\r
+extern EXPLOSION *ptr_explo_arriba;\r
+\r
+\r
+/* prototipos */\r
+void       agrega_explosion( EXPLOSION **prt_1era,\r
+                             fixed x,  fixed y,\r
+                             fixed dx, fixed dy,\r
+                             int vida,\r
+                             fixed r, fixed dr,\r
+                             int rot,\r
+                             BITMAP *spr );\r
+void mover_explosiones(EXPLOSION **prt_1era);\r
+void dibujar_explosion(EXPLOSION *prt_1era, BITMAP *bmp, int x, int y);\r
+void liberar_lista_explosion(EXPLOSION **prt_1era);\r
+#endif\r
diff --git a/include/filedata.h b/include/filedata.h
new file mode 100644 (file)
index 0000000..ed9150f
--- /dev/null
@@ -0,0 +1,22 @@
+// -------------------------------------------------------- \r
+// filedata.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// This file is used as a wrapper for load_datafile\r
+// I use this for reach the datafile searching in common paths\r
+// Is specially useful for datafiles in Windows, because most \r
+// of the time Windows don't start the program in the executable path, \r
+// and the program is unable to find the datafile.\r
+// --------------------------------------------------------\r
+#ifndef FILEDATA_H\r
+#define FILEDATA_H\r
+\r
+char *where_is_the_filename(char *buffer, const char *filename);\r
+\r
+DATAFILE *krono_load_datafile(const char *filename);\r
+DATAFILE *krono_load_datafile_callback(const char *filename, void (*callback)(DATAFILE *d));\r
+DATAFILE *krono_load_datafile_object(const char *filename, const char *objectname);\r
+\r
+#endif\r
diff --git a/include/game.h b/include/game.h
new file mode 100644 (file)
index 0000000..d69d2b9
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef GAME_H\r
+#define GAME_H\r
+\r
+/* Prototipos */\r
+\r
+void comenzar_juego(int);\r
\r
\r
+#endif \r
diff --git a/include/global.h b/include/global.h
new file mode 100644 (file)
index 0000000..70ff401
--- /dev/null
@@ -0,0 +1,50 @@
+/* --------------------------------------------------------\r
+   global.h\r
+   Variables globales, y simbolo de debug\r
+ -------------------------------------------------------- */\r
+#ifndef GLOBAL_H\r
+#define GLOBAL_H\r
+\r
+#include <aldumb.h>\r
+\r
+/* Info de un nivel */\r
+typedef struct NIVEL_T {\r
+  char titulo[80]; /* titulo nivel */\r
+  char texto[300]; /* introduccion de texto al nivel */\r
+  char cine_in[1024]; /* cinematica de comienzo nivel */\r
+  char cine_out[1024]; /* cinematica de final nivel */\r
+  char level_dat[1024]; /* DAT del nivel */\r
+  int clima_c, clima_t, clima_d; // info de clima, cantidad, tipo, direccion\r
+  DUH *musica; /* musica del nivel */\r
+} NIVEL_T;\r
+\r
+/* Globales exportadas */\r
+extern char lenguaje[3]; // lenguaje a usar, ej : es = espa~ol\r
+extern int nivel_detalle;\r
+extern int detalle_automatico;\r
+extern int nivel_actual;\r
+extern int nivel_de_dificultad;\r
+extern int cheat_god_mode;\r
+extern NIVEL_T info_nivel;\r
+\r
+extern char game_over_cine[1024]; /* cinematica de game over */\r
+extern char game_intro_cine[1024]; /* cinematica de introduccion */\r
+extern int driver_de_sonido;\r
+extern int quiere_snd;\r
+extern int volumen_sonido;\r
+extern int quiere_musica;\r
+extern int quiere_videos;\r
+extern int volumen_musica;\r
+extern int salir_del_juego;\r
+extern int paso_de_nivel;\r
+extern PALETTE pal_game;\r
+extern COLOR_MAP tabla_transparencia;\r
+extern RGB_MAP tabla_RGB;\r
+extern int KRONO_QUIERE_DEBUG;\r
+extern FONT *font_backup;\r
+extern FONT *hud_font;\r
+extern int quiere_usar_joystick;\r
+extern int numero_de_joystick;\r
+extern int quiere_usar_mouse;\r
+extern int mouse_velocidad;\r
+#endif\r
diff --git a/include/guiprocs.h b/include/guiprocs.h
new file mode 100644 (file)
index 0000000..07dabfc
--- /dev/null
@@ -0,0 +1,69 @@
+/* guiprocs.c - Kraptor\r
+   Esto contiene dialogos tipo 3-D para el GUI de Allegro\r
+   Fueron tomados de Allegro Dialog Editor\r
+   y modificados para su uso en Kraptor\r
+*/\r
+\r
+/* ORIGINAL:\r
+ * Allegro DIALOG Editor\r
+ * by Julien Cugniere\r
+ *\r
+ * guiprocs.h : Some thin 3d-looking GUI procs\r
+ */\r
+\r
+#ifndef GUIPROCS_H\r
+#define GUIPROCS_H\r
+\r
+#include <allegro.h>\r
+\r
+#define F_IN       1\r
+#define F_LIGHT            2\r
+\r
+#ifdef __cplusplus\r
+   extern "C" {\r
+#endif\r
+\r
+/* colors */\r
+extern int gui_text_color;\r
+extern int gui_disabled_color;\r
+extern int gui_white_color;\r
+extern int gui_light_color;\r
+extern int gui_back_color;\r
+extern int gui_dark_color;\r
+extern int gui_black_color;\r
+void xset_gui_colors(void);\r
+\r
+/* helpers */\r
+void gui_rect(BITMAP *bmp, int x, int y, int w, int h, int flags);\r
+void dotted_rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int fg, int bg);\r
+\r
+/* menus */\r
+void xdraw_menu(int x, int y, int w, int h);\r
+void xdraw_menu_item(MENU *m, int x, int y, int w, int h, int bar, int sel);\r
+\r
+\r
+/* gui agregados por Kronoman: */\r
+int xslider_proc(int msg, DIALOG* d, int c); /* slider tipo X11 */\r
+int xbitmap_proc(int msg, DIALOG *d, int c); /* bitmap que se ajusta a w, h */\r
+\r
+/* gui procs */\r
+int xtext_proc     (int, DIALOG*, int);\r
+int xctext_proc    (int, DIALOG*, int);\r
+int xrtext_proc    (int, DIALOG*, int);\r
+int xlist_proc     (int, DIALOG*, int);\r
+int xtext_list_proc(int, DIALOG*, int);\r
+int xtextbox_proc  (int, DIALOG*, int);\r
+int xbox_proc      (int, DIALOG*, int);\r
+int xcolorbox_proc (int, DIALOG*, int);\r
+int xcheck_proc    (int, DIALOG*, int);\r
+int xbutton_proc   (int, DIALOG*, int);\r
+int xedit_proc     (int, DIALOG*, int);\r
+int xpalette_proc  (int, DIALOG*, int);\r
+\r
+void xset_gui_colors(void);\r
+\r
+#ifdef __cplusplus\r
+   }\r
+#endif\r
+\r
+#endif /* GUIPROCS_H */\r
diff --git a/include/guitrans.h b/include/guitrans.h
new file mode 100644 (file)
index 0000000..9301850
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+guitrans.h\r
+Por Kronoman\r
+Copyrigth (c) 2002, Kronoman\r
+En memoria de mi querido padre\r
+\r
+Este modulo se encarga de traducir estructuras\r
+de los GUI de Allegro al idioma actual.\r
+*/\r
+\r
+#ifndef GUITRANS_H\r
+#define GUITRANS_H\r
+\r
+#include <allegro.h>\r
+\r
+void traducir_DIALOG_dp(DIALOG *d);\r
+void traducir_MENU_text(MENU *d);\r
+\r
+#endif\r
diff --git a/include/humo.h b/include/humo.h
new file mode 100644 (file)
index 0000000..c1836ea
--- /dev/null
@@ -0,0 +1,55 @@
+/*-------------------------------------------------------\r
+ humo.h\r
+ -------------------------------------------------------- \r
+ Copyright (c) 2002, Kronoman \r
+ En memoria de mi querido padre\r
+ Enero - 2003\r
+ -------------------------------------------------------- \r
+ Engine de humo (para edificios en llamas)\r
+ usando una lista enlazada  muy sencilla\r
+ --------------------------------------------------------*/ \r
+\r
+#ifndef HUMO_H\r
+#define HUMO_H\r
+\r
+#include <allegro.h>\r
+\r
+extern BITMAP *humo_spr;\r
+\r
+/* estructura de datos que contiene el humo */\r
+typedef struct HUMO {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int vida;      /* vida que le queda a la particula */\r
+    int col; /* color */\r
+    fixed r, ri;   /* radio, incremental de tama~o de radio */\r
+\r
+    struct HUMO *next;\r
+} HUMO;\r
+\r
+/* estructura de datos para _emisores_ de humo */\r
+typedef struct EMISOR_HUMO {\r
+    fixed x,  y;     /* posicion  */\r
+    int vida; // vida (se 'apaga' a medida que vida se aproxima a 0)\r
+\r
+    struct EMISOR_HUMO *next;\r
+} EMISOR_HUMO;\r
+\r
+/* prototipos */\r
+\r
+// Emisores de humo\r
+\r
+EMISOR_HUMO *agrega_emisor_humo(fixed x, fixed y, int vida );\r
+void mover_emisor_humo(int x, int y, int w, int h);\r
+void liberar_emisores_humo();\r
+\r
+// Humo en si...\r
+HUMO *agrega_humo( fixed x,  fixed y,\r
+                   fixed dx, fixed dy,\r
+                   int vida,\r
+                   int col, fixed r, fixed ri);\r
+\r
+void mover_humo(int x, int y, int w, int h);\r
+void dibujar_humo(BITMAP *bmp, int x, int y);\r
+void liberar_humo();\r
+#endif\r
diff --git a/include/ia.h b/include/ia.h
new file mode 100644 (file)
index 0000000..bdcf1ff
--- /dev/null
@@ -0,0 +1,46 @@
+// --------------------------------------------------------
+// ia.h
+// -------------------------------------------------------- 
+// Copyright (c) Kronoman 
+// En memoria de mi querido padre 
+// -------------------------------------------------------- 
+// Sistema de inteligencia artificial utizando "ejecutables"
+// binarios contenidos en un DAT
+// --------------------------------------------------------
+
+#ifndef KRAPTOR_IA_H
+#define KRAPTOR_IA_H
+
+
+#include "allegro.h"
+
+
+// Estructura contenedora de una instruccion 
+typedef struct IA_BYTECODE
+{
+ int x1, y1, x2, y2; // coordenadas de movimiento
+ int weapon; // arma a disparar
+ int loop; // cantidad de veces a repetir
+
+} IA_BYTECODE;
+
+
+// Estructura de la lista enlazada contenedora
+// de todos los "programas" de IA precargados
+typedef struct IA_NODE
+{
+ IA_BYTECODE *code; // puntero a matriz asignada con malloc de todas las instrucciones de esta IA particular
+ int size; // cantidad de bytecodes contenidos en bytecode[]
+ char id[1024]; // identificacion usada para identificar esta secuencia en la IA (cadena ASCCIZ)
+
+ struct IA_NODE *next; // puntero al siguiente
+} IA_NODE;
+
+
+
+// Prototipos
+void hacer_chache_ia(const char *file);
+void liberar_lista_ia();
+IA_NODE *buscar_lista_ia(const char *id);
+
+#endif
diff --git a/include/joymnu.h b/include/joymnu.h
new file mode 100644 (file)
index 0000000..9739b01
--- /dev/null
@@ -0,0 +1,17 @@
+/*\r
+ --------------------------------------------------------\r
+ joymnu.h\r
+ Calibracion del joystick\r
+ --------------------------------------------------------\r
+*/\r
+#ifndef JOYMNU_H\r
+#define JOYMNU_H\r
+\r
+\r
+void probar_el_joystick(int nj);\r
+void dialog_joystick_calibrate(int nj);\r
+void joystick_configuration_menu();\r
+\r
+\r
+\r
+#endif\r
diff --git a/include/jugador.h b/include/jugador.h
new file mode 100644 (file)
index 0000000..02cfced
--- /dev/null
@@ -0,0 +1,172 @@
+// -------------------------------------------------------- \r
+// jugador.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Este modulo contiene todo lo relacionado con el jugador\r
+// Tal como movimiento, disparos, etc...\r
+// Exporta ademas unas globales utiles para verificar\r
+// colisiones con disparos enemigos y enemigos en si.\r
+// Tiene la estructura con las teclas de control del jugador\r
+// -------------------------------------------------------- \r
+#ifndef JUGADOR_H\r
+#define JUGADOR_H\r
+\r
+#include <allegro.h>\r
+#include "pmask.h"\r
+\r
+/* Aceleracion X, Y del jugador */\r
+#define VEL_X_J  2.5\r
+#define VEL_Y_J  2.5\r
+\r
+/* friccion X,Y jugador */\r
+#define FRC_X_J  0.02\r
+#define FRC_Y_J  0.02\r
+\r
+/* velocidad maxima X, Y del jugador */\r
+#define MAX_VEL_J_X 10.0\r
+#define MAX_VEL_J_Y 10.0\r
+\r
+/* Cantidad maxima de tipos de armas */\r
+#define MAX_ARM_CLASS 15\r
+\r
+/* Cantidad maxima de energia del jugador */\r
+#define MAX_ENERGIA 200\r
+\r
+/* Esta bandera indica cuando el jugador esta muerto\r
+   DEBE ser un valor NEGATIVO, ej: -300\r
+   Es para que agonize en llamas... :^P */\r
+#define JUG_MUERTO -300\r
+\r
+/* Tipo de datos que contiene la definicion de armas del jugador */\r
+typedef struct ARMA_JUG {\r
+   /* Referente al modo 'shopping' donde se compra el arma */\r
+\r
+   BITMAP *arma;  /* dibujo del arma en el shop */\r
+   char desc[2049]; /* descripcion del arma larga (texto ascii) */\r
+   char desc_short[21]; /* descripcion corta para el HUD */\r
+   int precio; /* precio del arma, si es <=0, indica que este tipo de arma NO existe */\r
+   int cant_ammo; /* cantidad de balas x compra */\r
+   int cant_ammo_max; /* cantidad maxima de balas */\r
+\r
+   /* Referente al disparo en si */\r
+\r
+   BITMAP *spr;  /* sprite que representa el disparo */\r
+   PMASK *mask;  /* mascara de choque */\r
+   SAMPLE *snd[2]; /* 0 = sonido al dispararlo, 1 = sonido al impactar */\r
+\r
+   fixed vx, vy; /* velocidad x, y */\r
+   int vida;   /* duracion del disparo */\r
+   int punch;  /* `golpe` del arma */\r
+   int firerate; /* ratio de disparo, referido a lastshoot */\r
+\r
+   int t; /* tipo de disparo: esto se cambia reprogramando la seccion correspondiente en jugador.c\r
+             0 = recto [sale del centro]\r
+             1 = direccion al azar\r
+             2 = abanico triple, vx especifica la apertura del abanico (default = 5)\r
+             3 = doble recto [salen del centro (+/-) 50% del ancho nave]\r
+             4 = 1 del centro, 1 al azar por disparo (very cool!)\r
+             5 = 1 del centro, 1 de la izq, 1 de la derecha (tipo misile pod, incluye una variacion del 10% al azar en la velocidad en y, para efecto misile pod)\r
+             6 = flak, 6 al azar (ca~on de flak!), y 2 rectos de las alas\r
+          */\r
+\r
+   /* Esto es referente a la estela de particulas que\r
+      el arma puede dejar, o no.\r
+      Cada parametro tiene 2 indices, el valor minimo y maximo que puede tomar\r
+      respectivamente (para variacion al azar)\r
+      Cabe aclarar que la dx, dy es un numero decimal multiplicado por 100 (100 = 0.01)\r
+      Si vida[0] <= 0, no deja ninguna estela */\r
+   int est_vida[2]; /* vida de la particula */\r
+   int est_cant[2]; /* cantidad de particulas x frame */\r
+   int est_color[3][2]; /* color, el primer indice indica RGB, y el 2ndo min-max */\r
+   int est_dx[2]; /* aceleracion x inicial */\r
+   int est_dy[2]; /* aceleracion y inicial */\r
+   int est_tipo[2]; /* tipo(s) de particula */\r
+   int est_rad[2]; /* radio */\r
+   int est_transp; /* transparencia */\r
+} ARMA_JUG;\r
+\r
+/* Tipo de datos que contiene el jugador */\r
+typedef struct JUGADOR {\r
+    fixed x,  y;     /* posicion */\r
+    fixed dx, dy;    /* direccion */\r
+\r
+    int vida;      /* vida que le queda, energia  */\r
+\r
+    int dinero;    /* dinero (puntos) que tiene */\r
+\r
+    BITMAP *spr[6];  /* sprites que lo representan, 0 = izq, 1 = normal, 2 = der,\r
+                        3,4,5 son las sombras de los sprites\r
+                        (se generan al cargar los datos) */\r
+\r
+    PMASK *mask;  /* mascara de colision, para spr[1] */\r
+\r
+    int arma[MAX_ARM_CLASS]; /* armamentos que tiene (<= 0 no tiene el arma, > 0 posee el arma, cantidad de balas que tiene) */\r
+\r
+    int arma_actual; /* arma seleccionada */\r
+\r
+    int lastshoot; /* contador  para temporizar intervalo entre disparos */\r
+\r
+    int bombas; /* cantidad de bombas que le quedan */\r
+\r
+    /* Reparacion de la nave, para el shopping */\r
+    int reparar_cantidad; /* cantidad que repara cada unidad */\r
+    int reparar_precio;   /* precio por unidad */\r
+    char reparar_desc[2048]; /* descripcion */\r
+    BITMAP *reparar_bmp; /* bitmap de reparacion */\r
+\r
+    /* Bombas de la nave, para el shopping */\r
+    int bomba_cantidad;\r
+    int bomba_precio;\r
+    char bomba_desc[2048];\r
+    BITMAP *bomba_bmp;\r
+    int max_bombas;\r
+\r
+    /* dinero y bombas iniciales */\r
+    int init_money;\r
+    int init_bombas;\r
+\r
+} JUGADOR;\r
+\r
+/* Nodo de disparo del jugador, en lista enlazada */\r
+typedef struct DISP_JUG  {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int vida;        /* vida que le queda */\r
+\r
+    int arma; /* indice de la matriz ARMA_JUG que indica el tipo de disparo, etc */\r
+\r
+    /* puntero al siguiente */\r
+    struct DISP_JUG *next;\r
+} DISP_JUG;\r
+\r
+/* Teclas de juego, corresponden al tipo key[KEY_SPACE], etc */\r
+typedef struct TECLADO_JUG {\r
+  /* arriba, abajo, derecha, izquierda, disparar, cambiar arma, bomba especial */\r
+  int arr, abj, der, izq, sht, wpn, bmb;\r
+} TECLADO_JUG;\r
+\r
+\r
+/* GLOBALES EXPORTADAS */\r
+extern ARMA_JUG arma_tipo[MAX_ARM_CLASS];  /* tipos de armas */\r
+extern JUGADOR jugador;         /* jugador */\r
+extern DISP_JUG *disp_jug_1;    /* puntero al 1er disparo del jugador */\r
+extern TECLADO_JUG teclado_jug; /* teclado del jugador */\r
+\r
+/* Prototipos de funciones */\r
+void dibujar_tablero(BITMAP *bmp);\r
+void set_teclado_default();\r
+void reset_total_jugador();\r
+void reset_parcial_jugador();\r
+void jugador_proxima_arma();\r
+void interpreta_teclado();\r
+void dibujar_nave_jugador(BITMAP *bmp, int x, int y);\r
+void mover_jugador(int fy);\r
+\r
+void agregar_disparo_jug();\r
+void mover_disparos_jug(int fy);\r
+void dibujar_disp_jug(BITMAP *bmp, int x, int y);\r
+void liberar_lista_disparos_jug();\r
+\r
+#endif\r
diff --git a/include/kfbuffer.h b/include/kfbuffer.h
new file mode 100644 (file)
index 0000000..3fa29f0
--- /dev/null
@@ -0,0 +1,34 @@
+/*\r
+  Todo el sistema trabaja renderizando en un bitmap\r
+  de un tama~o fijo, el cual luego se estira al tama~o de pantalla\r
+  Este archivo contiene el buffer, y los parametros de su tama~o\r
+  porque varias rutinas los necesitan, especialmente\r
+  la de descartar enemigos cuando salen por la parte inferior de pantalla\r
+\r
+   -------------------------------------------------------- \r
+   Copyright (c) Kronoman \r
+   En memoria de mi querido padre \r
+   -------------------------------------------------------- \r
+  */\r
+#ifndef KFBUFFER_H\r
+#define KFBUFFER_H\r
+\r
+#include <allegro.h>\r
+\r
+/* ancho y alto de renderizado del area de juego */\r
+#define ANCHO_FB    600\r
+#define ALTO_FB     480\r
+\r
+/* ancho y alto area del buffer total */\r
+#define ANCHO_RFB   640\r
+#define ALTO_RFB    480\r
+\r
+\r
+/* globales exportadas */\r
+extern BITMAP *kfbufferbmp;\r
+\r
+/* prototipos */\r
+void enviar_kfbuffer2screen();\r
+void interlazar_kfbuffer(int r, int g, int b);\r
+\r
+#endif\r
diff --git a/include/krstring.h b/include/krstring.h
new file mode 100644 (file)
index 0000000..dcaaa97
--- /dev/null
@@ -0,0 +1,17 @@
+// -------------------------------------------------------- \r
+// krstring.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) 2002, Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Funciones para strings ASCIIZ auxiliares\r
+// -------------------------------------------------------- \r
+// ASCIIZ string function\r
+// --------------------------------------------------------\r
+\r
+#ifndef KRSTRING_H\r
+#define KRSTRING_H\r
+\r
+char *krtrim(char *dest, const char *orig);\r
+\r
+#endif\r
diff --git a/include/main.h b/include/main.h
new file mode 100644 (file)
index 0000000..443f880
--- /dev/null
@@ -0,0 +1,16 @@
+// -------------------------------------------------------- \r
+// Kraptor - Call of the freedom\r
+// --------------------------------------------------------\r
+// main.h \r
+// -------------------------------------------------------- \r
+// Copyright (c) 2002, Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+\r
+#ifndef MAIN_H\r
+#define MAIN_H\r
+\r
+// Version del engine\r
+#define KRAPTOR_VERSION_STR "1.0.2"\r
+\r
+#endif\r
diff --git a/include/mapa.h b/include/mapa.h
new file mode 100644 (file)
index 0000000..4498394
--- /dev/null
@@ -0,0 +1,39 @@
+// -------------------------------------------------------- \r
+// mapa.h \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Esto contiene todo lo referente al mapa en si\r
+// -------------------------------------------------------- \r
+#ifndef MAPA_H\r
+#define MAPA_H\r
+\r
+/* Tama¤o del fondo en pixeles */\r
+#define W_FONDO  600\r
+#define H_FONDO  4000\r
+\r
+/* Grilla WxH en pixels */\r
+#define W_GR 40\r
+#define H_GR 40\r
+\r
+/* Cantidad de cuadritos de la grilla [ancho y alto] */\r
+#define GRILLA_W  (W_FONDO / W_GR)\r
+#define GRILLA_H  (H_FONDO / H_GR)\r
+\r
+/* Globales exportadas */\r
+extern long mapa_g[GRILLA_W][GRILLA_H];\r
+extern long enem_g[GRILLA_W][GRILLA_H];\r
+extern int scroll_mapa;\r
+extern int scroll_mapa_speed;\r
+extern BITMAP *mapa_fondo;\r
+extern COLOR_MAP tabla_quemado;\r
+extern BITMAP *burn_cache_bmp[3];\r
+\r
+/* Prototipos */\r
+void scan_nivel_1era_vez();\r
+void scan_nuevos_enemigos(int y);\r
+void quemar_area(BITMAP *bmp, int xp, int yp, int rad1, int rad2);\r
+int explotar_fondo(int x, int y, int punch);\r
+void crear_mapa_quemazon(AL_CONST PALETTE pal, int x, int y, RGB *rgb);\r
+#endif\r
diff --git a/include/menu.h b/include/menu.h
new file mode 100644 (file)
index 0000000..42e748e
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ --------------------------------------------------------\r
+ menu.h\r
+ --------------------------------------------------------\r
+ Sistema de menu de Kraptor (al estilo de Unre*l)\r
+ --------------------------------------------------------\r
+*/\r
+#ifndef K_MENU_H\r
+#define K_MENU_H\r
+\r
+#include <allegro.h>\r
+\r
+/* Seleccion de menu */\r
+#define MNU_S_NEW_GAME    1\r
+#define MNU_S_LOAD_GAME   2\r
+#define MNU_S_QUIT_GAME   3\r
+\r
+#define MNU_S_CFG_SND     4\r
+#define MNU_S_CFG_CTRL    5\r
+#define MNU_S_CFG_DETAIL  6\r
+#define MNU_S_CFG_VIDEO   7\r
+\r
+#define MNU_S_CFG_SPANISH 8\r
+#define MNU_S_CFG_ENGLISH 9\r
+\r
+#define MNU_S_VER_HLP     10\r
+#define MNU_S_VER_ABOUT   11\r
+\r
+/* bitmap de fondo, y paleta de colores y musica */\r
+extern BITMAP *bmp_menu_main;\r
+extern PALETTE pal_menu_main;\r
+\r
+\r
+extern char *texto_ayuda_juego; /* puntero a la ayuda del juego */\r
+extern char *texto_acerca_de_juego; /* acerca de... */\r
+extern BITMAP *acerca_de_bmp; /* bitmap acerca de... */\r
+\r
+/* Prototipos */\r
+void realizar_menu_principal(); /* entrada para el menu principal */\r
+int modificar_sonido_mnu(void); /* menu para volumen de sonido/musica */\r
+int mod_teclado_jugar(void); /* menu para modificar el teclado */\r
+int mod_detalle_mnu(void); /* menu para modificar los detalles */\r
+int menu_configuracion_al_vuelo(void); /* menu de sonido, teclado, detalle */\r
+int ayuda_proggy_mnu(); /* ayuda */\r
+\r
+#endif\r
diff --git a/include/partic.h b/include/partic.h
new file mode 100644 (file)
index 0000000..4bcda36
--- /dev/null
@@ -0,0 +1,65 @@
+/*-------------------------------------------------------\r
+ partic.h\r
+ -------------------------------------------------------- \r
+ Copyright (c) 2002, Kronoman \r
+ En memoria de mi querido padre\r
+ Agosto - 2002\r
+ -------------------------------------------------------- \r
+ Engine de particulas usando una lista enlazada\r
+ muy sencilla\r
+ --------------------------------------------------------*/ \r
+\r
+#ifndef PARTIC_H\r
+#define PARTIC_H\r
+\r
+#include "allegro.h"\r
+\r
+/* NOTA:\r
+   el tipo de particula 't' puede ser:\r
+   1 = circulo\r
+   2 = cuadrado\r
+   3 = linea\r
+   o si spr != NULL, dibuja el bitmap rotando al azar (como que salto un pedazo\r
+   */\r
+\r
+/* estructura de datos que contiene la particula */\r
+typedef struct PARTICULA {\r
+    fixed x,  y;     /* posicion  */\r
+    fixed dx, dy;    /* direccion */\r
+    int vida;      /* vida que le queda a la particula */\r
+    fixed r, rg; /* radio y valor de crecimiento del radio 'rg' */\r
+    int col, t;   /* color  y tipo de grafico que la representa */\r
+    int transp; /* la particula es transparente? -1 = si, 0 = no [solo en alto detalle ] */\r
+    BITMAP *spr;     /* sprite que lo representa, o NULL si es una figura geometrica */\r
+    fixed rot; /* rotacion del bitmap */\r
+\r
+    /* puntero a la particula siguiente */\r
+    struct PARTICULA *next;\r
+} PARTICULA;\r
+\r
+\r
+/* prototipos */\r
+\r
+PARTICULA *agrega_particula( fixed x,  fixed y,\r
+                             fixed dx, fixed dy,\r
+                             int vida,\r
+                             int col, int r, int t,\r
+                             int transp, fixed rg,\r
+                             BITMAP *spr );\r
+\r
+void mover_particulas(int x, int y, int w, int h);\r
+\r
+void dibujar_particulas(BITMAP *bmp, int x, int y);\r
+\r
+void liberar_lista_particulas();\r
+\r
+\r
+\r
+/* DEBUG - estas variables son especificas a Kraptor */\r
+\r
+/* Cache de bmps representando particulas para 'reventar' naves */\r
+extern BITMAP *particula_cache_bmp[3];\r
+\r
+extern int cant_particulas_debug;\r
+\r
+#endif\r
diff --git a/include/pmask.h b/include/pmask.h
new file mode 100644 (file)
index 0000000..7455a39
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef pmask_H\r
+#define pmask_H\r
+\r
+/*\r
+This is the Pixel MASK library, which does pixel-perfect collisions using\r
+bit masks.\r
+\r
+There are several configuration options here, hope they aren't too\r
+confusing.\r
+*/\r
+\r
+#define PMASK_VERSION          1\r
+\r
+#define USE_ALLEGRO\r
+//#define USE_SDL\r
+\r
+#ifdef USE_ALLEGRO\r
+struct BITMAP;\r
+#endif\r
+#ifdef USE_SDL\r
+struct SDL_Surface;\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+#define pmask_USE_INLINE\r
+extern "C" {\r
+#endif\r
+\r
+//This is the bounding box collision detection macro.\r
+//It is a general purpose macro. Pass it the coordinates of one rectangle and the width and\r
+//height of it, then pass the coordinates of a second rectangle and the width and height of\r
+//it. It will return 0 if theres not collision or 1 if there is a collision between the\r
+//rectangles (the rectangles overlap).\r
+//This macro works looking for out of range values, if some value is out of\r
+//range it returns 0, if all the values are in range it returns true.\r
+#define check_bb_collision_general(x1,y1,w1,h1,x2,y2,w2,h2) (!( ((x1)>=(x2)+(w2)) || ((x2)>=(x1)+(w1)) || ((y1)>=(y2)+(h2)) || ((y2)>=(y1)+(h1)) ))\r
+#define check_bb_collision(mask1,mask2,x1,y1,x2,y2) check_bb_collision_general(x1,y1,mask1->w,mask1->h,x2,y2,mask2->w,mask2->h)\r
+\r
+//MASK_WORD_TYPE and MASK_WORD_BITBITS can be changed for your platform\r
+\r
+//MASK_WORD_TYPE should be the largest fast integer type available\r
+#define MASK_WORD_TYPE unsigned long int\r
+\r
+//MASK_WORD_BITBITS should be the log base 2\r
+//of the number of bits in MASK_WORD_TYPE\r
+//e.g. 4 for 16-bit ints, 5 for 32-bit ints, 6 for 64-bit ints\r
+#define MASK_WORD_BITBITS 5\r
+\r
+\r
+//if SINGLE_MEMORY_BLOCK is defined\r
+//then each mask will be allocated as\r
+//only a single memory block.  \r
+//this means that masks will (in theory) \r
+//be ever-so-slightly faster and more memory efficient\r
+//however, if in single memory block mode\r
+//then the masks are variable-sized\r
+//so you can not use an array of them\r
+//#define MASK_SINGLE_MEMORY_BLOCK\r
+\r
+typedef struct PMASK\r
+{\r
+       short int w;//width\r
+       short int h;//height\r
+#ifdef MASK_SINGLE_MEMORY_BLOCK\r
+       MASK_WORD_TYPE mask[1];//mask data (single memory block)\r
+#else\r
+       MASK_WORD_TYPE *mask;//mask data (pointer at second memory block)\r
+#endif\r
+} PMASK;\r
+\r
+void install_pmask(); //sets up library\r
+\r
+int check_pmask_collision(struct PMASK *mask1, struct PMASK *mask2, int x1, int y1, int x2, int y2); //checks for collision (0 = no collision, 1 = collision)\r
+\r
+int get_pmask_pixel(struct PMASK *mask, int x, int y) ; //returns 0 if mask is clear at those coordinates, 1 if not clear\r
+void set_pmask_pixel(struct PMASK *mask, int x, int y, int value) ;//makes mask clear at those coordinates if value is zero, others makes mask not-clear at those coordinates\r
+\r
+void init_pmask        (struct PMASK *mask, int w, int h); //initializes a PMASK\r
+void pmask_load_pixels (struct PMASK *mask, void *pixels, int pitch, int bytes_per_pixel, int trans_color);//loads a pmask with pixel data from memory\r
+void pmask_load_func   (struct PMASK *mask, int x, int y, void *surface, int trans_color, int (*func)(void*,int,int));//loads a pmask with pixel data from a function\r
+void deinit_pmask(PMASK *mask);//de-initializes a pmask\r
+\r
+PMASK *create_pmask  (int w, int h);//creates a new pmask and initializes it\r
+void destroy_pmask(struct PMASK *mask);//destroys a pmask created by create_pmask\r
+\r
+#if defined USE_ALLEGRO\r
+void init_allegro_pmask(struct PMASK *mask, struct BITMAP *sprite);\r
+PMASK *create_allegro_pmask(struct BITMAP *sprite);\r
+#endif\r
+\r
+#if defined USE_SDL\r
+void init_sdl_pmask(struct PMASK *mask, struct SDL_Surface *sprite, int trans_color);\r
+PMASK *create_sdl_pmask(struct SDL_Surface *sprite, int trans_color);\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#define MASK_WORD_SIZE sizeof(MASK_WORD_TYPE)\r
+#define MASK_WORD_BITS (MASK_WORD_SIZE*8)\r
+\r
+#if defined pmask_USE_INLINED\r
+inline int _get_pmask_pixel(struct PMASK *mask, int x, int y) {\r
+       //no bounds checking\r
+       return 1 & (mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] >> (x & (MASK_WORD_BITS-1)));\r
+}\r
+inline void _set_pmask_pixel(struct PMASK *mask, int x, int y, int value) {\r
+       //no bounds checking\r
+       if (value) {\r
+               mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] |= 1 << (x & (MASK_WORD_BITS-1));\r
+       } else {\r
+               mask->mask[(mask->h * (x >> MASK_WORD_BITBITS)) + y] &=~(1 << (x & (MASK_WORD_BITS-1)));\r
+       }\r
+}\r
+#else\r
+#define _get_pmask_pixel get_pmask_pixel\r
+#define _set_pmask_pixel set_pmask_pixel\r
+#endif\r
+\r
+\r
+#endif          /* ifndef PPCOL_H */\r
+\r
diff --git a/include/premio.h b/include/premio.h
new file mode 100644 (file)
index 0000000..122eac0
--- /dev/null
@@ -0,0 +1,43 @@
+/*-------------------------------------------------------\r
+ premio.h\r
+ -------------------------------------------------------- \r
+ Copyright (c) 2002, Kronoman \r
+ En memoria de mi querido padre\r
+ Enero - 2003\r
+ -------------------------------------------------------- */\r
+\r
+#ifndef PREMIO_H\r
+#define PREMIO_H\r
+\r
+#include <allegro.h>\r
+\r
+/* cantidad maxima de clases de premios */\r
+#define MAX_PREMIO_CLASS 20\r
+\r
+/* contenedor de las clases de premios */\r
+typedef struct PREMIO_CLASS {\r
+   int premiar;\r
+   int cantidad;\r
+   int vida;\r
+   BITMAP *sprite;\r
+   SAMPLE *sonido;\r
+} PREMIO_CLASS;\r
+\r
+/* estructura de datos que contiene cada premio individual; */\r
+typedef struct PREMIO {\r
+    fixed x,  y, r;     /* posicion  y rotacion (efecto cool)*/\r
+    fixed dx, dy, dr;    /* direccion */\r
+    int vida;        /* vida que le queda */\r
+    int clase;       /* indice de la clase de premio */\r
+    struct PREMIO *next;\r
+} PREMIO;\r
+\r
+/* globales exportadas */\r
+extern PREMIO_CLASS premio_class[MAX_PREMIO_CLASS];\r
+\r
+/* prototipos */\r
+PREMIO *agrega_premio(int premio, fixed x, fixed y);\r
+void mover_premio(int x, int y, int w, int h);\r
+void liberar_premio();\r
+void dibujar_premio(BITMAP *bmp, int x, int y);\r
+#endif\r
diff --git a/include/rvideo.h b/include/rvideo.h
new file mode 100644 (file)
index 0000000..bf0b70e
--- /dev/null
@@ -0,0 +1,31 @@
+// ----------------------------------------------------------------\r
+// rvideo.h\r
+// ----------------------------------------------------------------\r
+// Produce un video de un juego a archivos bmp sueltos\r
+// Ideal para generar un video promocional de un juego\r
+// Por Kronoman\r
+// Copyrigth Enero 2003, Kronoman\r
+// En memoria de mi querido padre\r
+// ----------------------------------------------------------------\r
+// Para que esto funcione, debe ser llamado en cada actualizacion\r
+// logica del juego, de esa manera mantiene los fps constantes\r
+// ----------------------------------------------------------------\r
+\r
+#ifndef RVIDEO_H\r
+#define RVIDEO_H\r
+#include <allegro.h>\r
+\r
+// Globales de configuracion\r
+extern char rvideo_filen[1024];\r
+extern int rvideo_cadafsave;\r
+extern int rvideo_step;\r
+extern int rvideo_f_actual;\r
+extern int rvideo_is_recording;\r
+extern int rvideo_resize;\r
+extern int rvideo_w, rvideo_h;\r
+\r
+// Prototipos\r
+void init_rvideo();\r
+void rvideo_record(BITMAP *bmp, RGB *pal);\r
+#endif\r
+\r
diff --git a/include/savedlg.h b/include/savedlg.h
new file mode 100644 (file)
index 0000000..c7a6252
--- /dev/null
@@ -0,0 +1,38 @@
+// ------------------------------------\r
+// savedlg.c\r
+// ------------------------------------\r
+// Sistema de salva / carga de juego\r
+// Por Kronoman\r
+// En memoria de mi querido padre\r
+// Copyright (c) 2002, Kronoman\r
+// ------------------------------------\r
+\r
+#ifndef SAVEDLG_H\r
+#define SAVEDLG_H\r
+\r
+#include <allegro.h>\r
+#include "jugador.h"\r
+#include "global.h"\r
+\r
+// cantidad de slots de savegame (el dialogo tiene soporte para 7)\r
+#define SAVE_GAME_SLOTS 7\r
+\r
+// Estructura de salvado del juego a disco\r
+// No puedo salvar directamente el JUGADOR, porque tiene punteros y boludeces que no sirven\r
+typedef struct SAVE_GAME_ST\r
+{\r
+     char desc[41]; // descripcion del savegame\r
+     int es_valido; // el savegame es valido? 0 = NO, != 0 = si\r
+     int vida;      /* vida que le queda, energia  */\r
+     int dinero;    /* dinero (puntos) que tiene */\r
+     int arma[MAX_ARM_CLASS]; /* armamentos que tiene (<= 0 no tiene el arma, > 0 posee el arma, cantidad de balas que tiene) */\r
+     int arma_actual; /* arma seleccionada */\r
+     int bombas; /* cantidad de bombas que le quedan */\r
+     int nivel_actual; // nivel que va jugando\r
+     int nivel_de_dificultad; // nivel de dificultad\r
+} SAVE_GAME_ST;\r
+\r
+// Prototipos\r
+void salvar_juego_menu();\r
+int cargar_juego_menu();\r
+#endif\r
diff --git a/include/shopping.h b/include/shopping.h
new file mode 100644 (file)
index 0000000..e08a615
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+ --------------------------------------------------------\r
+ shopping.h\r
+ --------------------------------------------------------\r
+ Sistema de shopping de Kraptor \r
+\r
+ NOTAS: TODOS LOS TEXTOS DEL MENU ESTAN EN *INGLES*\r
+ PARA PODER TRADUCIRLOS AUTOMATICAMENTE\r
+ CON EL ENGINE DE TRADUCCION.\r
+ USAR MENUES Y DIALOGOS *LOCALES* PARA QUE AL\r
+ ENTRAR/SALIR DE SCOPE, (CADA VEZ QUE SE LLAMA LA FUNCION)\r
+ SE TRADUZCAN AUTOMATICAMENTE AL LENGUAJE ORIGINAL.\r
+ --------------------------------------------------------\r
+*/\r
+\r
+#ifndef SHOPPING_H\r
+#define SHOPPING_H\r
+\r
+extern BITMAP *shop_bmp;\r
+\r
+void do_shopping_principal();\r
+\r
+\r
+\r
+#endif\r
diff --git a/include/sombras.h b/include/sombras.h
new file mode 100644 (file)
index 0000000..50255e4
--- /dev/null
@@ -0,0 +1,17 @@
+// -------------------------------------------------------- \r
+// sombras.h\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Genera las sombras del juego\r
+// Bastante simple. :^P\r
+// -------------------------------------------------------- \r
+#ifndef SOMBRAS_H\r
+#define SOMBRAS_H\r
+\r
+/* prototipos */\r
+void hacer_sombra(BITMAP *origen, BITMAP *destino);\r
+void colocar_sombra(BITMAP *bmp, BITMAP *sombra, int px, int py);\r
+\r
+#endif\r
diff --git a/include/sonido.h b/include/sonido.h
new file mode 100644 (file)
index 0000000..9920da8
--- /dev/null
@@ -0,0 +1,29 @@
+// -------------------------------------------------------- \r
+// sonido.h \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Modulo de sonido y musica\r
+// -------------------------------------------------------- \r
+#ifndef SONIDO_H\r
+#define SONIDO_H\r
+#include <aldumb.h> /* DUMB: libreria de sonido */\r
+\r
+\r
+// Prototipos\r
+\r
+// Sonido\r
+void tocar_sonido_paneado(int x, SAMPLE *spl, int vol, int freq);\r
+void tocar_sonido(SAMPLE *spl, int vol, int pan, int freq);\r
+\r
+\r
+// Musica\r
+void musica_stop();\r
+int musica_play(DUH *duh);\r
+void ejecutar_poll_musica();\r
+void reajustar_volumen_musica();\r
+void pausar_musica();\r
+void continuar_musica();\r
+\r
+#endif\r
diff --git a/include/wordwrap.h b/include/wordwrap.h
new file mode 100644 (file)
index 0000000..9055c88
--- /dev/null
@@ -0,0 +1,20 @@
+/*--------------------------------------------------------\r
+ wordwrap.h\r
+ --------------------------------------------------------\r
+ Copyright (c) Kronoman\r
+ En memoria de mi querido padre\r
+ --------------------------------------------------------\r
+ Funciones para escribir texto con 'word-wrap'\r
+ --------------------------------------------------------*/\r
+#ifndef KRONO_WORDWRAP_H\r
+#define KRONO_WORDWRAP_H\r
+\r
+#include "allegro.h"\r
+\r
+/* Prototipos */\r
+int  imprimir_wordwrap(BITMAP *bmp,\r
+                       const FONT *f,\r
+                       int x, int y, int color, int w,\r
+                       const char *text);\r
+\r
+#endif\r
diff --git a/install b/install
new file mode 100644 (file)
index 0000000..d9a3bc0
--- /dev/null
+++ b/install
@@ -0,0 +1,38 @@
+Kraptor
+-------
+
+Instructions for compilation of the engine from source code.
+
+Before compiling, check that:
+(*) You have all compiler tools installed (gcc,make,etc)
+(*) You have Allegro library properly installed (http://alleg.sf.net/)
+(*) You have DUMB Music library properly installed (http://dumb.sf.net/)
+
+
+The engine was tested and can be compiled with GNU GCC (Linux), MinGW (Windows), DJGPP (DOS)
+It may be able to compile with other compilers too.
+
+-- DJGPP users:
+
+Type:
+
+       fix.bat djgpp
+       fix.bat test
+       make
+
+-- Mingw users:
+
+Type:
+
+       fix.bat mingw
+       fix.bat test
+       make
+
+
+-- Linux users:
+
+Type:
+
+       ./fix.sh linux
+       ./fix.sh test
+       make
\ No newline at end of file
diff --git a/license b/license
new file mode 100644 (file)
index 0000000..54f0bb7
--- /dev/null
+++ b/license
@@ -0,0 +1,16 @@
+Kraptor Game Engine
+Kraptor Game Datafiles
+\r
+Copyright (c) 2002, 2003, Kronoman\r
+In loving memory of my father.\r
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+\r
+Distributed under The MIT License\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
diff --git a/makefile b/makefile
new file mode 100644 (file)
index 0000000..ed32c56
--- /dev/null
+++ b/makefile
@@ -0,0 +1,109 @@
+# ------------------------------------------------------------------------
+# Generic makefile
+# By Kronoman
+# Thanks to Schwarzung for the help on making the original makefile system.
+# ------------------------------------------------------------------------
+
+# This has the target platform defined, this is modified by fix.bat or fix.sh
+include target.os
+
+# Suggested by GNU Coding Stardards
+SHELL = /bin/sh
+
+# ===============================================
+# Target binary name without extension
+BINARY = kraptor
+
+# Source directory
+SRCDIR = src
+
+# Include directory
+INCDIR = include
+
+# Source code suffix (.c, .cpp, etc)
+SRCSUF = .c
+
+# Simple source code test file (must be in same dir as makefile for now) :(
+# The extension will be taken from SRCSUF, don't put it!
+TESTFILE = test
+# ===============================================
+
+
+# -----------------------------
+# -- Platform specific stuff --
+# -----------------------------
+
+# ------------------
+# DJGPP target
+# ------------------
+ifeq ($(TARGET),DJGPP)
+
+PLATFORMDIR=djgpp
+
+# compiler to invoque
+GCC = gcc
+# GPP = gxx
+
+# Binary file suffix
+BINSUF = .exe
+# object suffix
+OBJSUF = .o
+
+# If you need extra link options (like more librarys, add to LFLAGS var)
+LFLAGS = -s -laldmb -ldumb -lalleg
+
+# Compiler flags
+CFLAGS = -I$(INCDIR) -Wall -O3
+endif
+
+# ------------------
+# MingW32
+# ------------------
+ifeq ($(TARGET),MINGW32)
+
+PLATFORMDIR=mingw32
+
+GCC = gcc
+# GPP = g++
+
+# Binary file suffix
+BINSUF = _w32.exe
+OBJSUF = .o
+
+# If you need extra link options (like more librarys, add to LFLAGS var)
+LFLAGS = -s -mwindows -laldmb -ldumb -lalleg
+
+# Compiler flags
+CFLAGS = -I$(INCDIR) -Wall -O3
+endif
+
+# ------------------
+# Linux
+# ------------------
+ifeq ($(TARGET),LINUX)
+
+PLATFORMDIR=linux
+
+GCC = gcc
+# GPP = g++
+
+# Binary file suffix
+BINSUF = _linux.bin
+OBJSUF = .o
+
+# If you need extra link options (like more librarys, add to LFLAGS var)
+LFLAGS = -laldmb -ldumb `allegro-config --libs`
+
+# Compiler flags
+CFLAGS = -I$(INCDIR) -Wall -O3
+endif
+
+# ---------------------------------
+# -- Platform non-specific stuff --
+# ---------------------------------
+
+OBJDIR = obj/$(PLATFORMDIR)
+BINDIR = bin
+
+# -- The rules for build are in this file --
+include makefile.all
diff --git a/makefile.all b/makefile.all
new file mode 100644 (file)
index 0000000..8bd7180
--- /dev/null
@@ -0,0 +1,46 @@
+# Makefile generic - Rules to build
+# Fixed at last! :), thanks to Schwarzung
+
+TEMP = $(wildcard $(SRCDIR)/*$(SRCSUF))
+FILES = $(if $(TEMP), $(TEMP), $(error No source code found!))
+OBJS = $(addprefix $(OBJDIR)/,$(addsuffix $(OBJSUF), $(basename $(notdir $(FILES) ) ) ) )
+
+# main target, all project
+.PHONY: all
+all: $(BINDIR)/$(BINARY)$(BINSUF)
+
+$(BINDIR)/$(BINARY)$(BINSUF) : $(OBJS) 
+       $(GCC) $^ -o $@ $(LFLAGS)
+       @echo The $(BINDIR)/$(BINARY)$(BINSUF) is ready!
+
+$(OBJDIR)/%$(OBJSUF) : $(SRCDIR)/%$(SRCSUF)
+       $(GCC) $(CFLAGS) -c $< -o $@
+
+.PHONY: clean and also clean the test
+clean: cleantest
+       rm -rf $(BINDIR)/$(BINARY)$(BINSUF) $(OBJS)
+
+# Strip symbols and compress with upx packer (http://upx.sf.net/)
+.PHONY: upx
+upx:
+       strip --strip-all $(BINDIR)/$(BINARY)$(BINSUF)
+       upx --best $(BINDIR)/$(BINARY)$(BINSUF)
+
+# Install - Please add here your custom installation functions
+.PHONY: install
+install:
+       @echo Sorry, the install feature is not done yet.
+
+# Test if the system can compile - PLEASE MODIFY THIS TO SUIT YOUR NEEDS!
+# Compile the program
+# The test.run is to check if make run or not in DJGPP enviroment (ugly hack)
+# seems that DOS don't set errorlevel if fails to execute a program
+.PHONY: test
+test:
+       $(GCC) $(TESTFILE)$(SRCSUF) -o $(TESTFILE)$(BINSUF) $(CFLAGS) $(LFLAGS)
+       echo "don't edit me" > test.run
+
+# Cleans the test
+.PHONY: cleantest
+cleantest: 
+       rm -rf $(TESTFILE)$(BINSUF) test.run
\ No newline at end of file
diff --git a/obj/djgpp/remove.me b/obj/djgpp/remove.me
new file mode 100644 (file)
index 0000000..99e8d22
--- /dev/null
@@ -0,0 +1 @@
+This file can be safely removed
\ No newline at end of file
diff --git a/obj/linux/remove.me b/obj/linux/remove.me
new file mode 100644 (file)
index 0000000..99e8d22
--- /dev/null
@@ -0,0 +1 @@
+This file can be safely removed
\ No newline at end of file
diff --git a/obj/mingw32/remove.me b/obj/mingw32/remove.me
new file mode 100644 (file)
index 0000000..99e8d22
--- /dev/null
@@ -0,0 +1 @@
+This file can be safely removed
\ No newline at end of file
diff --git a/readme b/readme
new file mode 100644 (file)
index 0000000..d83e3bb
--- /dev/null
+++ b/readme
@@ -0,0 +1,140 @@
+Kraptor
+-------
+
+---------------------------------------------------------------------
+
+Official Web Site
+
+http://kraptor.sf.net/
+
+---------------------------------------------------------------------
+
+Copyright 2002, 2003, 2004,  Kronoman
+Released under the MIT license
+In loving memory of my father.
+Made in Argentina
+
+---------------------------------------------------------------------
+
+After years of oppression, the slaved people of the world have raised against their masters.
+You, has a mercenary pilot, has been contacted by the popular rebellion to fight against the forces of oppression.
+In the morning, you jump into your cockpit and start up the engines.
+Its time to get airborne and start the attack.
+Get ready to scramble the scum hired by the masters.
+Murder for freedom is the only way, you're a man on a mission, don't defraud us...
+
+---------------------------------------------------------------------
+
+What is this?
+
+Kraptor is a classic shoot 'em up scroller game, where you must fight against tons of bad dudes.
+The game offers high speed action, with massive destruction and lots of fun.
+Kraptor features a powerful engine for 2D shooter scroller games.
+Massive destruction, powerful weapons, all that you always wanted in this kind of games!
+It is also multi-platform (DOS, Win32, Linux and more!)
+
+---------------------------------------------------------------------
+
+Command line options
+
+-safe              Will run the game in 'safe' mode (will try to start it no matter what)
+-windowscreen      Will run the game in a window (not available in DOS version)
+-fullscreen        Will run the game in fullscreen
+-autoscreen        Will try to autodetect video card and screen mode
+-nosound           Disables the sound
+-320x200           Video mode 320x200
+-320x240           Video mode 320x240
+-640x480           Video mode 640x480
+-800x600           Video mode 800x600
+-1024x768          Video mode 1024x768
+
+---------------------------------------------------------------------
+
+Features
+
+Some of the main features of the engine and the game itself:
+
+# FULL SOURCE CODE AVAILABLE FREE (Under MIT license)
+# Works on many platforms, including DOS, Windows and Linux!
+# Supports all resolutions, like 320x200, 640x480, 1024x768, etc.; even those bizarre ones, like 160x120, 320x400, etc.
+# Uses stereo positional sound (you hear the ships flying around you)
+# Has a incredible particle system, that let all sorts of particle effects in the explosions, fire on the ground, the ships going down in flames,and the weapons can let a trail of smoke, beams, etc
+# Has a dynamic fire, smoke and explosions system based on layers and on-fly rendering, that let show a massive destruction effect on the air and ground.
+# Has a dynamic enviroment sub-engine to render rain, snow, etc.
+# The ships explodes into pieces, and the builds on the ground blows up in a chain-explosion effect.
+# Enemys of any size, and custom IAs and weapons.
+# All kind of animated bad dudes, from tiny ones to big bad bosses.
+# All the flying objects cast shadows over the background, with perspective correction.
+# Support for animations and cinematic, with sound and subtitles.
+# A on-fly translation system with UNICODE and UTF-8 support, that can translate on the fly all the GUIs to other language.
+# Multiple weapons for player and enemies.
+# Has original music sound-track.
+# You can lower/raise the detail level, in low detail, the game runs good even on a 486 DX2!
+# Original story, with cool movies.
+# Realistic huge hi-res backgrounds levels.
+# Original high quality stereo sounds and music
+# Support for Spanish and English translation on-fly
+# 'Black market' shop to buy new weapons, upgrade ship, etc.
+# GUI driven interface like the one used in Unre*l.
+# You can Save / Load your game
+
+---------------------------------------------------------------------
+
+Thanks to:
+
+# All the people that made open source and free software. Without them, the world would be yet more scary.
+# The guys of Allegro, DUMB, Pixelate and Allegro.cc. Cool job!
+# F3N1X Team, thanks for the Linux CDs!
+# Mother, thanks for the Linux T-Shirt and the new Linux CDs! Ha! Of course, thanks for live!
+# Father, thanks for so many things... specially my first 386. What cool machine it was!
+# Iron Chelo "The Bodyguard"
+# DJ Ñanga
+# GAC
+# J. Monytor (no man, we need more acceleration to put that tea cup in orbit of mars)
+# El Super 666, cool heavy metal CDs... thanks!
+# El Mago Eddy
+# Error Catastrofico
+# Gabriel, thanks for lots of good heavy MP3s
+# B. Gates, hope that you recover soon from your lobotomy...
+# G. W. Bush, call me when you be more sober...
+
+---------------------------------------------------------------------
+
+Software used in development
+
+The following software was used in the development of Kraptor
+For links to download them, check the "Links" section.
+
+GNU GCC, DJGPP and MinGW32 where the main compilers used in Kraptor
+Allegro is the game programming library used.
+DUMB is the music engine.
+Linux Mandrake 8.2 and 9.0 where used as the main OS for development.
+The GIMP and ASE where used to do the 2D graphic artwork and FLI cinematic.
+Blender, Povray, Giram, Ayam and Aqsis where used to do the 3D artwork.
+PMASK is the collision library made by "orz".
+Bluefish and Mozilla where used to make this web page.
+Bochs, a portable x86 Emulator, really useful for testing in other OS without reboot.
+Audacity, a cool free audio editor!
+DLG, a dialog editor by Julien Cugniere (thanks for the GUI routines too!)
+UPX was used to compress the executable in certaing platforms.
+Many other software that I don't remember right now was used also. Thanks to them too.
+Hardware used in development
+The main development machine was a P3 450 MHz (over-clocked at 500 MHz), 320MB RAM, 2 x 40GB HD, CD, CD-RW, optical pen, scanner, web-cam, etc, with Linux Mandrake 9.0, Free-DOS and Windoze 98
+One AMD Atlhon XP 1700 with 512MB RAM, NVIDIA GForce2 MX 400, dual 80 GB HD was used to the rendering and advanced graphic and sound edition.
+Also was used a 486DX2 66MHz, 8MB RAM, 540MB HD, 5 1/4 floppy, with DR-DOS for performance testing purposes.
+A Palm m125 was used to take ideas and notes 'on-fly' in the streets.
+
+---------------------------------------------------------------------
+
+Released under the MIT license
+The MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub-license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+---------------------------------------------------------------------
+
+
diff --git a/src/azar.c b/src/azar.c
new file mode 100644 (file)
index 0000000..3ea1774
--- /dev/null
@@ -0,0 +1,36 @@
+// azar.c\r
+// Macro para numeros al azar\r
+// Elige un numero entre min y max\r
+// Tomado de la internet y mejorado por Kronoman\r
+\r
+#ifndef AZAR_C\r
+#define AZAR_C\r
+\r
+#include <stdlib.h>\r
+\r
+#include "azar.h"\r
+/*\r
+Esta funcion explota si min - max da 0, sorry, pero la cambie...\r
+*/\r
+// #define rand_ex( min, max )   ( (rand() % (max - min)) + min )\r
+\r
+/* esta funcion es ligeramente mas lenta, pero NO explota... */\r
+int rand_ex(int min, int max)\r
+{\r
+int tmp;\r
+\r
+     if (min - max == 0) return 0 + min; /* evito division por cero */\r
+\r
+     /* correcion nueva, medio lenta, pero para corregir algunos bugs raros\r
+        intercambio min y max si estan al reves */\r
+     if (min > max)\r
+     {\r
+      tmp = min;\r
+      min = max;\r
+      max = tmp;\r
+     }\r
+\r
+     return ( rand() % (max - min) ) + min;\r
+}\r
+\r
+#endif\r
diff --git a/src/bomba.c b/src/bomba.c
new file mode 100644 (file)
index 0000000..1e790bb
--- /dev/null
@@ -0,0 +1,76 @@
+// -------------------------------------------------------- \r
+// bomba.c\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Este modulo contiene todo lo relacionado con las bombas\r
+// del jugador...\r
+// -------------------------------------------------------- \r
+#ifndef BOMBA_C\r
+#define BOMBA_C\r
+\r
+#include <allegro.h>\r
+#include "bomba.h"\r
+#include "mapa.h"\r
+#include "sonido.h"\r
+#include "explos.h"\r
+#include "kfbuffer.h"\r
+#include "azar.h"\r
+\r
+/* globales exportadas, setearlas al lanzar una bomba, ver jugador.c */\r
+int bomba_esta_activa = FALSE; // esta la bomba funcionando en este momento?\r
+int bomba_detonacion = 0; // tiempo de detonacion (30 = 1 segundo explotando)\r
+SAMPLE *bomba_sonido = NULL; // sonido de detonacion\r
+\r
+/* mueve la bomba */\r
+void mover_bomba()\r
+{\r
+int i;\r
+if (!bomba_esta_activa) return;\r
+\r
+// sonido de explosiones al azar...\r
+if (rand()%100 < 25)\r
+            tocar_sonido_paneado(rand()%ANCHO_FB,\r
+                                 explo_cache_snd[rand()%3],\r
+                                 rand_ex(128, 200),\r
+                                 rand_ex(800, 1300));\r
+\r
+bomba_detonacion--;\r
+if (bomba_detonacion <= 0)\r
+   {\r
+    /* sonido estruendoso de explosion */\r
+    if (rand()%100 < 95)\r
+       for (i = 0; i < rand()%3+1; i++)\r
+            tocar_sonido_paneado(rand()%ANCHO_FB,\r
+                                 explo_cache_snd[rand()%3],\r
+                                 rand_ex(196, 256),\r
+                                 rand_ex(800, 1300));\r
+\r
+    bomba_esta_activa = FALSE;\r
+    bomba_detonacion = 0;\r
+   }\r
+}\r
+\r
+/* dibuja la explosion de la bomba, actualmente, todo blanco... horrible! */\r
+void dibujar_bomba(BITMAP *bmp)\r
+{\r
+if (!bomba_esta_activa) return;\r
+\r
+clear_to_color(bmp, makecol(255,255,255) );\r
+\r
+}\r
+\r
+/* produce una detonacion total del piso del juego,\r
+   pasarle en x el 'scroll_mapa'  */\r
+void detonar_totalmente_el_piso(int y)\r
+{\r
+int x1,y1;\r
+/* DEBUG: esto detona con retroactividad, es decir todo el mapa hacia atras! */\r
+for (y1 = y / H_GR; y1 < GRILLA_H; y1++)\r
+    for (x1 = 0; x1 < GRILLA_W; x1++)\r
+           explotar_fondo(x1, y1, rand()%100+100);\r
+\r
+}\r
+\r
+#endif\r
diff --git a/src/captura.c b/src/captura.c
new file mode 100644 (file)
index 0000000..71b7622
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+ --------------------------------------------------------\r
+ captura.c \r
+ -------------------------------------------------------- \r
+ Copyright (c) Kronoman \r
+ En memoria de mi querido padre \r
+ -------------------------------------------------------- \r
+ Funcion para tomar una captura de pantalla\r
+ Automaticamente la salva en archivoxxx.bmp, etc\r
+ -------------------------------------------------------- \r
+*/\r
+#ifndef CAPTURAR_C\r
+#define CAPTURAR_C\r
+\r
+#include <stdio.h>\r
+#include "allegro.h"\r
+\r
+/* Esta funcion captura la pantalla, usando el prefijo para el archivo\r
+   Salva un PCX de 8 bits de color.\r
+*/\r
+void capturar_la_pantalla(char *prefijo) \r
+{\r
+      char arch[1024];\r
+      int i = 0;\r
+\r
+      BITMAP *bmp;\r
+      PALETTE pal;\r
+\r
+      /* Buscar un archivo entre 0 y 4095 para salvar el archivo\r
+         Usa numeracion hexadecimal para que entren mas archivos */\r
+      do {\r
+       sprintf(arch, "%s%x.bmp", prefijo, i);\r
+       i++;\r
+      } while (exists(arch) && i < 4096);\r
+\r
+\r
+      get_palette(pal);\r
+      bmp = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H);\r
+      save_bitmap(arch, bmp, pal);\r
+      destroy_bitmap(bmp);\r
+}\r
+\r
+#endif\r
diff --git a/src/cinema.c b/src/cinema.c
new file mode 100644 (file)
index 0000000..d50bc77
--- /dev/null
@@ -0,0 +1,749 @@
+/*\r
+ --------------------------------------------------------\r
+ cinema.c\r
+ --------------------------------------------------------\r
+ Copyright (c) Septiembre 2002, Kronoman\r
+ En memoria de mi querido padre\r
+ --------------------------------------------------------\r
+ Engine de cinematicas mediante scripts y datafiles\r
+ Nota: quiere_videos afecta si esto funciona o no. :D\r
+ -------------------------------------------------------- */\r
+\r
+#ifndef CINEMA_C\r
+#define CINEMA_C\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include "allegro.h"\r
+\r
+#include "krstring.h"\r
+#include "kfbuffer.h" /* dibuja en el buffer, debe estar funcionando OK... */\r
+#include "cinema.h"\r
+#include "error.h"\r
+#include "wordwrap.h"\r
+#include "datafind.h"\r
+#include "global.h"\r
+#include "filedata.h"\r
+\r
+/* Listado de comandos disponibles al script principal */\r
+CMD_SCRIPT_TYPE cmd_list[] =\r
+{\r
+ { "cls",          cmd_cls,              3    },\r
+ { "fade_out",     cmd_fade_out,         1    },\r
+ { "fade_out_color", cmd_fade_out_color, 4    },\r
+ { "rect",         cmd_rect,             7    },\r
+ { "rectfill",     cmd_rectfill,         7    },\r
+ { "line",         cmd_line,             7    },\r
+ { "locate",       cmd_locate,           3    },\r
+ { "text_color",   cmd_text_color,       3    },\r
+ { "text_back",    cmd_text_back ,       3    },\r
+ { "text_font",    cmd_text_font,        0    },\r
+ { "echo",         cmd_echo,             0    },\r
+ { "echo_centre_x",cmd_echo_centre_x,    0    },\r
+ { "echo_centre_xy", cmd_echo_centre_xy, 0    },\r
+ { "rest",         cmd_rest,             1    },\r
+ { "set_palette",  cmd_set_palette,      1    },\r
+ { "set_palette_default", cmd_set_palette_default, 0 },\r
+ { "blit",         cmd_blit,             3    },\r
+ { "sprite",       cmd_sprite,           3    },\r
+ { "stretch_blit", cmd_stretch_blit,     5    },\r
+ { "stretch_blit",  cmd_stretch_blit,    5    },\r
+ { "play_sample",   cmd_play_sample,     4    },\r
+ { "play_fli",      cmd_play_fli,        7    },\r
+ { "clear_fli_back",cmd_clear_fli_back,  3    },\r
+ { "keyboard_cancel_fli", cmd_keyboard_cancel_fli, 1 },\r
+ { NULL, NULL, 0 } /* fin de listado */\r
+};\r
+\r
+/* Globales, usadas en la interpretacion */\r
+static DATAFILE *el_archivo = NULL; /* el archivo DAT a usar... */\r
+\r
+static char linea_actual[MAX_LINEA]; /* linea de comando actual, completa */\r
+static int n_linea_actual; /* numero de linea actual */\r
+\r
+static char comando_actual[80+1]; /* comando actual leido */\r
+static char s2nd_param[MAX_LINEA]; /* todo lo que quedo sacando el comando principal */\r
+\r
+static char str_param[MAX_PARAMS][256]; /* parametros parseados a char, maximo 256 letras c/u */\r
+static int c_str_param = 0; /* cantidad de parametros str leidos */\r
+\r
+static int int_param[MAX_PARAMS]; /* parametros parseados a int */\r
+static int c_int_param = 0; /* cantidad de parametros int leidos */\r
+\r
+static int teclado_cancela_fli = 0; /* puedo cancelar un FLI con teclado? */\r
+static int cls_el_fli[3] = { 0, 0, 0 }; /* color de limpieza antes de 'tocar' un FLI */\r
+\r
+/* Referente a la salida de texto... */\r
+static int x_echo = 0, y_echo = 0, w_echo = ANCHO_RFB; /* pos cursor */\r
+static int echo_text_color, echo_text_back; /* colores */\r
+static FONT *echo_font; /* font a usar */\r
+\r
+// DEBUG: El mapa RGB fue desactivado porque causaba problemas al usar multiples paletas... sorry gordi..\r
+// static RGB_MAP rgb_table_cine; /* mapa RGB para la paleta actual */\r
+\r
+static PALETTE pal_cine; /* paleta actual */\r
+\r
+/* ------------------------------------------------- */\r
+/* Globales usadas por las funciones de los comandos */\r
+\r
+/* DEBUG: agregar aqui las globales extra necesarias, como 'static' */\r
+\r
+/* --------------------- Funciones de los comandos --------------- */\r
+\r
+/* Esta funcion limpia la pantalla al color especificado */\r
+int cmd_cls() {\r
+ clear_to_color(kfbufferbmp, makecol(int_param[0], int_param[1], int_param[2]));\r
+ enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+ return 0; /* todo OK */\r
+}\r
+\r
+/* Dibuja un rectangulo vacio */\r
+int cmd_rect()\r
+{\r
+ rect(kfbufferbmp,\r
+      int_param[0], int_param[1],\r
+      int_param[2], int_param[3],\r
+      makecol(int_param[4], int_param[5], int_param[6]));\r
+ enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+ return 0;\r
+}\r
+\r
+/* Dibuja un rectangulo lleno */\r
+int cmd_rectfill()\r
+{\r
+ rectfill(kfbufferbmp,\r
+          int_param[0], int_param[1],\r
+          int_param[2], int_param[3],\r
+          makecol(int_param[4], int_param[5], int_param[6]));\r
+ enviar_kfbuffer2screen(); /* refrescar pantalla */         \r
+ return 0;\r
+}\r
+\r
+/* Traza lineas */\r
+int cmd_line()\r
+{\r
+     line(kfbufferbmp,\r
+          int_param[0], int_param[1],\r
+          int_param[2], int_param[3],\r
+          makecol(int_param[4], int_param[5], int_param[6]));\r
+ enviar_kfbuffer2screen(); /* refrescar pantalla */         \r
+ return 0;\r
+}\r
+\r
+/* Esta funcion es un wrapper de fade_out de Allegro */\r
+int cmd_fade_out() {\r
+ fade_out(int_param[0]);\r
+ get_palette(pal_cine); // actualizar la paleta actual\r
+ return 0;\r
+}\r
+\r
+/* Esta funcion es un wrapper de fade_out de Allegro\r
+ pero ajustado para que haga un fade out al color especificado\r
+\r
+fade_out_color [r] [g] [b] [velocidad]\r
+   Realiza una transicion al color [r] [g] [b]\r
+   [velocidad] 1..64 (lento-rapido)\r
+ */\r
+int cmd_fade_out_color() {\r
+\r
+ RGB col; // color formato (nota: esto va de 0..63, NO  de 0..255!!)\r
+ PALETTE pal_dest; // paleta destino\r
+ PALETTE pal_orig; // paleta origen\r
+ int i = 0;\r
+\r
+ // divido por 4 para que quede en rango 0..63\r
+ // ademas, ajusto con MIN y MAX en rango...\r
+ col.r = MAX(0, MIN(63, int_param[0] / 4));\r
+ col.g = MAX(0, MIN(63, int_param[1] / 4));\r
+ col.b = MAX(0, MIN(63, int_param[2] / 4));\r
+\r
+ for (i = 0; i < 256; i++)\r
+ {\r
+  pal_dest[i].r = col.r;\r
+  pal_dest[i].g = col.g;\r
+  pal_dest[i].b = col.b;\r
+ }\r
+\r
+ get_palette(pal_orig);\r
+\r
+ fade_from(pal_orig, pal_dest, int_param[3]);\r
+\r
+ get_palette(pal_cine); // actualizar la paleta actual\r
\r
+ return 0;\r
+}\r
+\r
+/* Posiciona el cursor de texto */\r
+int cmd_locate()\r
+{\r
+ x_echo = int_param[0];\r
+ y_echo = int_param[1];\r
+ w_echo = int_param[2];\r
+ return 0;\r
+}\r
+\r
+/* Color de texto para echo */\r
+int cmd_text_color()\r
+{\r
+ echo_text_color = makecol(int_param[0], int_param[1], int_param[2]);\r
+ return 0;\r
+}\r
+\r
+/* Color de fondo para el texto */\r
+int cmd_text_back()\r
+{\r
+ if (int_param[0] < 0 || int_param[1] < 0 || int_param[2] < 0)\r
+     echo_text_back = -1;\r
+ else\r
+     echo_text_back = makecol(int_param[0], int_param[1],int_param[2]);\r
+     \r
+ text_mode(echo_text_back);\r
+ return 0;\r
+}\r
+\r
+/* Cambiar la fuente del texto */\r
+int cmd_text_font()\r
+{\r
+ DATAFILE *p = NULL;\r
+ if (c_str_param > 0)\r
+ {\r
+     p = find_datafile_object_type(el_archivo, str_param[0], DAT_FONT);\r
+     if (p == NULL) return -1; /* fallo... */\r
+     echo_font = p->dat;\r
+ }\r
+ else\r
+ {\r
+  echo_font = font;\r
+ }\r
+\r
+return 0;\r
+}\r
+\r
+/* Salida a pantalla de texto\r
+   escribe y avanza la linea... (como el print de Qbasic) */\r
+int cmd_echo()\r
+{\r
+text_mode(echo_text_back);\r
+\r
+y_echo = imprimir_wordwrap(kfbufferbmp,\r
+                           echo_font,\r
+                           x_echo, y_echo, echo_text_color, w_echo,\r
+                           s2nd_param);\r
+\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+/* Salida de texto centrado en x */\r
+int cmd_echo_centre_x()\r
+{\r
+int x;\r
+text_mode(echo_text_back);\r
+x = text_length(echo_font, s2nd_param);\r
+x = (kfbufferbmp->w - x)/2;\r
+\r
+//textprintf(kfbufferbmp, echo_font, x, y_echo, echo_text_color, "%s", s2nd_param);\r
+//y_echo += text_height(echo_font);\r
+\r
+// usa word-wrap...\r
+y_echo = imprimir_wordwrap(kfbufferbmp,\r
+                           echo_font,\r
+                           x, y_echo, echo_text_color, w_echo,\r
+                           s2nd_param);\r
+\r
+\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+/* Salida de texto centrado en x,y */\r
+int cmd_echo_centre_xy()\r
+{\r
+int x;\r
+text_mode(echo_text_back);\r
+x = text_length(echo_font, s2nd_param);\r
+x = (kfbufferbmp->w - x)/2;\r
+y_echo = (kfbufferbmp->h - text_height(echo_font)) / 2;\r
+\r
+//textprintf(kfbufferbmp, echo_font, x, y_echo, echo_text_color, "%s", s2nd_param);\r
+//y_echo += text_height(echo_font);\r
+\r
+// usa word-wrap...\r
+y_echo = imprimir_wordwrap(kfbufferbmp,\r
+                           echo_font,\r
+                           x, y_echo, echo_text_color, w_echo,\r
+                           s2nd_param);\r
+\r
+\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+\r
+/* Pausa sincronica, puede ser cancelada con el teclado */\r
+int cmd_rest()\r
+{\r
+long int f = 0; /* para el for */\r
+\r
+   if (int_param[0] <= 0 )\r
+         {\r
+          clear_keybuf();\r
+          readkey(); // esperar por una tecla\r
+          clear_keybuf();\r
+         }\r
+       else\r
+        {\r
+        clear_keybuf();\r
+        f = 0; \r
+        // el cancelar solo funciona si la pausa es > 10 ms\r
+        if (int_param[0] > 10)\r
+        {\r
+                while ((f < int_param[0]) && (!keypressed()))\r
+                {\r
+                 rest (10);\r
+                 f += 10;\r
+                }\r
+        }\r
+        else\r
+        {\r
+                rest((long)int_param[0]);\r
+        }\r
+        clear_keybuf();\r
+        }\r
+return 0;\r
+}\r
+\r
+/* Setea la paleta y la tabla RGB */\r
+int cmd_set_palette()\r
+{\r
+DATAFILE *p;\r
+p = find_datafile_object_type(el_archivo, str_param[0], DAT_PALETTE);\r
+if (p == NULL) return -1; /* fallo... */\r
+\r
+memcpy(pal_cine, p->dat, sizeof(PALETTE));\r
+\r
+// create_rgb_table(&rgb_table_cine, pal_cine, NULL);\r
+// rgb_map = &rgb_table_cine; // DEBUG - mapa RGB desactivado\r
+\r
+vsync(); /* evita flicker */\r
+set_palette(pal_cine);\r
+\r
+return 0;\r
+}\r
+\r
+/* Setea la paleta VGA DEFAULT y la tabla RGB */\r
+int cmd_set_palette_default()\r
+{\r
+memcpy(pal_cine, default_palette, sizeof(PALETTE));\r
+\r
+vsync(); /* evita flicker */\r
+set_palette(pal_cine);\r
+\r
+return 0;\r
+}\r
+\r
+/* blitea un bitmap a pantalla */\r
+int cmd_blit()\r
+{\r
+DATAFILE *p;\r
+p = find_datafile_object_type(el_archivo, str_param[2], DAT_BITMAP);\r
+if (p == NULL) return -1; /* fallo... */\r
+\r
+blit((BITMAP *)p->dat, kfbufferbmp, 0, 0, int_param[0], int_param[1], ((BITMAP *)p->dat)->w, ((BITMAP *)p->dat)->h);\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+/* sprite a pantalla */\r
+int cmd_sprite()\r
+{\r
+DATAFILE *p;\r
+p = find_datafile_object_type(el_archivo, str_param[2], DAT_BITMAP);\r
+if (p == NULL) return -1; /* fallo... */\r
+\r
+draw_sprite(kfbufferbmp, (BITMAP *)p->dat, int_param[0], int_param[1]);\r
+\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+/* estira un bitmap */\r
+int cmd_stretch_blit()\r
+{\r
+DATAFILE *p;\r
+p = find_datafile_object_type(el_archivo, str_param[4], DAT_BITMAP);\r
+if (p == NULL) return -1; /* fallo... */\r
+\r
+stretch_blit((BITMAP *)p->dat, kfbufferbmp, 0, 0, ((BITMAP *)p->dat)->w, ((BITMAP *)p->dat)->h, int_param[0], int_param[1], int_param[2], int_param[3]);\r
+enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+return 0;\r
+}\r
+\r
+/* ejecuta un sonido (sample) */\r
+int cmd_play_sample()\r
+{\r
+DATAFILE *p;\r
+p = find_datafile_object_type(el_archivo, str_param[0], DAT_SAMPLE);\r
+if (p == NULL) return -1; /* fallo... */\r
+\r
+play_sample((SAMPLE *)p->dat, int_param[1], int_param[2], int_param[3], 0);\r
+\r
+return 0;\r
+}\r
+\r
+/*\r
+ejecuta un archivo FLI (animacion\r
+esta funcion es complicada porque utiliza sonidos y subtitulos... :^P\r
+NOTA: si no logra abrir el fli, NO falla\r
+      esto es para permitir facilmente hacer demostraciones con videos 'recortados'\r
+*/\r
+int cmd_play_fli()\r
+{\r
+int ret = 0; int loop = 0;\r
+DATAFILE *p = NULL; /* buscador */\r
+DATAFILE *fli_p = NULL; /* FLI */\r
+int ctxt = 0; /* encontro el [script_fli]? */\r
+DATAFILE *psample = NULL; /* SAMPLE a ejecutar */\r
+char tmpstr[1024]; /* string temporal de uso vario */\r
+tmpstr[0] = '\0';\r
+\r
+// play_fli [x] [y] [w] [h] [loop] [objeto_fli] [script_fli]\r
+//           0   1   2   3    4      5           6\r
+   /* buscar FLI a ejecutar */\r
+   p = find_datafile_object_type(el_archivo, str_param[5], DAT_FLI);\r
+   if (p == NULL) return 0; /* fallo... no hay FLI..., lo ignoro */\r
+\r
+   fli_p = p; /* tomar el puto FLI */\r
+\r
+   /* buscar la configuracion [script_fli], si no existe, se ignorara */\r
+   p = find_datafile_object(el_archivo, str_param[6]);\r
+   if (p != NULL)\r
+      {\r
+      ctxt = TRUE; /* lo encontro */\r
+      set_config_data((char *)p->dat, p->size);\r
+      }\r
+   else\r
+      ctxt = 0; /* no lo encontro... */\r
+\r
+   /* mostramos el fli de la manera complicada...\r
+      ver fli.c de Allegro para mas info */\r
+clear_keybuf(); /* limpio el buffer de teclado */\r
+\r
+rgb_map = NULL; /* anulo el mapa RGB */\r
+\r
+/* ir realizando el looping adecuado */\r
+for (loop = int_param[4]; loop > 0; loop--)\r
+  {\r
+     if (open_memory_fli(fli_p->dat) != FLI_OK) return -1; /* no era un FLI... */\r
+\r
+      ret = next_fli_frame(0);\r
+      if (ret == FLI_ERROR) return -1;\r
+\r
+      while (ret == FLI_OK)\r
+      {\r
+          /* actualiza la paleta */\r
+         if (fli_pal_dirty_from <= fli_pal_dirty_to)\r
+                      set_palette_range(fli_palette,\r
+                                        fli_pal_dirty_from,\r
+                                        fli_pal_dirty_to, TRUE);\r
+\r
+          /* actualiza la pantalla */\r
+          if (fli_bmp_dirty_from <= fli_bmp_dirty_to)\r
+          {\r
+            /* debo limpiar el buffer? */\r
+            if (cls_el_fli[0] > -1 && cls_el_fli[1] > -1 && cls_el_fli[2] > -1)\r
+                  clear_to_color(kfbufferbmp, makecol(cls_el_fli[0], cls_el_fli[1], cls_el_fli[2]));\r
+\r
+            stretch_blit(fli_bitmap, kfbufferbmp,\r
+                         0, 0,\r
+                         fli_bitmap->w, fli_bitmap->h,\r
+                         int_param[0], int_param[1],\r
+                         int_param[2], int_param[3]);\r
+\r
+            vsync(); // tratar de evitar el flicker\r
+            enviar_kfbuffer2screen(); /* refrescar pantalla */\r
+          }\r
+          \r
+          reset_fli_variables();\r
+\r
+          ret = next_fli_frame(0);\r
+          if (ret == FLI_ERROR) return -1; /* ERROR! */\r
+\r
+          if (ctxt)\r
+          {\r
+             /* ejecutar los sonidos adecuados al frame... */\r
+           sprintf(tmpstr,"FRAME_%d", fli_frame);\r
+           psample = find_datafile_object_type(el_archivo,  get_config_string(tmpstr, "snd", "null"), DAT_SAMPLE);\r
+           if (psample != NULL) play_sample((SAMPLE *)p->dat, 255, 128 ,1000, 0);\r
+\r
+             /* DEBUG: subtitular en caso necesario... */\r
+          }\r
+          \r
+         do {\r
+          /* esperar hasta proximo cuadro */\r
+          /* si aprieta una tecla, salir... */\r
+          if (keypressed() && teclado_cancela_fli)\r
+              {\r
+              ret = FLI_EOF;\r
+              fli_timer = 1;\r
+              loop = -1;\r
+              }\r
+         } while (fli_timer <= 0);\r
+         \r
+      }\r
+   close_fli(); /* adios... */\r
+ }\r
+\r
+/* Devolver mapa RGB */\r
+// rgb_map = &rgb_table_cine; // DEBUG: desactivado\r
+clear_keybuf(); /* limpio el buffer de teclado */\r
+return 0;\r
+}\r
+\r
+/* color de limpieza del fli */\r
+int cmd_clear_fli_back()\r
+{\r
+  cls_el_fli[0] = int_param[0] % 256;\r
+  cls_el_fli[1] = int_param[1] % 256;\r
+  cls_el_fli[2] = int_param[2] % 256;\r
+return 0;\r
+}\r
+\r
+/* ajusta la bandera de cancelar los fli con el teclado */\r
+int cmd_keyboard_cancel_fli()\r
+{\r
+teclado_cancela_fli = int_param[0];\r
+\r
+return 0;\r
+}\r
+\r
+/* --------------------- Funciones del motor en si --------------- */\r
+\r
+/* Esta macro funcion se encarga de reproducir una cinematica\r
+   desde un archivo DAT, pasarselo en char *file,\r
+   sera cargado, ejecutado, y liberado...\r
+   Esta es la funcion de entrada que deberia usarse para ejecutar\r
+   una cinematica \r
+   la afecta quiere_videos;\r
+   */\r
+void ejecutar_cinematica(char *file)\r
+{\r
+ DATAFILE *carga = NULL;\r
+ DATAFILE *p;\r
+ char *guion_txt;\r
+ char tmp[80]; // temporal... formacion del nombre del script\r
+\r
+ if (!quiere_videos) return; // el usuario no quiere ver videos\r
+\r
+ carga = krono_load_datafile(file);\r
+\r
+ if  (carga == NULL) return; /* el archivo no existe... chau... */\r
+\r
+ /* buscar el script */\r
+ sprintf(tmp, "guion_txt_%s", lenguaje);\r
+ p = find_datafile_object(carga, tmp);\r
+ if (p==NULL)\r
+ {\r
+     // si no existe el especifico del lenguaje, buscar el generico\r
+     p = find_datafile_object(carga, "guion_txt");\r
+     // si no existe el generico, buscar la version en ingles\r
+     if (p==NULL)\r
+     {\r
+         p = find_datafile_object(carga, "guion_txt_en");\r
+         if (p == NULL) return; /* no hay guion... chau... */\r
+     }\r
+ }\r
+ guion_txt = (char *)p->dat;\r
+\r
+ ejecutar_script(guion_txt, p->size, carga);\r
+\r
+ unload_datafile(carga); /* liberar... */\r
+}\r
+\r
+\r
+/*\r
+   Ejecuta el script pasado en char *txt_script\r
+   Esto podria ser un DATAFILE ->dat pasado a char, por ejemplo.\r
+   Toma el caracter 10 como salto de linea (compatible con UNIX)\r
+   El texto pasado en *txt_script puede ser del largo que se desee,\r
+   pero debe ser especificado en int size.\r
+   El char *archivo es el archivo DATAFILE que contendra\r
+   los diferentes objetos FLI, BITMAP, etc a usar por los comandos\r
+   Debe estar PRE-cargado en RAM\r
+   NOTA: kfbufferbmp sera usado como doble buffer! DEBE estar iniciado!\r
+\r
+\r
+   NOTA 2: Por pedido popular, ahora con ESC,SPACE o ENTER se puede cancelar \r
+           completamente la animacion\r
+*/\r
+void ejecutar_script(const char *txt_script, const int size, DATAFILE *archivo)\r
+{\r
+ int i = 0; /* posicion x en el txt_script */\r
+ int xl = 0; /* pos en tmp[] */\r
+ char tmp[MAX_LINEA]; /* lectura tmp */\r
+\r
+\r
+/* Iniciar el script */\r
+x_echo = 0, y_echo = 0, w_echo = ANCHO_RFB; /* pos cursor */\r
+\r
+echo_font = font; /* font a usar */\r
+echo_text_color = makecol(255,255,255); echo_text_back = -1; /* colores texto */\r
+text_mode(-1);\r
+\r
+teclado_cancela_fli = TRUE;\r
+cls_el_fli[0] = cls_el_fli[1] = cls_el_fli[2] = 0;\r
+\r
+get_palette(pal_cine); /* tomo la paleta actual */\r
+\r
+rgb_map = NULL; /* anulo el mapa RGB */\r
+\r
+// debug: desactivado\r
+// create_rgb_table(&rgb_table_cine, pal_cine, NULL);\r
+// rgb_map = &rgb_table_cine;\r
+\r
+/* doble buffer, debe estar iniciado! */\r
+set_clip(kfbufferbmp, 0, 0, kfbufferbmp->w-1, kfbufferbmp->h-1); /* clipping adecuado */\r
+clear(kfbufferbmp);\r
+\r
+n_linea_actual = 0;\r
+el_archivo = archivo;\r
+tmp[0] = '\0';\r
+linea_actual[0] = '\0';\r
+\r
+/* Revisar linea por linea del buffer */\r
+ for (i = 0; i < size; i++)\r
+ {\r
+  /* Ir armando la linea */\r
+  if (txt_script[i] == '\r' || xl == MAX_LINEA-1 || txt_script[i] == 10) /* salto de linea */\r
+  {\r
+   tmp[xl] = '\0';\r
+   krtrim(linea_actual, tmp); /* remover espacios */\r
+   n_linea_actual ++;\r
+   xl = 0;\r
+\r
+   if (parsear_y_ejecutar_linea()) return; /* interpretar comando, y cancelar si el usuario cancela */\r
+   \r
+   tmp[0] = '\0';\r
+   linea_actual[0] = '\0';\r
+  }\r
+  else\r
+  {      /* armando la linea */\r
+   tmp[xl] = (txt_script[i] >= 32) ? txt_script[i] : ' '; /* filtra chars 'raros' */\r
+   xl++;\r
+  }\r
+ }\r
+\r
+ /* Ultima linea, interpretar tambien... */\r
+   tmp[xl] = '\0';\r
+   krtrim(linea_actual, tmp); /* remover espacios */\r
+   n_linea_actual ++;\r
+   xl = 0;\r
+\r
+   parsear_y_ejecutar_linea(); /* interpretar comando! */\r
+\r
+ /* Termino el show... */\r
+}\r
+\r
+\r
+/*\r
+Esta funcion interpreta una linea y la parsea en sus parametros\r
+respectivos, para luego llamar a la funcion adecuada\r
+Si el usuario presiona una tecla, devuelve TRUE (-1) (Cancelar)\r
+Caso contrario, devuelve 0\r
+*/\r
+int parsear_y_ejecutar_linea()\r
+{\r
+int i, i2;\r
+char *tok;\r
+char tmptok[MAX_LINEA];\r
+\r
+/* es un comentario? no hacer nada... */\r
+if (linea_actual[0] == '#' || strlen(linea_actual) < 1 ) return 0;\r
+\r
+/* Limpio los parametros... */\r
+for (i = 0; i < MAX_PARAMS; i++)\r
+    {\r
+        int_param[i] = 0;\r
+        str_param[i][0] = '\0';\r
+    }\r
+\r
+comando_actual[0] = '\0';\r
+\r
+i = c_str_param = c_int_param = 0;\r
+\r
+/* Parsear la linea... */\r
+sprintf(tmptok, "%s", linea_actual); /* evito modificar el original */\r
+for (tok = strtok(tmptok, " ");tok;tok = strtok(0, " "))\r
+     {\r
+      if (i == 0)\r
+         {\r
+          krtrim(comando_actual, tok); /* el 1er comando */\r
+         }\r
+         else\r
+         { /* tomar parametros */\r
+          krtrim(str_param[i-1], tok); /* remover espacios */\r
+          c_str_param ++;\r
+          int_param[i-1] = atoi(tok);\r
+          c_int_param++;\r
+         }\r
+      i++;\r
+      if (i > MAX_PARAMS-1) break; /* muchos parametros */\r
+     }\r
+\r
+/* Tomar todo menos el primer parametro... */\r
+tmptok[0] = s2nd_param[0] = '\0';\r
+\r
+i2 = 0;\r
+i = strlen(comando_actual);\r
+while (i < strlen(linea_actual)) /* con un for no funcionaba... por que? */\r
+    {\r
+      tmptok[i2] = linea_actual[i];\r
+      i2++;\r
+      i++;\r
+    }\r
+\r
+tmptok[i2] = '\0';\r
+\r
+krtrim(s2nd_param, tmptok);\r
+\r
+/* ----------- interpretacion ----------- */\r
+\r
+/* recorro la lista en busca del comando a usar */\r
+i = 0;\r
+    while (cmd_list[i].comando != NULL && cmd_list[i].proc != NULL)\r
+    {\r
+        /* NOTA: cambiar strcmp x stricmp para ignorar mayus/minus, pero\r
+           no es ANSI ni POSIX */\r
+        if (strcmp(comando_actual, cmd_list[i].comando) == 0)\r
+            {\r
+             /* Tiene suficientes parametros? */\r
+             if (c_str_param < cmd_list[i].min_params && c_int_param < cmd_list[i].min_params)\r
+                {\r
+                 sprintf(tmptok,"ERROR:\ncinema.c:\nscript:linea(%d)='%s'\nInsuficientes parametros (requiere %d)!\n", n_linea_actual,linea_actual,cmd_list[i].min_params);\r
+                 levantar_error(tmptok);\r
+                }\r
+\r
+             /* llamar a la funcion, devuelven -1 en error */\r
+             if ( (*cmd_list[i].proc)() )\r
+                {\r
+                 sprintf(tmptok,"ERROR:\ncinema.c:\nscript:linea(%d)='%s'\nEl comando '%s' fallo\nPosibles parametros incorrectos o falta de objetos...\n", n_linea_actual,linea_actual,cmd_list[i].comando);\r
+                 levantar_error(tmptok);\r
+                }\r
+             \r
+                               // ver si el usuario cancelo\r
+                               if (keypressed() && (key[KEY_ESC] || key[KEY_ENTER] || key[KEY_SPACE]) ) \r
+                                       return TRUE;\r
+                               else\r
+                                   return 0; /* termino, proxima linea please... */\r
+            }\r
+        i++;\r
+    }\r
+\r
+/* Comando no reconocido! SHIT! */\r
+sprintf(tmptok, "ERROR:\ncinema.c:\nscript:linea(%d)='%s'\nComando no reconocido!\n", n_linea_actual, linea_actual);\r
+levantar_error(tmptok);\r
+       \r
+return 0;\r
+}\r
+#endif\r
diff --git a/src/clima.c b/src/clima.c
new file mode 100644 (file)
index 0000000..de89a9f
--- /dev/null
@@ -0,0 +1,172 @@
+// ------------------------------------\r
+// clima.c\r
+// ------------------------------------\r
+// Modulo de efectos climaticos\r
+// Por Kronoman\r
+// En memoria de mi querido padre\r
+// Copyright (c) 2002, Kronoman\r
+// ------------------------------------\r
+\r
+\r
+#include <allegro.h>\r
+#include "clima.h"\r
+#include "azar.h"\r
+#include "global.h"\r
+\r
+static CLIMA_P clima_p[MAX_CLIMA_P]; // contenedor de particulas\r
+static int clima_cant = 0; // cantidad de particulas 0..MAX_CLIMA_P\r
+\r
+// auxiliar que reinicia una particula individual\r
+// parametros:\r
+// idem a init_clima,\r
+// i es el indice de la particula\r
+static void reinit_clima_part(BITMAP *bmp, int c, int t, int d, int i )\r
+{\r
+  int c2;\r
+  int minx = 50, miny = 50 , maxx = 100 , maxy = 150; // velocidades minimas y maximas \r
+\r
+  // info extra       \r
+  clima_p[i].t = t;\r
+  clima_p[i].d = d;\r
+\r
+  // iniciar coordenadas de las particulas y direccion\r
+      clima_p[i].y = itofix( rand_ex(0, bmp->h) );\r
+      clima_p[i].x = itofix( rand_ex(0, bmp->w) );\r
+\r
+  // color y radio\r
+  switch (t)\r
+  {\r
+  case 0: // lluvia\r
+    c2 = rand_ex(200, 255);\r
+    clima_p[i].col = makecol(0,128,c2); // tonos de azul\r
+    clima_p[i].r = 1;\r
+       minx = 80;\r
+       maxx = 120;\r
+    miny = 60;\r
+       maxy = 180;\r
+  break;\r
+\r
+  case 1: // nieve\r
+    c2 = rand_ex(192, 255);\r
+    clima_p[i].col = makecol(c2,c2,c2); // tono de gris\r
+    clima_p[i].r = rand_ex(1,5); // radio\r
+       minx = 40;\r
+       maxx = 110;\r
+    miny = 50;\r
+       maxy = 150;\r
+  break;\r
+\r
+  default: // error, el tipo no existe, no poner clima\r
+     clima_cant = 0;\r
+     return;\r
+  break;\r
+  }\r
+\r
+// velocidad de particulas\r
+  clima_p[i].dx = ftofix( (float)rand_ex(minx, maxx) / 10.0);\r
+  clima_p[i].dy = ftofix( (float)rand_ex(miny, maxy) / 10.0);\r
+\r
+// si hay que ir a la izquierda...\r
+if (d == 0) clima_p[i].dx = fixmul(clima_p[i].dx , itofix(-1)); // a la izquierda\r
+\r
+}\r
+\r
+// Inicializa el clima\r
+// Parametros:\r
+// bmp = bitmap de buffer\r
+// c = cantidad de particulas\r
+// t = tipo: 0 = lluvia, 1 = nieve, etc\r
+// d = direccion de caida: 0 = izquierda, 1 = derecha\r
+//\r
+void init_clima(BITMAP *bmp, int c, int t, int d)\r
+{\r
+int i;\r
+if (c < 1 || c > MAX_CLIMA_P)\r
+   {\r
+     clima_cant = 0;\r
+     return;\r
+   }\r
+// iniciar particulas\r
+\r
+for (i=0; i < c; i ++)\r
+{\r
+  reinit_clima_part(bmp, c, t, d, i );\r
+} // fin for\r
+\r
+ clima_cant = c;\r
+}\r
+\r
+\r
+// mueve el clima\r
+// parametros:\r
+// bmp = bitmap de uso\r
+void mover_clima(BITMAP *bmp)\r
+{\r
+int i;\r
+ for (i=0; i < clima_cant; i ++)\r
+ {\r
+  // mover clima\r
+  clima_p[i].x = fixadd(clima_p[i].x, clima_p[i].dx);\r
+  clima_p[i].y = fixadd(clima_p[i].y, clima_p[i].dy);\r
+  // reiniciar particula si se sale\r
+  if (clima_p[i].x < 0 || fixtoi(clima_p[i].x) > bmp->w ||\r
+      clima_p[i].y < 0 || fixtoi(clima_p[i].y) > bmp->h)\r
+      {\r
+        reinit_clima_part(bmp, clima_cant, clima_p[i].t, clima_p[i].d, i );\r
+      }\r
+ } // fin for\r
+}\r
+\r
+\r
+// dibuja el clima\r
+// parametros:\r
+// bmp = bitmap de uso\r
+void dibuja_clima(BITMAP *bmp)\r
+{\r
+int i;\r
+ for (i=0; i < clima_cant; i ++)\r
+ {\r
+  switch (clima_p[i].t)\r
+  {\r
+  case 0: // lluvia\r
+  \r
+  if (nivel_detalle > 9) \r
+  {\r
+        drawing_mode(DRAW_MODE_TRANS, NULL, 0,0); // lluvia transparente, cool!\r
+       triangle(bmp,\r
+         fixtoi(clima_p[i].x),\r
+         fixtoi(clima_p[i].y),\r
+         fixtoi(fixadd(clima_p[i].x, clima_p[i].dx)),\r
+         fixtoi(fixadd(clima_p[i].y, clima_p[i].dy)),\r
+         fixtoi(clima_p[i].x),\r
+         fixtoi(clima_p[i].y)+(rand()%4)+1,\r
+         clima_p[i].col);\r
+  solid_mode();\r
+  }\r
+  else\r
+  {\r
+           line(bmp,\r
+             fixtoi(clima_p[i].x),\r
+             fixtoi(clima_p[i].y),\r
+             fixtoi(fixadd(clima_p[i].x, clima_p[i].dx)),\r
+             fixtoi(fixadd(clima_p[i].y, clima_p[i].dy)),\r
+             clima_p[i].col);\r
+  }\r
+  break;\r
+\r
+  case 1: // nieve\r
+    circlefill(bmp,\r
+           fixtoi(clima_p[i].x),\r
+           fixtoi(clima_p[i].y),\r
+           clima_p[i].r,\r
+           clima_p[i].col);\r
+  break;\r
+\r
+  default: // error, el tipo no existe, no dibujar\r
+  break;\r
+  }\r
+ } // fin for\r
\r
\r
+}\r
+\r
diff --git a/src/combo.c b/src/combo.c
new file mode 100644 (file)
index 0000000..0e7c310
--- /dev/null
@@ -0,0 +1,117 @@
+// -------------------------------------------------------- \r
+// combo.c \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Esto contiene combos para agregar explosiones+particulas\r
+// y tocar los sonidos, musica, etc\r
+// -------------------------------------------------------- \r
+#ifndef COMBO_C\r
+#define COMBO_C\r
+\r
+#include "allegro.h"\r
+#include "partic.h"\r
+#include "explos.h"\r
+#include "azar.h"\r
+#include "combo.h"\r
+#include "global.h"\r
+/*\r
+   agrega muchas particulas  a la vez\r
+   cant es la cantidad\r
+   si col < 0, usara colores en gama de fuego (naranjas)\r
+*/\r
+void poner_muchas_particulas( int x,  int y,\r
+                              int dx, int dy,\r
+                              int vida,\r
+                              int col, int r, int t,\r
+                              BITMAP *spr,\r
+                              int cant )\r
+{\r
+int i, c2;\r
+c2 = col;\r
+\r
+/* si el nivel de detalle es bajo, limita la cantidad de particulas a 10 por round */\r
+if (nivel_detalle < 4 && cant > 10) cant = 10;\r
+if (nivel_detalle < 2 && cant > 5) cant = 5;\r
+\r
+for (i = 0; i < cant; i++)\r
+        {\r
+        if (col < 0) c2  = makecol(255,rand()%255,0);\r
+\r
+           agrega_particula( itofix(x),  itofix(y),\r
+                             ftofix((rand_ex(-100*dx, 100*dx))/100.0), ftofix((rand_ex(-100*dy, 100*dy))/100.0),\r
+                             rand_ex(vida/4, vida),\r
+                             c2, rand_ex(r/2,r)+1, t,0,0,\r
+                             spr );\r
+        }\r
+}\r
+\r
+/*\r
+ agrega una explosion y particulas en x,y\r
+ con cantidad c y radio r (tambien indica duracion particulas * 2)\r
+ las particulas son trozos de nave y fuego\r
+ el radio para la explosion es el ancho/alto en pixeles...\r
+ si bmpp es !=0, pondra chispas con bitmaps tambien (Explosion final de algo grande)\r
+ */\r
+void poner_explosion_nave(int x, int y, int c, int r, int bmpp)\r
+{\r
+\r
+/* DEBUG: funcion mal hecha, no agrega bitmaps, solo poligonos */\r
+poner_muchas_particulas(  x,   y,\r
+                          5, 5,\r
+                         r*2,\r
+                         -1, 4, 3,\r
+                         NULL,\r
+                         c );\r
+\r
+\r
+pone_explo_pixel(&ptr_explo_arriba, x, y, r, r*2, ftofix(0.01));\r
+\r
+if (bmpp && nivel_detalle > 7 ) { /* particulas con bitmaps */\r
+    int z1;\r
+    for (z1 = 0; z1 < 3; z1++)\r
+        poner_muchas_particulas(  x,   y,\r
+                                  5, 5,\r
+                                 r*rand_ex(2, 4),\r
+                                 -1, 4, 3,\r
+                                 particula_cache_bmp[z1],\r
+                                 c/rand_ex(2,3) ); /* poner 1/3 o 1/2 de particulas */\r
+    }\r
+\r
+}\r
+\r
+/*\r
+Esta funcion coloca una explosion en x,y\r
+con radio r, el radio expresado en PIXELS!\r
+v es la vida, v2 la combustion\r
+NOTA: la explosion se limita en tama~o para no sobrecargar el juego\r
+NOTA: pasarle el puntero a la capa de explosion con &puntero! \r
+*/\r
+void pone_explo_pixel(EXPLOSION **explo, int x, int y, int r, int v, fixed v2)\r
+{\r
+float rpx; /* para calculos luego */\r
+BITMAP *tmp;\r
+\r
+/* Limitar a 150 pixels de radio */\r
+if (r > 150) r= 150;\r
+\r
+if (nivel_detalle < 2 && r > 50) r = 50; /* el detalle limita el tama~o tambien */\r
+\r
+/* explosion, calculo la proporcion entre pixeles y el tama~o del\r
+   sprite de la explosion y luego la agrego */\r
+\r
+tmp = explo_cache_bmp[rand()%3];\r
+rpx = (float)r / (float)tmp->w;\r
+\r
+agrega_explosion( explo,\r
+                  itofix(x),  itofix(y),\r
+                  0,0,\r
+                  v,\r
+                  ftofix(rpx), v2,\r
+                  rand()%255,\r
+                  tmp );\r
+\r
+}\r
+\r
+#endif\r
diff --git a/src/config.c b/src/config.c
new file mode 100644 (file)
index 0000000..b1d136d
--- /dev/null
@@ -0,0 +1,77 @@
+// -------------------------------------------------------------\r
+// config.c\r
+// -------------------------------------------------------------\r
+// Se encarga de cargar / salvar la configuracion de Kraptor\r
+// Por Kronoman\r
+// Copyright (c) 2003, Kronoman\r
+// En memoria de mi querido padre\r
+// -------------------------------------------------------------\r
+\r
+#include <allegro.h>\r
+#include "jugador.h"\r
+#include "config.h"\r
+#include "global.h"\r
+\r
+void cargar_configuracion()\r
+{\r
+ set_config_file("kraptor.cfg");\r
+ teclado_jug.arr = get_config_int("kraptor_keyboard", "arr", teclado_jug.arr);\r
+ teclado_jug.abj = get_config_int("kraptor_keyboard", "abj", teclado_jug.abj);\r
+ teclado_jug.izq = get_config_int("kraptor_keyboard", "izq", teclado_jug.izq);\r
+ teclado_jug.der = get_config_int("kraptor_keyboard", "der", teclado_jug.der);\r
+ teclado_jug.sht = get_config_int("kraptor_keyboard", "sht", teclado_jug.sht);\r
+ teclado_jug.wpn = get_config_int("kraptor_keyboard", "wpn", teclado_jug.wpn);\r
+ teclado_jug.bmb = get_config_int("kraptor_keyboard", "bmb", teclado_jug.bmb);\r
+\r
+ nivel_detalle = get_config_int("kraptor_detalle", "nivel_detalle", nivel_detalle);\r
+ detalle_automatico = get_config_int("kraptor_detalle", "detalle_automatico", detalle_automatico);\r
+ quiere_videos = get_config_int("kraptor_detalle", "quiere_videos", quiere_videos);\r
\r
+ quiere_snd = get_config_int("kraptor_snd", "quiere_snd", quiere_snd);\r
+ volumen_sonido = get_config_int("kraptor_snd", "volumen_sonido", volumen_sonido);\r
+ quiere_musica = get_config_int("kraptor_snd", "quiere_musica", quiere_musica);\r
+ volumen_musica = get_config_int("kraptor_snd", "volumen_musica", volumen_musica);\r
+\r
+ KRONO_QUIERE_DEBUG = get_config_int("KRONO_QUIERE_DEBUG", "KRONO_QUIERE_DEBUG", KRONO_QUIERE_DEBUG);\r
+ quiere_usar_joystick = get_config_int("kraptor_joystick", "quiere_usar_joystick", quiere_usar_joystick);\r
+ numero_de_joystick = get_config_int("kraptor_joystick", "numero_de_joystick", numero_de_joystick);\r
+\r
+\r
+ quiere_usar_mouse = get_config_int("kraptor_mouse", "quiere_usar_mouse", quiere_usar_mouse);\r
+ mouse_velocidad = get_config_int("kraptor_mouse", "mouse_velocidad", mouse_velocidad);\r
+\r
+// load_joystick_data(NULL);  // esto me dio problemas la primera vez que lo use... ojo\r
+\r
\r
+}\r
+\r
+void salvar_configuracion()\r
+{\r
+ set_config_file("kraptor.cfg");\r
+\r
+ set_config_int("kraptor_keyboard", "arr", teclado_jug.arr);\r
+ set_config_int("kraptor_keyboard", "abj", teclado_jug.abj);\r
+ set_config_int("kraptor_keyboard", "izq", teclado_jug.izq);\r
+ set_config_int("kraptor_keyboard", "der", teclado_jug.der);\r
+ set_config_int("kraptor_keyboard", "sht", teclado_jug.sht);\r
+ set_config_int("kraptor_keyboard", "wpn", teclado_jug.wpn);\r
+ set_config_int("kraptor_keyboard", "bmb", teclado_jug.bmb);\r
+\r
+ set_config_int("kraptor_detalle", "nivel_detalle", nivel_detalle);\r
+ set_config_int("kraptor_detalle", "quiere_videos", quiere_videos);\r
+ set_config_int("kraptor_detalle", "detalle_automatico", detalle_automatico);\r
+\r
+ set_config_int("kraptor_snd", "quiere_snd", quiere_snd);\r
+ set_config_int("kraptor_snd", "volumen_sonido", volumen_sonido);\r
+ set_config_int("kraptor_snd", "quiere_musica", quiere_musica);\r
+ set_config_int("kraptor_snd", "volumen_musica", volumen_musica);\r
+ set_config_int("KRONO_QUIERE_DEBUG", "KRONO_QUIERE_DEBUG", KRONO_QUIERE_DEBUG);\r
+\r
+ set_config_int("kraptor_joystick", "quiere_usar_joystick", quiere_usar_joystick);\r
+ set_config_int("kraptor_joystick", "numero_de_joystick", numero_de_joystick);\r
+\r
+ set_config_int("kraptor_mouse", "quiere_usar_mouse", quiere_usar_mouse);\r
+ set_config_int("kraptor_mouse", "mouse_velocidad", mouse_velocidad);\r
\r
+// save_joystick_data(NULL); // esto me dio problemas la primera vez que lo use... ojo\r
+}\r
diff --git a/src/data.c b/src/data.c
new file mode 100644 (file)
index 0000000..2eb37ba
--- /dev/null
@@ -0,0 +1,669 @@
+// -------------------------------------------------------- \r
+// data.c \r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Esto se encarga de cargar y poner en memoria\r
+// los datos leidos de disco.\r
+// -------------------------------------------------------- \r
+#ifndef DATA_C\r
+#define DATA_C\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "allegro.h"\r
+\r
+#include "data.h"\r
+#include "error.h"\r
+#include "global.h"\r
+#include "jugador.h"\r
+#include "enemigo.h"\r
+#include "pmask.h"\r
+#include "sombras.h"\r
+#include "datafind.h"\r
+#include "explos.h"\r
+#include "mapa.h"\r
+#include "partic.h"\r
+#include "menu.h"\r
+#include "shopping.h"\r
+#include "humo.h" \r
+#include "ia.h"\r
+#include "premio.h"\r
+#include "filedata.h"\r
+#include "bomba.h"\r
+\r
+/* Globales */\r
+\r
+    /* Este datafile contiene los datos principales del juego\r
+       tales como el script de secuencia de niveles,\r
+       graficos de menues, paleta de juego, armamento,\r
+       enemigos, sprites del jugador, premios, sonidos\r
+       Se carga al inicio del programa, y se descarga al salir\r
+       */\r
+DATAFILE *krapmain = NULL;\r
+\r
+    /* Cada fondo y mapa de juego esta puesto por separado\r
+       en un DAT para evitar sobrecarga de memoria.\r
+       Este datafile es cargado y descargado a medida que pasan\r
+       los niveles.\r
+       Contiene el fondo (600x4000) y el mapa de juego\r
+       */\r
+DATAFILE *datmapa = NULL;\r
+\r
+/* Esto contiene los graficos para los menues */\r
+DATAFILE *datmenu = NULL;\r
+\r
+/* globales internas */\r
+static int byte_acumulado = 0; /* auxiliar para contar bytes leidos (no necesario) */\r
+\r
+/* Funcion interna callback, que muestra cuanto se ha leido...\r
+   en la esquina superior izquierda, usando colores\r
+   del GUI para el texto\r
+   La primera vez que es llamado (byte_acumulado == 0) dibuja una caja de texto\r
+   Esta dise~ado para no atrasar mucho la carga */\r
+static void cargar_callback(DATAFILE *d)\r
+{\r
+ if (byte_acumulado <= 0)\r
+    {\r
+     byte_acumulado = 0;\r
+     /* fondo */\r
+     rectfill(screen, 0,0,SCREEN_W-1, (text_height(font)+5)*2, gui_bg_color);\r
+     /* sombra (negro) */\r
+     rectfill(screen, 5,5,SCREEN_W-5, (text_height(font)+10)*2, makecol(0,0,0));\r
+     /* borde */\r
+     rect(screen, 0,0,SCREEN_W-1, (text_height(font)+5)*2, gui_fg_color);\r
+    }\r
+\r
+ byte_acumulado += d->size;\r
+ text_mode(gui_bg_color);\r
+ textprintf(screen, font, 2, 2, gui_fg_color, "Wait please, loading...");\r
+ textprintf(screen, font, 2, text_height(font)+4, gui_fg_color, "-> %d", byte_acumulado);\r
+}\r
+\r
+\r
+/* Esta funcion carga los datos principales del juego en memoria,\r
+   es decir, paletas, jugador, enemigo, IA, armamento\r
+   Afecta a  *krapmain\r
+   MUESTRA UN MENSAJE DE CARGA EN PANTALLA! [ESQUINA SUP-IZQ]\r
+   */\r
+void cargar_datos_principales()\r
+{\r
+   DATAFILE *p = NULL; /* puntero de busqueda */\r
+   int i, i2; /* para los fors */\r
+   char tmpstr[1024], tmpstr2[1024]; /* uso general */\r
+\r
+   if (krapmain != NULL) unload_datafile(krapmain);\r
+   if (datmenu != NULL) unload_datafile(datmenu);\r
+\r
+   set_color_conversion(COLORCONV_TOTAL | COLORCONV_KEEP_TRANS);\r
+\r
+   /* colores para el callback que muestra el progreso de la carga */\r
+   gui_fg_color = makecol(255,255,255);\r
+   gui_bg_color = makecol(0,0,0);\r
+   byte_acumulado = 0; /* contador para mostrar progreso */\r
+\r
+   /* primero, trato de cargar SOLO la paleta de juego,\r
+      esto es para poder convertir las imagenes a los bpp adecuados */\r
+   krapmain = krono_load_datafile_object("krapmain.dat", "pal_game");\r
+   if (krapmain == NULL)  levantar_error("ERROR: no existe pal_game en krapmain.dat");\r
+\r
+       /* copiar la paleta a RAM ... */\r
+       memcpy(pal_game, krapmain->dat, sizeof(PALETTE));\r
+    \r
+       /* Paletas de colores y mapas de transparencias... [ya estan cargadas, hago calculos...] */\r
+       set_palette(pal_game); /* la seteo, la precisa la sombra... */\r
+    \r
+       /* Crear mapa de transparencia de 8 bits */\r
+       create_trans_table(&tabla_transparencia, pal_game, 128,128,128, NULL);\r
+       color_map = &tabla_transparencia;  /* la rutina de sombras la precisa! */\r
+    \r
+       /* Crear mapa RGB de 8 bits */\r
+       create_rgb_table(&tabla_RGB, pal_game, NULL);\r
+       rgb_map = &tabla_RGB;\r
+\r
+       /* Crear mapa para 'quemado' del fondo */\r
+ create_color_table(&tabla_quemado,\r
+                       pal_game,\r
+                       crear_mapa_quemazon,\r
+                       NULL);\r
+       \r
+   /* ya no preciso mas la paleta en RAM */\r
+   unload_datafile_object(krapmain);\r
+   krapmain = NULL;\r
+\r
+   /* Cargo el cache de inteligencia artificial */\r
+   hacer_chache_ia("ia.dat");\r
+\r
+   /* Ahora si, cargar TODO el archivo de datos */\r
+   gui_bg_color = makecol(0,0,0);  gui_fg_color = makecol(255,255,255); // colores para la info de carga\r
+   krapmain = krono_load_datafile_callback("krapmain.dat", cargar_callback);\r
+   if (krapmain == NULL) levantar_error("ERROR: no se pudo cargar krapmain.dat");\r
+\r
+   /* DEBUG: falta ajustar datafile al modo de video actual */\r
+   fixup_datafile(krapmain);\r
+\r
+   p = find_datafile_object(krapmain, "gamescript");\r
+   if (p == NULL) levantar_error("ERROR: el gamescript no esta definido en krapmain.dat");\r
+\r
+   set_config_data((char *)p->dat, p->size);\r
+\r
+\r
+   /* obtener la cinematica de introduccion al primer nivel */\r
+   sprintf(game_intro_cine, "%s", get_config_string("game_intro", "cine", "null"));\r
+\r
+   /* obtener la cinematica de game over */\r
+   sprintf(game_over_cine, "%s", get_config_string("game_over", "cine", "null"));\r
+\r
+   /* font para el 'hud' */\r
+   p = find_datafile_object(krapmain, "hud_font");\r
+   if (p == NULL)\r
+     hud_font = font_backup;\r
+   else\r
+     hud_font = (FONT *)p->dat;\r
+\r
+   /* Cargar explosiones, particulas, sonidos y sprite quemador en cache */\r
+    for (i = 0; i < 3; i++)\r
+    {\r
+     sprintf(tmpstr,"explo_bmp_%d", i);\r
+     p = find_datafile_object_type(krapmain, tmpstr, DAT_BITMAP);\r
+     if (p == NULL) levantar_error("ERROR: falta un objeto explo_bmp_[0..2]");\r
+     explo_cache_bmp[i] = (BITMAP *)p->dat;\r
+\r
+     sprintf(tmpstr,"explo_snd_%d", i);\r
+     p = find_datafile_object_type(krapmain, tmpstr, DAT_SAMPLE);\r
+     if (p == NULL) levantar_error("ERROR: falta un objeto explo_snd_[0..2]");\r
+     explo_cache_snd[i] = (SAMPLE *)p->dat;\r
+     explo_cache_snd[i]->priority = 30; /* prioridad baja a las explosiones */\r
+\r
+     sprintf(tmpstr,"chispa_%d", i);\r
+     p = find_datafile_object_type(krapmain, tmpstr, DAT_BITMAP);\r
+     if (p == NULL) levantar_error("ERROR: falta un objeto chispa_[0..2]");\r
+     particula_cache_bmp[i] = (BITMAP *)p->dat;\r
+\r
+     sprintf(tmpstr,"burn_%d", i);\r
+     p = find_datafile_object_type(krapmain, tmpstr, DAT_BITMAP);\r
+     if (p == NULL) levantar_error("ERROR: falta un objeto burn_[0..2]");\r
+     burn_cache_bmp[i] = (BITMAP *)p->dat;\r
+\r
+    }\r
+    // Cargar humo en cache\r
+     p = find_datafile_object_type(krapmain, "humo", DAT_BITMAP);\r
+     if (p == NULL)\r
+             humo_spr = NULL;\r
+     else\r
+             humo_spr = (BITMAP *)p->dat;\r
+\r
+\r
+   /* Script del jugador a partir de aqui */\r
+\r
+   p = find_datafile_object(krapmain, "jugador");\r
+   if (p == NULL) levantar_error("ERROR: el jugador no esta definido en krapmain.dat");\r
+\r
+   set_config_data((char *)p->dat, p->size);\r
+\r
+   /* Cargar sprites del jugador */\r
+   for (i = 0; i < 3; i++)\r
+    {\r
+     sprintf(tmpstr,"spr_%d", i);\r
+\r
+     p = find_datafile_object_type(krapmain, get_config_string("jugador", tmpstr, "null"), DAT_BITMAP);\r
+     if (p == NULL) levantar_error("ERROR: en el jugador: spr_* no esta definido en krapmain.dat");\r
+     jugador.spr[i] = (BITMAP *)p->dat;\r
+\r
+     jugador.spr[i+3] = create_bitmap(jugador.spr[i]->w * 0.8, jugador.spr[i]->h * 0.8);\r
+     hacer_sombra(jugador.spr[i], jugador.spr[i+3]);\r
+    }\r
+\r
+   /* dinero y bombas al iniciar un nuevo juego */\r
+   jugador.init_money = get_config_int("JUGADOR","init_money", 0);\r
+   jugador.init_bombas = get_config_int("JUGADOR","init_bombas", 0);\r
+\r
+   /* reparacion de la nave */\r
+   jugador.reparar_cantidad = get_config_int("JUGADOR_REPARAR","cantidad", 10);\r
+   jugador.reparar_precio = get_config_int("JUGADOR_REPARAR","precio" , 1);\r
+   sprintf(jugador.reparar_desc,"%s", get_config_string("JUGADOR_REPARAR", "desc", "Fix the ship") );\r
+\r
+   p = find_datafile_object_type(krapmain, get_config_string("JUGADOR_REPARAR", "bmp", "null"), DAT_BITMAP);\r
+   if (p == NULL)\r
+     jugador.reparar_bmp = NULL;\r
+   else\r
+      jugador.reparar_bmp = (BITMAP *)p->dat;\r
+\r
+   /* bombas especiales de la nave */\r
+   jugador.bomba_cantidad = get_config_int("JUGADOR_BOMBA_ESPECIAL","cantidad", 10);\r
+   jugador.bomba_precio = get_config_int("JUGADOR_BOMBA_ESPECIAL","precio" , 10);\r
+   jugador.max_bombas = get_config_int("JUGADOR_BOMBA_ESPECIAL","max_ammo" , 5);\r
+   sprintf(jugador.bomba_desc,"%s", get_config_string("JUGADOR_BOMBA_ESPECIAL", "desc", "Special bomb") );\r
+\r
+   p = find_datafile_object_type(krapmain, get_config_string("JUGADOR_BOMBA_ESPECIAL", "bmp", "null"), DAT_BITMAP);\r
+   if (p == NULL)\r
+     jugador.bomba_bmp = NULL;\r
+   else\r
+      jugador.bomba_bmp = (BITMAP *)p->dat;\r
+\r
+   p = find_datafile_object_type(krapmain, get_config_string("JUGADOR_BOMBA_ESPECIAL", "bomba_sonido", "null"), DAT_SAMPLE);\r
+   if (p == NULL)\r
+     bomba_sonido = NULL;\r
+   else\r
+     bomba_sonido = (SAMPLE *)p->dat;\r
+\r
+\r
+   /* mascara de colision del jugador */\r
+   jugador.mask = create_allegro_pmask(jugador.spr[1]);\r
+\r
\r
+   /* Armamento del jugador */\r
+   for (i=0; i < MAX_ARM_CLASS; i++)\r
+       {\r
+        sprintf(tmpstr,"ARMA_%d", i);\r
+\r
+        arma_tipo[i].arma = NULL;\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "arma", "null"), DAT_BITMAP);\r
+        if (p != NULL )  arma_tipo[i].arma = (BITMAP *)p->dat;\r
+\r
+        sprintf(arma_tipo[i].desc,"%s", get_config_string(tmpstr, "desc", "null"));\r
+        sprintf(arma_tipo[i].desc_short,"%s", get_config_string(tmpstr, "desc_short", "null"));\r
+        arma_tipo[i].desc[2048] = '\0';\r
+        arma_tipo[i].desc_short[20] = '\0';\r
+\r
+        arma_tipo[i].precio = get_config_int(tmpstr, "precio", -1);\r
+        arma_tipo[i].cant_ammo = get_config_int(tmpstr, "cant_ammo", 0);\r
+        arma_tipo[i].cant_ammo_max = get_config_int(tmpstr, "cant_ammo_max", 0);\r
+\r
+        arma_tipo[i].spr = NULL;\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "spr", "null"), DAT_BITMAP);\r
+        if (p != NULL) arma_tipo[i].spr = (BITMAP *)p->dat;\r
+\r
+        arma_tipo[i].mask = NULL;\r
+\r
+        if (arma_tipo[i].spr != NULL)\r
+            {\r
+                arma_tipo[i].mask = create_allegro_pmask(arma_tipo[i].spr);\r
+            }\r
+\r
+        arma_tipo[i].snd[0] = NULL;\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "snd_0", "null"), DAT_SAMPLE);\r
+        if (p != NULL)\r
+        {\r
+            arma_tipo[i].snd[0] = (SAMPLE *)p->dat;\r
+            arma_tipo[i].snd[0]->priority = 140; /* prioridad  */\r
+        }\r
+\r
+        arma_tipo[i].snd[1] = NULL;\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "snd_1", "null"), DAT_SAMPLE);\r
+        if (p != NULL)\r
+        {\r
+            arma_tipo[i].snd[1] = (SAMPLE *)p->dat;\r
+            arma_tipo[i].snd[1]->priority = 50; /* prioridad  */\r
+        }\r
+\r
+        arma_tipo[i].vx = ftofix(get_config_float(tmpstr,"vx", 0.0));\r
+        arma_tipo[i].vy = ftofix(get_config_float(tmpstr,"vy", 0.0));\r
+        arma_tipo[i].vida = get_config_int(tmpstr,"vida", -1);\r
+        arma_tipo[i].punch = get_config_int(tmpstr,"punch", 0);\r
+        arma_tipo[i].firerate = get_config_int(tmpstr,"firerate", 0);\r
+        arma_tipo[i].t = get_config_int(tmpstr,"t", 0);\r
+\r
+        /* Estela del disparo... */\r
+        arma_tipo[i].est_vida[0] = get_config_int(tmpstr, "est_vida_min", 0);\r
+        arma_tipo[i].est_vida[1] = get_config_int(tmpstr, "est_vida_max", 0);\r
+        arma_tipo[i].est_cant[0] = get_config_int(tmpstr, "est_cant_min", 0);\r
+        arma_tipo[i].est_cant[1] = get_config_int(tmpstr, "est_cant_max", 0);\r
+\r
+        arma_tipo[i].est_color[0][0] = get_config_int(tmpstr, "est_color_r_min", 0);\r
+        arma_tipo[i].est_color[0][1] = get_config_int(tmpstr, "est_color_r_max", 0);\r
+        arma_tipo[i].est_color[1][0] = get_config_int(tmpstr, "est_color_g_min", 0);\r
+        arma_tipo[i].est_color[1][1] = get_config_int(tmpstr, "est_color_g_max", 0);\r
+        arma_tipo[i].est_color[2][0] = get_config_int(tmpstr, "est_color_b_min", 0);\r
+        arma_tipo[i].est_color[2][1] = get_config_int(tmpstr, "est_color_b_max", 0);\r
+\r
+        arma_tipo[i].est_dx[0] = get_config_int(tmpstr, "est_dx_min", 0);\r
+        arma_tipo[i].est_dx[1] = get_config_int(tmpstr, "est_dx_max", 0);\r
+\r
+        arma_tipo[i].est_dy[0] = get_config_int(tmpstr, "est_dy_min", 0);\r
+        arma_tipo[i].est_dy[1] = get_config_int(tmpstr, "est_dy_max", 0);\r
+\r
+        arma_tipo[i].est_tipo[0] = get_config_int(tmpstr, "est_tipo_min", 0);\r
+        arma_tipo[i].est_tipo[1] = get_config_int(tmpstr, "est_tipo_max", 0);\r
+       \r
+       arma_tipo[i].est_rad[0] = get_config_int(tmpstr, "est_rad_min", 1);\r
+       arma_tipo[i].est_rad[1] = get_config_int(tmpstr, "est_rad_max", 2);\r
+\r
+       arma_tipo[i].est_transp = get_config_int(tmpstr, "est_transp", 0);\r
+       }\r
+\r
+   /* Cargar premios */\r
+   p = find_datafile_object(krapmain, "premios");\r
+   if (p == NULL) levantar_error("ERROR: los premios no estan definidos en krapmain.dat");\r
+   set_config_data((char *)p->dat, p->size);\r
+   \r
+   for (i = 0; i < MAX_PREMIO_CLASS; i++)\r
+   {\r
+   sprintf(tmpstr,"PREMIO_%d", i);\r
+   premio_class[i].premiar = get_config_int(tmpstr,"premiar", -666);\r
+   premio_class[i].cantidad = get_config_int(tmpstr,"cantidad", 0);\r
+   premio_class[i].vida = get_config_int(tmpstr,"vida", 0);\r
+\r
+   // Obtener bitmap\r
+   p = find_datafile_object_type(krapmain, get_config_string(tmpstr, "sprite", "null"), DAT_BITMAP);\r
+   if (p != NULL)\r
+      premio_class[i].sprite = (BITMAP *)p->dat;\r
+   else\r
+      premio_class[i].sprite = NULL;\r
+\r
+   // obtener sonido\r
+   p = find_datafile_object_type(krapmain, get_config_string(tmpstr, "sonido", "null"), DAT_SAMPLE);\r
+   if (p != NULL)\r
+      premio_class[i].sonido = (SAMPLE *)p->dat;\r
+   else\r
+      premio_class[i].sonido = NULL;\r
+    \r
+   }\r
+\r
+   /* Script de enemigos a partir de aqui */\r
+\r
+   /* Cargar clases de enemigos */\r
+   p = find_datafile_object(krapmain, "enemigos");\r
+   if (p == NULL) levantar_error("ERROR: los enemigos no estan definidos en krapmain.dat");\r
+   set_config_data((char *)p->dat, p->size);\r
+\r
+   /* Cargar enemigos, tipo de IA que le corresponde, y tipos de armas */\r
+   for (i=0; i < MAX_E_CLASS; i++)\r
+       {\r
+\r
+        /* Seccion ENEMIGO_n */\r
+        sprintf(tmpstr,"ENEMIGO_%d", i);\r
+\r
+        enem_t[i].vida = get_config_int(tmpstr,"vida", -1);\r
+\r
+        enem_t[i].peso = get_config_int(tmpstr,"peso", 0);\r
+      \r
+        enem_t[i].dinero = get_config_int(tmpstr,"dinero", 0);\r
+        \r
+        /* premios que suelta el enemigo */\r
+        enem_t[i].premio_idx = get_config_int(tmpstr,"premio_idx", -1);\r
+        enem_t[i].premio_prob = get_config_int(tmpstr,"premio_prob", -1);\r
+\r
+        enem_t[i].spr_delay = get_config_int(tmpstr,"spr_delay", 10); //delay de animacion\r
+\r
+        // bytecodes de tipo de IA   \r
+        enem_t[i].ia_node = buscar_lista_ia(get_config_string(tmpstr,"tipo_ia","null"));  \r
+        enem_t[i].ia_azar = get_config_int(tmpstr,"ia_azar", 0); // ia azaroza?\r
+        enem_t[i].ia_boss = get_config_int(tmpstr,"ia_boss", 0); // ia boss?\r
+           \r
+      // cargar los sprites de animacion del enemigo\r
+      for (i2 = 0; i2<4; i2++)\r
+      {\r
+        enem_t[i].spr[i2] = NULL;\r
+        sprintf(tmpstr2, "spr_%d", i2);\r
+        p = find_datafile_object_type(krapmain, get_config_string(tmpstr, tmpstr2, "null"), DAT_BITMAP);\r
+        // intentar con spr, si no existe spr_0\r
+        if (i2 == 0 && p == NULL) p = find_datafile_object_type(krapmain, get_config_string(tmpstr, "spr", "null"), DAT_BITMAP);\r
+        // cuando es el primer sprite, se obvia si no existe, en caso contrario, el resto se asigna al primero\r
+        if (p != NULL)\r
+          { enem_t[i].spr[i2] = (BITMAP *)p->dat; }\r
+          else\r
+          {\r
+          if (i2 == 0)\r
+            { enem_t[i].spr[i2] = NULL; } // no hay sprite inicial\r
+            else\r
+            { enem_t[i].spr[i2] = enem_t[i].spr[0]; } // si no existe, tomo el primero\r
+          }\r
+\r
+        enem_t[i].mask[i2] = NULL;\r
+        if (enem_t[i].spr[i2] != NULL) /* sombra y mascara de colision */\r
+           {\r
+            enem_t[i].spr_shadow[i2] = create_bitmap(enem_t[i].spr[i2]->w  * 0.8, enem_t[i].spr[i2]->h  * 0.8);\r
+            hacer_sombra(enem_t[i].spr[i2] , enem_t[i].spr_shadow[i2]); // sombra\r
+            enem_t[i].mask[i2] = create_allegro_pmask(enem_t[i].spr[i2]); // mascara de colision\r
+           }\r
+      }\r
+\r
+        /*------ Seccion ARMA_n ------*/\r
+        sprintf(tmpstr,"ARMA_%d", i);\r
+\r
+        arma_ene[i].spr = NULL;\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "spr", "null"), DAT_BITMAP);\r
+        if (p != NULL) arma_ene[i].spr = (BITMAP *)p->dat;\r
+\r
+        arma_ene[i].mask = NULL;\r
+\r
+        if (arma_ene[i].spr != NULL)\r
+             {\r
+                arma_ene[i].mask = create_allegro_pmask(arma_ene[i].spr);\r
+             }\r
+\r
+        arma_ene[i].snd[0] = NULL;\r
+        arma_ene[i].snd[1] = NULL;\r
+\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "snd_0", "null"), DAT_SAMPLE);\r
+        if (p != NULL)\r
+        {\r
+            arma_ene[i].snd[0] = (SAMPLE *)p->dat;\r
+            arma_ene[i].snd[0]->priority = 100; /* prioridad  */\r
+        }\r
+\r
+        p = find_datafile_object_type(krapmain,  get_config_string(tmpstr, "snd_1", "null"), DAT_SAMPLE);\r
+        if (p != NULL)\r
+        {\r
+            arma_ene[i].snd[1] = (SAMPLE *)p->dat;\r
+            arma_ene[i].snd[1]->priority = 40; /* prioridad  */\r
+        }\r
+\r
+        arma_ene[i].vx = ftofix(get_config_float(tmpstr,"vx", 0.0));\r
+        arma_ene[i].vy = ftofix(get_config_float(tmpstr,"vy", 0.0));\r
+        arma_ene[i].vida = get_config_int(tmpstr,"vida", -1);\r
+        arma_ene[i].punch = get_config_int(tmpstr,"punch", 0);\r
+        arma_ene[i].t = get_config_int(tmpstr,"t", 0);\r
+\r
+        /* Estela del disparo... */\r
+        arma_ene[i].est_vida[0] = get_config_int(tmpstr, "est_vida_min", 0);\r
+        arma_ene[i].est_vida[1] = get_config_int(tmpstr, "est_vida_max", 0);\r
+        arma_ene[i].est_cant[0] = get_config_int(tmpstr, "est_cant_min", 0);\r
+        arma_ene[i].est_cant[1] = get_config_int(tmpstr, "est_cant_max", 0);\r
+\r
+        arma_ene[i].est_color[0][0] = get_config_int(tmpstr, "est_color_r_min", 0);\r
+        arma_ene[i].est_color[0][1] = get_config_int(tmpstr, "est_color_r_max", 0);\r
+        arma_ene[i].est_color[1][0] = get_config_int(tmpstr, "est_color_g_min", 0);\r
+        arma_ene[i].est_color[1][1] = get_config_int(tmpstr, "est_color_g_max", 0);\r
+        arma_ene[i].est_color[2][0] = get_config_int(tmpstr, "est_color_b_min", 0);\r
+        arma_ene[i].est_color[2][1] = get_config_int(tmpstr, "est_color_b_max", 0);\r
+\r
+        arma_ene[i].est_dx[0] = get_config_int(tmpstr, "est_dx_min", 100);\r
+        arma_ene[i].est_dx[1] = get_config_int(tmpstr, "est_dx_max", 100);\r
+\r
+        arma_ene[i].est_dy[0] = get_config_int(tmpstr, "est_dy_min", 0);\r
+        arma_ene[i].est_dy[1] = get_config_int(tmpstr, "est_dy_max", 0);\r
+\r
+        arma_ene[i].est_tipo[0] = get_config_int(tmpstr, "est_tipo_min", 0);\r
+        arma_ene[i].est_tipo[1] = get_config_int(tmpstr, "est_tipo_max", 0);\r
+\r
+       arma_ene[i].est_rad[0] = get_config_int(tmpstr, "est_rad_min", 1);\r
+       arma_ene[i].est_rad[1] = get_config_int(tmpstr, "est_rad_max", 2);\r
+\r
+       arma_ene[i].est_transp = get_config_int(tmpstr, "est_transp", 0);\r
+        \r
+       }\r
+\r
+   // Fondo del shopping\r
+     p = find_datafile_object_type(krapmain, "shop_bmp", DAT_BITMAP);\r
+     if (p == NULL)\r
+        shop_bmp = NULL;\r
+     else\r
+        shop_bmp = (BITMAP *)p->dat;\r
+\r
+\r
+   /* cargar los items del menu principal  */\r
+       if (datmenu != NULL) unload_datafile(datmenu);\r
+       gui_bg_color = makecol(0,0,0);  gui_fg_color = makecol(255,255,255); // colores para la info de carga\r
+       datmenu = krono_load_datafile_callback("krapmnu.dat", cargar_callback);\r
+       if (datmenu == NULL)  levantar_error("ERROR: no se pudo abrir 'krapmnu.dat'");\r
+\r
+       /* paleta de colores */\r
+       p = find_datafile_object(datmenu, "main_menu_pal");\r
+       if (p == NULL) levantar_error("ERROR: no se pudo obtener 'main_menu_pal'");\r
+    \r
+           /* copiar la paleta a RAM ... */\r
+           memcpy(pal_menu_main, p->dat, sizeof(PALETTE));\r
+\r
+       /* cargar archivo de ayuda (texto) */\r
+       p = find_datafile_object(datmenu, "help_txt");\r
+       if (p == NULL)\r
+         { texto_ayuda_juego = NULL; }\r
+        else\r
+         {\r
+          texto_ayuda_juego = (char *)p->dat;\r
+          /* esto es necesario, sino, no tiene fin la cadena! */\r
+          texto_ayuda_juego[p->size - 1] = '\0';\r
+         }\r
+\r
+       /* acerca de... */\r
+       p = find_datafile_object(datmenu, "about_txt");\r
+       if (p == NULL)\r
+         { texto_acerca_de_juego = NULL; }\r
+        else\r
+         {\r
+          texto_acerca_de_juego = (char *)p->dat;\r
+          /* esto es necesario, sino, no tiene fin la cadena! */\r
+          texto_acerca_de_juego[p->size - 1] = '\0';\r
+         }\r
+\r
+       /* imagen de acerca de... */\r
+       p = find_datafile_object_type(datmenu, "about_bmp", DAT_BITMAP);\r
+       if (p == NULL) \r
+             acerca_de_bmp  = NULL;\r
+       else\r
+            acerca_de_bmp = (BITMAP *)p->dat; \r
+\r
+       /* cargo el bitmap de fondo */\r
+       p = find_datafile_object_type(datmenu, "main_menu_bmp", DAT_BITMAP);\r
+       if (p == NULL)  levantar_error("ERROR: no existe 'main_menu_bmp' en 'krapmnu.dat'");\r
+    \r
+       bmp_menu_main = (BITMAP *)p->dat; \r
+\r
+   /* fin de los items del menu */\r
+\r
+   /* DEBUG: en caso necesario agregar mas datos necesarios aqui */\r
+\r
+}\r
+\r
+\r
+/*\r
+    Esta funcion puede hacer 2 cosas:\r
+    - verificar si el proximo nivel existe\r
+    - o verificar si existe y cargar el nivel especificado en RAM\r
+\r
+    parametros:\r
+    nivel => nivel a cargar\r
+    solo_verificar => 0 indica que cargue el nivel en RAM,\r
+                      -1 que solo verifique\r
+                      SIEMPRE son cargados los datos basicos del nivel (cinematicas, titulo)\r
+\r
+    devuelve 0 si funciona, -1 si falla (el nivel no existe, o el archivo no existe)\r
+\r
+    SI SE VA A CARGAR EL NIVEL:\r
+    MUESTRA UN MENSAJE DE CARGA EN PANTALLA! [ESQUINA SUP-IZQ]\r
+\r
+    Nota: grilla de nivel/enemigos se guarda en enteros Intel 32 bits, para zafar en\r
+    todas las plataformas\r
+*/\r
+int cargar_nivel(int nivel, int solo_verificar)\r
+{\r
+   DATAFILE *p = NULL; /* puntero de busqueda */\r
+   PACKFILE *fp; // para leer las grillas\r
+   int xx, yy; // para leer las grillas\r
+   char tmpstr[1024]; // uso general\r
+   char tmpstr2[1024];\r
+   \r
+   if (krapmain == NULL) return -1;\r
+\r
+   p = find_datafile_object(krapmain, "gamescript");\r
+   if (p == NULL) levantar_error("ERROR: el gamescript no esta definido en krapmain.dat");\r
+\r
+   set_config_data((char *)p->dat, p->size);\r
+\r
+   sprintf(tmpstr,"nivel_%d", nivel);\r
+\r
+   /* cargar siempre la info basica del nivel... (si no, las cinematicas no andan! )*/\r
+   sprintf(info_nivel.level_dat, "%s", get_config_string(tmpstr, "level_dat", "null"));\r
+   sprintf(info_nivel.cine_in, "%s", get_config_string(tmpstr, "cine_in", "null"));\r
+   sprintf(info_nivel.cine_out, "%s", get_config_string(tmpstr, "cine_out", "null"));\r
+   sprintf(info_nivel.texto, "%s", get_config_string(tmpstr, "texto", "null"));\r
+   sprintf(info_nivel.titulo, "%s", get_config_string(tmpstr, "titulo", "null"));\r
+   info_nivel.clima_c = get_config_int(tmpstr, "clima_c", 0);\r
+   info_nivel.clima_t = get_config_int(tmpstr, "clima_t", 0);\r
+   info_nivel.clima_d = get_config_int(tmpstr, "clima_d", 0);\r
+\r
+   info_nivel.musica = NULL; /* por ahora, no se si hay musica... */\r
+\r
+   /* Debo SOLO verificar si el nivel existe? */\r
+   if (solo_verificar) return !exists(info_nivel.level_dat);\r
+\r
+   /* ------ Cargar realmente en RAM el archivo...  ------ */\r
+\r
+   /* colores para el callback que muestra el progreso de la carga */\r
+   gui_fg_color = makecol(255,255,255);\r
+   gui_bg_color = makecol(0,0,0);\r
+   byte_acumulado = 0; /* contador para mostrar progreso */\r
+\r
+   if (datmapa != NULL)\r
+    {\r
+         unload_datafile(datmapa);\r
+         datmapa = NULL;\r
+    }\r
+   gui_bg_color = makecol(0,0,0);  gui_fg_color = makecol(255,255,255); // colores para la info de carga\r
+   datmapa = krono_load_datafile_callback(info_nivel.level_dat, cargar_callback);\r
+   if (datmapa == NULL) return -1; /* fallo la carga del nivel */\r
+\r
+   /* copiarse las grillas */\r
+   sprintf(tmpstr2, "%s#mapa_g", info_nivel.level_dat); // cargar el mapa_g\r
+   fp = pack_fopen(tmpstr2, F_READ);\r
+   if (fp == NULL) levantar_error("ERROR: no existe mapa_g en el nivel!");\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                  mapa_g[xx][yy] = pack_igetl(fp);\r
+                  \r
+         pack_fclose(fp);\r
+   \r
+// grilla de enemigos, con soporte para varias dificultades\r
+   sprintf(tmpstr2, "%s#enem_g_%d", info_nivel.level_dat, nivel_de_dificultad);\r
+   fp = pack_fopen(tmpstr2, F_READ);\r
+   if (fp == NULL)\r
+       {\r
+        sprintf(tmpstr2, "%s#enem_g", info_nivel.level_dat );\r
+        fp = pack_fopen(tmpstr2, F_READ);\r
+        if (fp == NULL) levantar_error("ERROR: no existe enem_g en el nivel!");\r
+       }\r
+\r
+          for (xx =0; xx < W_FONDO / W_GR; xx++)\r
+          for (yy =0; yy < H_FONDO / H_GR; yy++)\r
+                 enem_g[xx][yy] = pack_igetl(fp);\r
+                  \r
+         pack_fclose(fp);\r
+\r
+   /* obtener el fondo y ajustar dimensiones en un mapa nuevo...\r
+      esto ayuda a conservar espacio en disco,\r
+      para demos, permitiendo usar un fondo mas chico en disco! */\r
+\r
+   p = find_datafile_object(datmapa, "mapa_fondo");\r
+   if (p == NULL) levantar_error("ERROR: no existe mapa_fondo en el nivel!");\r
+\r
+   mapa_fondo = create_bitmap(W_FONDO, H_FONDO); /* acordarse de liberar esto luego... en game.c */\r
+\r
+   if (mapa_fondo == NULL) levantar_error("ERROR: data.c:cargar_nivel()\nInsuficiente memoria RAM para cargar el mapa del nivel!\n(~2.3MB requeridos!)");\r
+\r
+   stretch_blit((BITMAP *)p->dat, mapa_fondo, 0, 0,\r
+                 ((BITMAP *)p->dat)->w, ((BITMAP *)p->dat)->h,\r
+                 0, 0,\r
+                 mapa_fondo->w, mapa_fondo->h);\r
+\r
+  /* Tomo la musica del juego */\r
+  info_nivel.musica = NULL;\r
+  p = find_datafile_object(datmapa, "musica");\r
+  if (p != NULL)  info_nivel.musica = (DUH *)p->dat;\r
+\r
+   return 0; /* Todo bien, negrita... */\r
+}\r
+\r
+#endif\r
diff --git a/src/datafind.c b/src/datafind.c
new file mode 100644 (file)
index 0000000..c5fa192
--- /dev/null
@@ -0,0 +1,182 @@
+// -------------------------------------------------------- \r
+// datafind.c\r
+// Funciones de busqueda avanzada de objetos dentro de un archivo DAT\r
+// -------------------------------------------------------- \r
+// Copyright (c) 2002, Kronoman\r
+// Escrito por Kronoman - Republica Argentina\r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Funcion para buscar un objeto en un datafile.\r
+// Busca primero el verdadero, si no existe, busca por aproximacion!!!\r
+// COOL!\r
+// --------------------------------------------------------\r
+\r
+#ifndef _KRONO_DATAFIND_C\r
+#define _KRONO_DATAFIND_C\r
+\r
+#include <allegro.h>\r
+#include "datafind.h"\r
+\r
+// --------------------------------------------------------\r
+// fuzzy_find_datafile_object\r
+// Busca un objeto por nombre aproximado en un archivo DAT\r
+// basado en el codigo de allegro en el archivo datafile.c\r
+// IGNORA MAYUSCULAS/MINUSCULAS\r
+// IGNORA TIPO DE OBJETO (puede devolver cualquier tipo)\r
+// --------------------------------------------------------\r
+DATAFILE *fuzzy_find_datafile_object(AL_CONST DATAFILE *dat, AL_CONST char *objectname)\r
+{\r
+   char name[512];\r
+   char name2[512];\r
+   int recurse = FALSE;\r
+   int pos, c;\r
+\r
+\r
+   // primero ver si hay un archivo con el mismo nombre en la manera estandard\r
+//   DATAFILE *tmp = find_datafile_object(dat, objectname); // debug\r
+//   if (tmp != NULL) return tmp;\r
+   \r
+\r
+   // sacar el nombre de archivo\r
+   pos = 0;\r
+\r
+   while ((c = ugetxc(&objectname)) != 0) {\r
+      if ((c == '#') || (c == '/') || (c == OTHER_PATH_SEPARATOR)) {\r
+        recurse = TRUE;\r
+        break;\r
+      }\r
+      pos += usetc(name+pos, c);\r
+   }\r
+\r
+   usetc(name+pos, 0);\r
+\r
+   ustrupr(name); // pasar a mayusculas\r
+\r
+   // buscar el objeto pedido  (busca nombre aproximado)\r
+   for (pos=0; dat[pos].type != DAT_END; pos++) {\r
+         // obtener nombre y pasarlo a mayusculas\r
+         ustrcpy(name2, get_datafile_property(dat+pos, DAT_NAME) );\r
+         ustrupr(name2);\r
+\r
+      if (ustrstr( name2 , name  ) == NULL) {\r
+        if (recurse) {\r
+             if (dat[pos].type == DAT_FILE)\r
+              return fuzzy_find_datafile_object(dat[pos].dat, objectname);\r
+                   else\r
+              return NULL;\r
+           }\r
+          }\r
+        else\r
+           return (DATAFILE*)dat+pos; // lo encontro\r
+   }\r
+\r
+   // el objeto no esta... shit!\r
+   return NULL; \r
+}\r
+\r
+// --------------------------------------------------------\r
+// find_datafile_object_type\r
+// busca un objeto en un datafile del tipo requerido\r
+// en type_required pasar el tipo, ejemplo: DAT_BITMAP\r
+// --------------------------------------------------------\r
+DATAFILE *find_datafile_object_type(AL_CONST DATAFILE *dat, AL_CONST char *objectname, int type_required)\r
+{\r
+   char name[512];\r
+   int recurse = FALSE;\r
+   int pos, c;\r
+\r
+   // obtener el nombre de archivo\r
+   pos = 0;\r
+\r
+   while ((c = ugetxc(&objectname)) != 0) {\r
+      if ((c == '#') || (c == '/') || (c == OTHER_PATH_SEPARATOR)) {\r
+        recurse = TRUE;\r
+        break;\r
+      }\r
+      pos += usetc(name+pos, c);\r
+   }\r
+\r
+   usetc(name+pos, 0);\r
+\r
+   // buscar el objeto \r
+   for (pos=0; dat[pos].type != DAT_END; pos++) {\r
+      if (ustricmp(name, get_datafile_property(dat+pos, DAT_NAME)) == 0) {\r
+        if (recurse) {\r
+           if (dat[pos].type == DAT_FILE)\r
+           return find_datafile_object_type(dat[pos].dat, objectname, type_required);\r
+           else\r
+              return NULL;\r
+        }\r
+        else\r
+        if (dat[pos].type == type_required) return (DATAFILE*)dat+pos; // lo encontro\r
+      }\r
+   }\r
+\r
+   // no esta, shit...\r
+   return NULL; \r
+}\r
+\r
+\r
+\r
+// --------------------------------------------------------\r
+// fuzzy_find_datafile_object_type\r
+// Busca un objeto por nombre aproximado en un archivo DAT\r
+// basado en el codigo de allegro en el archivo datafile.c\r
+// IGNORA MAYUSCULAS/MINUSCULAS\r
+// NO IGNORA TIPO DE OBJETO\r
+// Pasar en type_required el tipo de objeto; ej: DAT_BITMAP\r
+// --------------------------------------------------------\r
+DATAFILE *fuzzy_find_datafile_object_type(AL_CONST DATAFILE *dat, AL_CONST char *objectname, int type_required)\r
+{\r
+   char name[512];\r
+   char name2[512];\r
+   int recurse = FALSE;\r
+   int pos, c;\r
+\r
+\r
+   // primero ver si hay un archivo con el mismo nombre en la manera estandard\r
+//   DATAFILE *tmp = find_datafile_object_type(dat, objectname, type_required);\r
+//   if (tmp != NULL) return tmp;\r
+   \r
+\r
+   // sacar el nombre de archivo\r
+   pos = 0;\r
+\r
+   while ((c = ugetxc(&objectname)) != 0) {\r
+      if ((c == '#') || (c == '/') || (c == OTHER_PATH_SEPARATOR)) {\r
+        recurse = TRUE;\r
+        break;\r
+      }\r
+      pos += usetc(name+pos, c);\r
+   }\r
+\r
+   usetc(name+pos, 0);\r
+\r
+   ustrupr(name); // pasar a mayusculas\r
+\r
+   // buscar el objeto pedido  (busca nombre aproximado)\r
+   // se fija si el objeto coincide con el tipo requerido\r
+\r
+   for (pos=0; dat[pos].type != DAT_END; pos++) {\r
+         // obtener nombre y pasarlo a mayusculas\r
+         ustrcpy(name2, get_datafile_property(dat+pos, DAT_NAME) );\r
+         ustrupr(name2);\r
+\r
+      if (ustrstr( name2 , name  ) == NULL) {\r
+        if (recurse) {\r
+             if (dat[pos].type == DAT_FILE)\r
+              return fuzzy_find_datafile_object_type(dat[pos].dat, objectname, type_required);\r
+                   else\r
+              return NULL;\r
+           }\r
+          }\r
+        else\r
+        if (dat[pos].type == type_required ) return (DATAFILE*)dat+pos; // lo encontro\r
+   }\r
+\r
+   // el objeto no esta... shit!\r
+   return NULL; \r
+}\r
+\r
+\r
+#endif\r
diff --git a/src/enemigo.c b/src/enemigo.c
new file mode 100644 (file)
index 0000000..80e9ead
--- /dev/null
@@ -0,0 +1,675 @@
+// --------------------------------------------------------\r
+// enemigo.c\r
+// -------------------------------------------------------- \r
+// Copyright (c) Kronoman \r
+// En memoria de mi querido padre \r
+// -------------------------------------------------------- \r
+// Este modulo contiene todo lo relacionado con los enemigos\r
+// Tal como movimiento, disparos, etc...\r
+// -------------------------------------------------------- \r
+#ifndef ENEMIGO_C\r
+#define ENEMIGO_C\r
+\r
+#include <stdio.h>\r
+#include "allegro.h"\r
+#include "pmask.h"\r
+#include "azar.h"\r
+#include "enemigo.h"\r
+#include "kfbuffer.h"\r
+#include "jugador.h" /* lo preciso para poder verificar\r
+                        los disparos contra el jugador... jeje */\r
+#include "sombras.h"\r
+#include "combo.h"\r
+#include "partic.h"\r
+#include "global.h"\r
+#include "sonido.h"\r
+#include "bomba.h"\r
+#include "ia.h"\r
+#include "premio.h"\r
+#include "error.h"\r
+/* GLOBALES */\r
+ARMA_ENE arma_ene[MAX_E_CLASS]; /* armamento enemigo */\r
+ENEM_T enem_t[MAX_E_CLASS]; /* tipos de enemigos */\r
+ENEMIGO *enemigo_1 = NULL; /* puntero al 1er enemigo activo */\r
+DISP_ENE *disp_ene_1 = NULL; /* puntero al 1er disparo activo */\r
+\r
+/* esta variable NO es necesaria, solo la uso para\r
+   ver cuantos enemigos hay en memoria, y de esa manera,\r
+   revisar la performance... */\r
+int cant_enemigos_debug = 0;\r
+\r
+/* Agrega un enemigo en x, y de tipo 'tipo' */\r
+void agregar_enemigo(int x, int y, int tipo )\r
+{\r
+    ENEMIGO *nueva = malloc(sizeof(ENEMIGO));\r
+    nueva->next = enemigo_1;\r
+    enemigo_1 = nueva;\r
+\r
+    if (nueva != NULL) /* si el malloc funciono, seteo los datos... */\r
+    {\r
+        nueva->x = itofix(x);\r
+        nueva->y = itofix(y);\r
+        nueva->vida = enem_t[tipo].vida; /* que corta es la vida de un piloto enemigo... */\r
+        nueva->ene_t = tipo; /* que somos? yankis gallinas o pilotos de verdad? */\r
+        // resetear la IA\r
+        nueva->bytecode_actual = -1; // aun no ejecute nada, por eso -1\r
+        nueva->bytecode_loop = 0; // empezar con la 1era instruccion\r
+\r
+        nueva->ia_node = enem_t[tipo].ia_node;\r
+        // debo comenzar la IA en un punto al azar?\r
+        if (enem_t[tipo].ia_azar != 0) nueva->bytecode_actual = rand_ex(-1, nueva->ia_node->size-1);\r
+        \r
+        // animaciones, etc...\r
+        nueva->spr_actual = rand()%4;\r
+        nueva->spr_delay = 0;\r
+    }\r
+}\r
+\r
+/* Esta funcion altera la IA del enemigo\r
+   llamar en cada ciclo...\r
+   */\r
+void IA_enemigo(ENEMIGO *ene) \r
+{\r
+    \r
+// interpretar bytecodes de la IA\r
+if (ene->ia_node == NULL) return; // no tiene IA, descerebrado...\r
+if (ene->ia_node->size < 1) return; // IA vacia, que paso?\r
+    \r
+ene->bytecode_loop--; // ejecute 1 instruccion\r
+\r
+\r
+if (ene->bytecode_loop < 0)\r
+   {\r
+    // proxima instruccion\r
+    ene->bytecode_actual ++;\r
+    if (ene->bytecode_actual > ene->ia_node->size - 1) ene->bytecode_actual = 0;\r
+    if (ene->bytecode_actual > ene->ia_node->size-1) return; // seguridad... :)\r
+    ene->bytecode_loop = ene->ia_node->code[ene->bytecode_actual].loop;\r
+\r
+    // copiar bytecode, solo campos importantes... el resto indeterminados... :)\r
+    ene->bytecode_exe.x1 = rand_ex(ene->ia_node->code[ene->bytecode_actual].x1, ene->ia_node->code[ene->bytecode_actual].x2);\r
+    ene->bytecode_exe.y1 = rand_ex(ene->ia_node->code[ene->bytecode_actual].y1, ene->ia_node->code[ene->bytecode_actual].y2);\r
+\r
+   }\r
+\r
+   \r
+if (ene->bytecode_actual > ene->ia_node->size-1) return; // seguridad... :)\r
+    \r
+   // mover enemigo\r
+   ene->x = fixadd(ene->x, itofix(ene->bytecode_exe.x1));\r
+   ene->y = fixadd(ene->y, itofix(ene->bytecode_exe.y1));\r
+\r
+\r
+        /* debo disparar ? */\r
+        if (ene->ia_node->code[ene->bytecode_actual].weapon > -1)\r
+        {\r
+            // cambio de arma del enemigo\r
+            ene->arma_actual = ene->ia_node->code[ene->bytecode_actual].weapon;\r
+            // disparar\r
+            agregar_disparo_ene(ene);\r
+        }\r
+\r
+\r
+}\r
+\r
+\r
+/*\r
+   Esta funcion actualiza los enemigos\r
+   Verifica colisiones con disparos de jugador y con el jugador mismo\r
+   Precisa saber el desplazamiento del fondo, 'fy' ya que\r
+   cuando el enemigo sale de pantalla, se elimina...\r
+   */\r
+void mover_enemigos(int fy)\r
+{\r
+    ENEMIGO **tmp_p = &enemigo_1;\r
+    DISP_JUG *tmpd = NULL;\r
+    ENEMIGO *tmp = NULL;\r
+\r
+    cant_enemigos_debug = 0; /* DEBUG: innecesario */\r
+\r
+    while (*tmp_p) {\r
+\r
+        cant_enemigos_debug++; /* DEBUG: innecesario */\r
+\r
+        tmp = *tmp_p;\r
+          /* hacer IA del enemigo */\r
+            IA_enemigo(tmp);\r
+\r
+        // animacion del enemigo\r
+        tmp->spr_delay--;\r
+        if (tmp->spr_delay < 0)\r
+            {\r
+             tmp->spr_delay = enem_t[tmp->ene_t].spr_delay; // reiniciar contador\r
+             tmp->spr_actual++; // cambiar sprite\r
+             if (tmp->spr_actual > 3) tmp->spr_actual = 0;\r
+            }\r
+\r
+\r
+          /* verificar colisiones... */\r
+\r
+          /* colision contra el jugador? */\r
+          if (check_pmask_collision(enem_t[tmp->ene_t].mask[tmp->spr_actual], jugador.mask,\r
+                                    fixtoi(tmp->x), fixtoi(tmp->y),\r
+                                    fixtoi(jugador.x), fixtoi(jugador.y) ) != 0)\r
+                                    {\r
+            /* DEBUG: choco al jugador!, falta sonido! */\r
+\r
+          pone_explo_pixel(&ptr_explo_arriba,\r
+                           fixtoi(tmp->x)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w,\r
+                           fixtoi(tmp->y)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->h,\r
+                           rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w+enem_t[tmp->ene_t].spr[tmp->spr_actual]->w/3,\r
+                           rand()%30+20,\r
+                           ftofix(0.01));\r
+\r
+            jugador.vida -= enem_t[tmp->ene_t].peso + rand()%5; /* restar energia al jugador */\r
+            tmp->vida -= rand()%5 + 5;  /* restarme energia tambien */\r
+          };\r
+\r
+          /* loop:\r
+             recorrer disparos del jugador\r
+             DEBUG: esto es muy lento!! */\r
+\r
+          tmpd = disp_jug_1;\r
+          while (tmpd) {\r
+                /* chequear colision, solo si el disparo esta activo,\r
+                   de la manera hecha siguiente, si el disparo esta muerto,\r
+                   evito comprobar la mascara, que tarda mas...*/\r
+\r
+                  if ( tmpd->vida > 0)\r
+                  if (check_pmask_collision(enem_t[tmp->ene_t].mask[tmp->spr_actual], arma_tipo[tmpd->arma].mask,\r
+                                            fixtoi(tmp->x), fixtoi(tmp->y),\r
+                                            fixtoi(tmpd->x), fixtoi(tmpd->y) ) != 0 )\r
+                                            {\r
+\r
+                    /* DEBUG: choco al disparo del jugador, restar energia, etc! */\r
+                    poner_explosion_nave(fixtoi(tmpd->x),\r
+                                         fixtoi(tmpd->y),\r
+                                         rand()%20+20, rand()%10+5+arma_tipo[tmpd->arma].punch*2, 0);\r
+\r
+                    /* DEBUG: sonido del arma\r
+                              del jugador pegandole al enemigo */\r
+                    tocar_sonido_paneado(fixtoi(tmpd->x),\r
+                                         arma_tipo[tmpd->arma].snd[1],\r
+                                         rand_ex(200,255),\r
+                                         rand_ex(900,1100));\r
+\r
+\r
+                    /* Esta comparacion es para NO pagarle mas de una vez al jugador\r
+                       por la muerte... */\r
+                    if (tmp->vida > 0 )\r
+                    {\r
+\r
+                      tmp->vida -= arma_tipo[tmpd->arma].punch; /* restar energia al enemigo */\r
+\r
+                      /* DEBUG: mato al enemigo */\r
+                      if (tmp->vida <= 0)\r
+                      {\r
+                      int ttt;\r
+                      for (ttt=0; ttt < rand()%3 + enem_t[tmp->ene_t].peso/2+1; ttt++)\r
+                         {\r
+                         pone_explo_pixel(&ptr_explo_arriba,\r
+                                          fixtoi(tmp->x)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w,\r
+                                          fixtoi(tmp->y)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->h,\r
+                                          rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w+enem_t[tmp->ene_t].spr[tmp->spr_actual]->w/3,\r
+                                          rand()%30+20,\r
+                                          ftofix(0.01));\r
+                         }\r
+                         // Soltar premio, si lo hubiera... -DEBUG-\r
+                         if ( (enem_t[tmp->ene_t].premio_idx > -1) && (rand()%100+1 < enem_t[tmp->ene_t].premio_prob ) )\r
+                                   agrega_premio(enem_t[tmp->ene_t].premio_idx, tmp->x, tmp->y);\r
+                         \r
+                         // Pagar... \r
+                        jugador.dinero += enem_t[tmp->ene_t].dinero;\r
+                      }\r
+                   } /* fin de no pagar 2 veces */\r
+\r
+                    tmpd->vida = -1; /* eliminar disparo, la memoria\r
+                                        se libera en jugador.c */\r
+                  } /* fin chequear colision */\r
+\r
+                tmpd = tmpd->next; /* siguiente */\r
+\r
+            } /* fin loop de verificar disparos */\r
+\r
+        /* Si esta activa la bomba especial, restar energia progresivamente */\r
+        if (bomba_esta_activa && tmp->vida > 0)\r
+           {\r
+           tmp->vida -= rand()%10+5;\r
+                   if (tmp->vida < 1)\r
+                   {\r
+                           jugador.dinero += enem_t[tmp->ene_t].dinero; // pagar\r
+                           tmp->vida = -1; // fuerzo que se 'combustione' completamente\r
+                   }\r
+           }\r
+\r
+        /* Ir combustionando el enemigo cuando muere (energia <= 0) */\r
+        if (tmp->vida <= 0 )\r
+           {\r
+                 tmp->vida -= rand()%10+10;\r
+\r
+\r
+                 /* Explosiones peque~as */\r
+                 if (rand()%150 < abs((tmp->vida * 100) / ENE_MUERTO) ) /* incremental al irse combustionando */\r
+                 {\r
+                    /* sonido */\r
+                    if (rand()%10 < 5)\r
+                            {\r
+                             tocar_sonido_paneado(fixtoi(tmp->x),\r
+                                                  explo_cache_snd[rand()%3],\r
+                                                  rand_ex(128,255),\r
+                                                  rand_ex(900, 1000));\r
+                            }\r
+\r
+                     pone_explo_pixel(&ptr_explo_arriba,\r
+                                      fixtoi(tmp->x)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w,\r
+                                      fixtoi(tmp->y)+rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->h,\r
+                                      rand()%enem_t[tmp->ene_t].spr[tmp->spr_actual]->w+enem_t[tmp->ene_t].spr[tmp->spr_actual]->w/3,\r
+                                      rand()%30+10,\r
+                                      ftofix(0.01));\r
+    \r
+                    /* Descontrolar enemigo */\r
+                    // tmp->dx = (rand()%100 < 50) ? ftofix(MAX_VEL_E_X * (-1.0)) : ftofix(MAX_VEL_E_X);\r
+                    // tmp->dy = (rand()%100 < 50) ? ftofix(MAX_VEL_E_Y * (-1.0)) : ftofix(MAX_VEL_E_Y);\r
+                }\r
+    \r
+                /* al aproximarse al final, recontra-explotar... */\r
+                if (tmp->vida < (ENE_MUERTO / 10)*9  && nivel_detalle > 4)\r
+                            {\r
+                                pone_explo_pixel(&ptr_explo_arriba,\r
+                                                  fixtoi(tmp->x)+enem_t[tmp->ene_t].spr[tmp->spr_actual]->w/2,\r
+                                                  fixtoi(tmp->y)+enem_t[tmp->ene_t].spr[tmp->spr_actual]->h/2,\r
+                                                  enem_t[tmp->ene_t].spr[tmp->spr_actual]->w+rand()%10,\r
+                                                  rand()%10+10,\r
+                                                  ftofix(0.01));\r
+\r
+                                 /* PARTICULAS Y PEDAZOS DE NAVES AL MORIR... */\r
+                                if (tmp->vida-10 <= ENE_MUERTO)\r
+                                        poner_explosion_nave(fixtoi(tmp->x)+enem_t[tmp->ene_t].spr[tmp->spr_actual]->w/2,\r
+                                                             fixtoi(tmp->y)+enem_t[tmp->ene_t].spr[tmp->spr_actual]->h/2,\r
+                                                             rand()%20+20,\r
+                                                             rand()%10+5, -1);\r
+                             }\r
+           } /* fin combustionar */\r
+\r
+\r
+          /* verificar limites de pantalla visible */\r
+          /* nota: la IA rebota en las X, queda cool. */\r
+          if (tmp->x < 0) { tmp->x = 0; tmp->bytecode_exe.x1 *= -1; }\r
+\r
+          if (fixtoi(tmp->x) > ANCHO_FB - enem_t[tmp->ene_t].spr[tmp->spr_actual]->w )\r
+                  {\r
+                    tmp->x = itofix(ANCHO_FB - enem_t[tmp->ene_t].spr[tmp->spr_actual]->w);\r
+                    tmp->bytecode_exe.x1 *= -1; \r
+                  }\r
+\r
+          if (fixtoi(tmp->y) < fy - (enem_t[tmp->ene_t].spr[tmp->spr_actual]->h*2)) tmp->y = itofix(fy - (enem_t[tmp->ene_t].spr[tmp->spr_actual]->h*2));\r
+    \r
+          if (fixtoi(tmp->y) < fy )\r
+             {\r
+               tmp->y = itofix(fy+2); /* DEBUG: mejorar esto para que no 'salte' desde arriba de pantalla! */\r
+               tmp->bytecode_exe.y1 *= -1;\r
+             }\r
+\r
+         // es un BOSS, no pasar de 2/3 de pantalla?\r
+         if (enem_t[tmp->ene_t].ia_boss)\r
+         {\r
+           if (fixtoi(tmp->y)+enem_t[tmp->ene_t].spr[tmp->spr_actual]->h > (fy+ALTO_FB) / 3 * 2 )\r
+           {\r
+                   tmp->y = itofix((fy+ALTO_FB) / 3 * 2 - enem_t[tmp->ene_t].spr[tmp->spr_actual]->h);\r
+                   tmp->bytecode_exe.y1 *= -1;\r
+           }\r
+         }\r
+         else\r
+         {  // desaparecer al salir por abajo\r
+            if (fixtoi(tmp->y) > fy + ALTO_FB*1.05) tmp->vida = ENE_MUERTO; \r
+         }\r
+\r
+        /* Verificacion para ir limpiando la lista de enemigos muertos */\r
+        if (tmp->vida <= ENE_MUERTO) {\r
+          /* murio, eliminar y pasar al siguiente!!! */\r
+          *tmp_p = tmp->next;\r
+          free(tmp);\r
+        } else {\r
+            tmp_p = &tmp->next; /* nadie murio, siguiente por favor! */\r
+        }\r
+    } /* fin loop recorrer enemigos */\r
+}\r
+\r
+/*\r
+   Esta funcion dibuja los enemigos en\r
+   el bitmap, desplazado x,y,\r
+   dibuja tambien una sombra que se desplaza\r
+   en relacion al borde inferior del bitmap y el centro y del mismo\r
+   de manera de dar un look 3D (como el viejo Rapt*r :^P )\r
+   TIENE que estar seteado el colormap de transparencia\r
+   */\r
+void dibujar_enemigos(BITMAP *bmp, int x, int y)\r
+{\r
+    ENEMIGO *tmp = enemigo_1;\r
+\r
+    while (tmp) {\r
+\r
+\r
+       /* Colocar enemigo */\r
+       if (enem_t[tmp->ene_t].spr[tmp->spr_actual] != NULL)\r
+       {\r
+               /* colocar la sombra */\r
+               colocar_sombra(bmp, enem_t[tmp->ene_t].spr_shadow[tmp->spr_actual], fixtoi(tmp->x)-x, fixtoi(tmp->y)-y);\r
+               draw_sprite(bmp, enem_t[tmp->ene_t].spr[tmp->spr_actual], fixtoi(tmp->x)-x, fixtoi(tmp->y)-y);\r
+       }\r
+       else\r
+       {\r
+               char errstr[1024];\r
+               sprintf(errstr, "ERROR: dibujar_enemigos, hay un enemigo sin sprite (clase: %d, sprite: %d)!", tmp->ene_t, tmp->spr_actual);\r
+               levantar_error(errstr);\r
+       }\r
+\r
+\r
+        /* DEBUG: mostrar energia del enemigo */\r
+//        if (KRONO_QUIERE_DEBUG)\r
+//            {\r
+//                text_mode(0);\r
+//                textprintf(bmp, font, fixtoi(tmp->x)-x, fixtoi(tmp->y)-y, makecol(255,255,255), "%d" , tmp->vida);\r
+//            }\r
+\r
+       tmp = tmp->next;\r
+    }\r
+}\r
+\r
+\r
+/* Esta funcion se debe llamar cuando no se precise mas la lista\r
+   Libera la RAM usada y reinicia la lista\r
+   */\r
+void liberar_lista_enemigos() {\r
+    ENEMIGO *tmp = enemigo_1;\r
+    enemigo_1 = NULL;\r
+\r
+    while (tmp) {\r
+        ENEMIGO *next = tmp->next;\r
+        free(tmp);\r
+        tmp = next;\r
+    }\r
+}\r
+\r
+/* ------- DISPAROS DE LOS ENEMIGOS A PARTIR DE AQUI -------- */\r
+\r
+/*\r
+   Esta funcion agrega un disparo a la lista de disparos\r
+   Automaticamente lo agrega usando el arma del enemigo, etc\r
+   Ademas, verifica el timer, y todo lo demas.\r
+   Pasarle el puntero al enemigo que dispara.\r
+*/\r
+void agregar_disparo_ene(ENEMIGO *ene)\r
+{\r
+    int c = 0, i = 0;\r
+\r
+    if (ene->arma_actual < 0) return; /* enemigo desarmado */\r
+\r
+    /* DEBUG:\r
+       EJECUTAR LOS SONIDOS DEL DISPARO  */\r
+    tocar_sonido_paneado(fixtoi(ene->x),\r
+                         arma_ene[ene->arma_actual].snd[0],\r
+                         rand_ex(128, 200),\r
+                         rand_ex(900, 1100));\r
+\r
+\r
+    switch (arma_ene[ene->arma_actual].t)\r
+    {\r
+     case 0:\r
+     case 1:\r
+     case 4:\r
+           c = 1;\r
+     break;\r
+\r
+     case 5:\r
+           c = 5;\r
+     break;\r
+\r
+     case 2:\r
+           c = 3;\r
+      break;\r
+\r
+     case 3:\r
+           c = 2;\r
+      break;\r
+\r
+     case 6:\r
+        c = 4;\r
+     break;\r
+\r
+     case 7:\r
+        c = rand_ex(20, 30);\r
+     break;\r
+          \r
+     case 8:\r
+        c = 20;\r
+     break;\r
+     \r
+     case 9:\r
+       c = rand_ex(20, 30);\r
+     break;\r
+     \r
+     case 10:\r
+       c = rand_ex(5, 30);\r
+     break;\r
+     case 11:\r
+       c = rand_ex(4, 8);\r
+     break;\r
+     \r
+     default:\r
+     /* DEBUG, que paso? */\r
+       c = -1; /* no agregar nada! */\r
+     break;\r
+    }\r
+\r
+ /* Si el tipo de disparo es doble, o triple, realizar el proceso varias veces */\r
+ for (i=0; i<c; i++)\r
+  {\r
+    DISP_ENE *nueva = malloc(sizeof(DISP_ENE));\r
+    nueva->next = disp_ene_1;\r
+    disp_ene_1  = nueva;\r
+\r
+    if (nueva != NULL) /* si el malloc funciono, seteo los datos... */\r
+    {\r
+\r
+     /* Para evitar problemas, lleno todos los valores con defaults primero... */\r
+     /* La 'y' es comun a todos los tipos de disparos */\r
+     nueva->x = fixadd(ene->x, itofix(enem_t[ene->ene_t].spr[ene->spr_actual]->w/2));\r
+     nueva->y = fixadd(ene->y, itofix(enem_t[ene->ene_t].spr[ene->spr_actual]->h/2));\r
+     nueva->dx = arma_ene[ene->arma_actual].vx;\r
+     nueva->dy = arma_ene[ene->arma_actual].vy;\r
+     nueva->arma = ene->arma_actual;\r
+     nueva->vida = arma_ene[nueva->arma].vida;\r
+\r
+     /* Dependiendo del tipo de disparo, setear su posicion */\r
+     switch (arma_ene[nueva->arma].t)\r
+     {\r
+       case 0: /* recto */\r
+           nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+       break;\r
+\r
+       case 1: /* direccion al azar */\r
+       case 6:\r
+       case 7:\r
+           nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+           nueva->dx = ftofix((float)rand_ex(-fixtof(arma_ene[ene->arma_actual].vx)*10.0, fixtof(arma_ene[ene->arma_actual].vx)*10.0) / 10.0);\r
+           if (rand()%100 < 10)  nueva->dx = 0;\r
+\r
+           nueva->dy = fmul(arma_ene[ene->arma_actual].vy, itofix(rand_ex(1, 3)) );\r
+       break;\r
+\r
+       case 2: /* abanico triple */\r
+           nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+           if (i == 0)  nueva->dx = arma_ene[ene->arma_actual].vx;\r
+           if (i == 1)  nueva->dx = 0;\r
+           if (i == 2)  nueva->dx = fixmul(arma_ene[ene->arma_actual].vx, itofix(-1)) ;\r
+           nueva->dy = arma_ene[ene->arma_actual].vy;\r
+       break;\r
+\r
+       case 3: /* doble recto */\r
+           nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+           nueva->dx = arma_ene[ene->arma_actual].vx;\r
+           nueva->dy = arma_ene[ene->arma_actual].vy;\r
+       break;\r
+\r
+       case 4: /* rastreador y en un 10% al azar */\r
+       case 5:\r
+       case 8:\r
+           nueva->x = fixadd(ene->x, itofix(rand()% enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+\r
+           if (jugador.x < ene->x ) // rastrear\r
+            nueva->dx = ftofix((float)rand_ex(-150, 0)/10.0);\r
+           else\r
+            nueva->dx = ftofix((float)rand_ex(0, 150)/10.0);\r
+\r
+           nueva->dy = arma_ene[ene->arma_actual].vy;\r
+\r
+           if (rand()%100 < 15) // cada tanto, al azar\r
+              {\r
+               nueva->dx = ftofix((float)rand_ex(-150, 150) / 10.0);\r
+               nueva->dy = fmul(arma_ene[ene->arma_actual].vy, itofix(rand_ex(1, 3)) );\r
+              }\r
+\r
+       break;\r
+       \r
+       case 9: // en todas direcciones\r
+       case 10:\r
+       case 11:\r
+                  nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+\r
+                if (rand()%100 < 50)\r
+                       nueva->dx = ftofix((float)rand_ex(-fixtoi(arma_ene[ene->arma_actual].vx)*10, 0)/10.0);\r
+                else  \r
+               nueva->dx = ftofix((float)rand_ex(fixtoi(arma_ene[ene->arma_actual].vx)*10,  0)/10.0);          \r
+                  \r
+                if (rand()%100 < 50)\r
+                       nueva->dy = ftofix((float)rand_ex(-fixtoi(arma_ene[ene->arma_actual].vy)*10, -fixtoi(arma_ene[ene->arma_actual].vy)*5 )/10.0);\r
+                else  \r
+               nueva->dy = ftofix((float)rand_ex(fixtoi(arma_ene[ene->arma_actual].vy)*10, fixtoi(arma_ene[ene->arma_actual].vy)*5)/10.0);\r
+       break;\r
+       \r
+       default: /* que paso? */\r
+           nueva->x = fixadd(ene->x, itofix(rand() % enem_t[ene->ene_t].spr[ene->spr_actual]->w));\r
+           nueva->dx = ftofix((float)rand_ex(-150, 150)/10.0);\r
+           nueva->dy = arma_ene[ene->arma_actual].vy;\r
+       break;\r
+\r
+     } // fin switch\r
+    } // fin != null\r
+  } // fin for\r
+};\r
+\r
+/*\r
+  Esta funcion actualiza la logica de los disparos\r
+  y los comprueba contra el jugador\r
+  ademas de remover los&#