Use an absolute directory under /usr/share/games/ for game data
[kraptor.git] / src / ia.c
blobcb7de2cc72e24f40dff033622a3e5e8e84f299e6
1 // --------------------------------------------------------
2 // ia.c
3 // --------------------------------------------------------
4 // Copyright (c) Kronoman
5 // En memoria de mi querido padre
6 // --------------------------------------------------------
7 // Sistema de inteligencia artificial utizando "ejecutables"
8 // binarios contenidos en un DAT
9 // --------------------------------------------------------
11 #include "allegro.h"
12 #include "error.h"
13 #include "ia.h"
14 #include "filedata.h"
16 #include <stdio.h>
18 // Globales
20 // Primer nodo de la lista enlazada
21 static IA_NODE *first_ia_node = NULL;
24 // Busca en la lista enlazada de IAs la que corresponde
25 // al nombre pasado, y devuelve un puntero a ella, o NULL si no se encuentra
26 IA_NODE *buscar_lista_ia(const char *id)
28 IA_NODE *nodo = first_ia_node;
30 // recorrer la lista enlazada
31 while (nodo)
33 if (ustricmp(id, nodo->id) == 0 ) return nodo; // lo encontro
34 nodo = nodo->next;
37 return NULL;
40 // Libera la lista enlazada de la IA
41 void liberar_lista_ia()
43 IA_NODE *nodo = first_ia_node;
44 first_ia_node = NULL;
46 while (nodo)
48 IA_NODE *next = nodo->next;
49 free(nodo->code); // debug, dudoso...
50 free(nodo);
51 nodo = next;
56 // Agrega un nodo de IA a la lista enlazada
57 // Pasarle un puntero al objeto conteniendo el script de IA (nodo nuevo)
58 static void agregar_nodo_ia(DATAFILE *dat)
60 int i;
61 char *p;
62 char tmp[256]; // formacion de token
63 int tok = 0; // posicion en token
64 int params[6],idx = 0; // parametros y parametro leyendo ahora
65 int bytecode_actual = 0; // bytecodes cargados
66 IA_NODE *nodo = NULL; // nodo nuevo
68 p = (char *)dat->dat; //stream de lectura y parsing
70 // alocar RAM para el nodo
71 // nodo
72 nodo = (IA_NODE *)malloc(sizeof(IA_NODE));
73 if (nodo == NULL) levantar_error ("FATAL!: Sin memoria en agregar_nodo_ia()!");
74 nodo->next = first_ia_node;
75 first_ia_node = nodo;
77 // bytecodes en el nodo, y propiedades extra
78 nodo->code = NULL;
80 sprintf(nodo->id, "%s", get_datafile_property(dat, DAT_NAME));
81 tmp[0] = '\0'; tok = 0;
83 for (i=0; i < dat->size; i++)
86 // llego al token?
87 if (p[i] == ',')
89 tmp[tok] = '\0';
90 params[idx] = atoi(tmp);
93 idx++;
94 tok = 0;
95 if (idx == 6) // fin del bytecode
97 idx = 0;
98 if (nodo->code == NULL)
99 nodo->code = malloc(sizeof(IA_BYTECODE));
100 else
101 nodo->code = realloc(nodo->code, sizeof(nodo->code) + sizeof(IA_BYTECODE)*(bytecode_actual+1));
103 // copiar info
104 nodo->code[bytecode_actual].x1 = params[0];
105 nodo->code[bytecode_actual].x2 = params[1];
106 nodo->code[bytecode_actual].y1 = params[2];
107 nodo->code[bytecode_actual].y2 = params[3];
108 nodo->code[bytecode_actual].weapon = params[4];
109 nodo->code[bytecode_actual].loop = params[5];
111 bytecode_actual++; // otro bytecode mas...
114 else
116 tmp[tok] = p[i];
117 tok++;
121 nodo->size = bytecode_actual;
125 // Funcion que hace el cache de la IA en si
126 // Llamar solo al comienzo del juego, pasarle el nombre del archivo DAT a cargar
127 // Si falla, aborta el programa
128 // NOTA: la info de como funciona internamente el grabber, fue tomada de grabber.txt
129 void hacer_chache_ia(const char *file)
131 DATAFILE *tmp = NULL;
132 int pos;
134 tmp = krono_load_datafile(file);
135 if (tmp == NULL ) levantar_error("ERROR: fallo hacer_cache_ia();");
137 // Recorrer todo el archivo, buscando los de tipo IA
138 // DAT_ID es una macro que genera el identificador type (ver grabber.txt y get_datafile_property)
139 for (pos=0; tmp[pos].type != DAT_END; pos++)
141 if (tmp[pos].type == DAT_ID('I','A',' ',' ')) // tiene ID de "IA " ?
143 // encontro objeto en la IA, agregar nodo
144 agregar_nodo_ia((DATAFILE *)tmp+pos);
148 unload_datafile(tmp);