Clean up a little bit.
[runemen.git] / src / runeconf.c
blob9254bfbcba352c7124ab8bcafa71d0ae6519bb08
1 #include <stdio.h>
2 #include <SDL.h>
4 #include "libs/lazyass/lazyass.h"
5 #include "libs/libcsslike/cssdom.h"
7 #include "rune.h"
8 #include "runeconf.h"
9 #include "draw.h"
11 unit_p bunits[MAX_BUNITS];
12 house_p bhouses[MAX_BHOUSES];
14 Uint16 num_bunits;
15 Uint16 num_bhouses;
17 char pseudo_marker[80];
19 char unit_classes[MAX_BUNITS][128];
20 char house_classes[MAX_BHOUSES][128];
22 SDL_Color _white = { 0xff };
24 #define TL_OR_PIX(NAM, MULT) \
25 if (NAM ## U[0] == 't' && NAM ## U[1] == 0) NAM = NAM * MULT; \
26 else if (NAM ## U[0] != 'p' || NAM ## U[1] != 'x' || NAM ## U[2] != 0) { \
27 fprintf(stderr, "Unknown unit '%s', please use 't' or 'px'\n", NAM ## U); \
28 return -1; \
31 /** Houses **/
32 int rcfg_house_count(dom_iter* this, void* ptr) {
34 int i;
35 for (i = 0; i < MAX_BHOUSES; i++) {
36 house_p *housep = &bhouses[i];
39 pseudo_marker[0] = 0;
41 return MAX_BHOUSES;
44 int rcfg_house_pick(dom_iter* this, void* ptr) {
46 house_p *housep = ptr;
48 if (ptr == bhouses) {
49 this->cursor = 0;
52 this->next = (housep+1);
53 this->parent = NULL;
54 this->kids = NULL;
56 if (this->cursor++ > num_bhouses) {
57 this->next = NULL;
60 return 0;
63 char* rcfg_house_test(void *ptr, const char *name) {
64 #define _eq(STR) (!strcasecmp(name, STR))
65 house_p *housep = (house_p *)ptr;
66 int num = (housep - bhouses);
68 if (_eq("type")) return "building";
70 if (_eq("num")) {
71 static char buf[12];
72 snprintf(buf, sizeof(buf), "%d", num);
73 return buf;
76 if (_eq("id")) {
77 return housep->id;
80 if (_eq("class")) {
81 return house_classes[num];
84 return "";
85 #undef _eq
89 int rcfg_house_apply(void *ptr, const char *name, const char *value) {
90 #define _eq(STR) (!strcasecmp(name, STR))
91 #define _veq(STR) (!strcasecmp(value, STR))
92 #define _sveq(STR) (!strcasecmp(subvalue, STR))
94 house_p *housep = ptr;
95 int num = (housep - bhouses);
97 //printf(" Applying value %s = %s for house %d %s (%s)\n", name, value, num, housep->title, housep->id);
99 if (_eq("id")) {
100 strncpy(housep->id, value, LEN_HOUSE_ID);
102 if (pseudo_marker[0]) {
103 char *cc = house_classes[num];
104 strncat(cc, " ", sizeof(house_classes[0]));
105 strncat(cc, pseudo_marker, sizeof(house_classes[0]));
107 /* Hack -- initialize */
108 housep->icon = num;
109 housep->tex = ASS_LoadTexture("runelord.bmp", &_white);
111 else
112 if (_eq("pseudo")) {
113 if (_veq("last")) {
114 num_bhouses = (housep - bhouses);
115 if (num_bhouses > MAX_BHOUSES) num_bhouses = MAX_HOUSES;
118 else
119 if (_eq("pseudo-mark")) {
120 strncpy(pseudo_marker, value, sizeof(pseudo_marker));
122 else
123 if (_eq("class")) {
124 char *cc = house_classes[num];
125 strncat(cc, " ", sizeof(house_classes[0]));
126 strncat(cc, value, sizeof(house_classes[0]));
128 else
129 if (_eq("title")) {
130 strncpy(housep->title, value, LEN_HOUSE_TITLE);
132 else
133 if (_eq("icon")) housep->icon = atoi(value);
134 else
135 if (_eq("gold")) housep->gold_cost = atoi(value);
136 else
137 if (_eq("tile-plane")) {
138 int a, b, c, d;
139 char aU[4], bU[4], cU[4], dU[4];
140 //printf("Scanning '%s'\n", value);
141 if (sscanf(value, "%d%s %d%s %d%s %d%s", &a, aU, &b, bU, &c, cU, &d, dU) == 8) {
142 TL_OR_PIX(a, TILE_W);
143 TL_OR_PIX(b, TILE_H);
144 TL_OR_PIX(c, TILE_W);
145 TL_OR_PIX(d, TILE_H);
146 housep->plane.x = a;
147 housep->plane.y = b;
148 housep->plane.w = c;
149 housep->plane.h = d;
150 } else if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
151 TL_OR_PIX(a, TILE_W);
152 TL_OR_PIX(b, TILE_H);
153 c = 512;
154 d = 512;
155 housep->plane.x = a;
156 housep->plane.y = b;
157 housep->plane.w = a;
158 housep->plane.h = b;
159 } else { printf("Tile plane must in `Nu Nu` or `Nu Nu Nu Nu` format (N=number, u=unit(px,t))\n"); return -1; }
161 else
162 if (_eq("tile-size")) {
163 int a, b;
164 char aU[4], bU[4];
165 if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
166 if (aU[0] != 't' || aU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
167 if (bU[0] != 't' || bU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
168 housep->w = a;
169 housep->h = b;
170 } else { printf("Tile size must in `Nu Nu` format (N=number, u=unit(px,t))\n"); }
172 else
173 if (_eq("offset-unbuilt")) {
174 int a, b;
175 char aU[4], bU[4];
176 if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
177 if (aU[0] != 't' || aU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
178 if (bU[0] != 't' || bU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
179 housep->unbuilt.x = a * 16;
180 housep->unbuilt.y = b * 16;
181 } else { printf("Tile size must in `Nu Nu` format (N=number, u=unit(px,t))\n"); }
183 else
184 if (_eq("offset-idle")) {
185 int a, b;
186 char aU[4], bU[4];
187 if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
188 if (aU[0] != 't' || aU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
189 if (bU[0] != 't' || bU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
190 housep->built.x = a * 16;
191 housep->built.y = b * 16;
192 } else { printf("Tile size must in `Nu Nu` format (N=number, u=unit(px,t))\n"); }
194 else { printf(" Ignoring value %s = %s for house %d %s (%s)\n", name, value, num, housep->title, housep->id); }
195 return 0;
196 #undef _sveq
197 #undef _veq
198 #undef _eq
201 /** Units **/
202 int rcfg_units_count(dom_iter* this, void* ptr) {
204 int i;
205 for (i = 0; i < MAX_BUNITS; i++) {
206 unit_classes[i][0] = 0;
207 unit_p *unit = &bunits[i];
208 unit->plane.x = unit->plane.y = 0;
209 unit->plane.w = unit->plane.h = 0;
212 pseudo_marker[0] = 0;
214 return MAX_BUNITS;
217 int rcfg_units_pick(dom_iter* this, void* ptr) {
219 unit_p *unitp = ptr;
221 if (ptr == bunits) {
222 this->cursor = 0;
225 this->next = (unitp+1);
226 this->parent = NULL;
227 this->kids = NULL;
229 if (this->cursor++ > num_bunits) {
230 this->next = NULL;
233 return 0;
236 char* rcfg_units_test(void *ptr, const char *name) {
237 #define _eq(STR) (!strcasecmp(name, STR))
238 unit_p *unitp = ptr;
240 if (_eq("type")) return "unit";
242 if (_eq("num")) {
243 static char buf[12];
244 sprintf(buf, "%d", (unitp-bunits));
245 return buf;
248 if (_eq("id")) {
249 return unitp->id;
252 if (_eq("class")) {
253 return unit_classes[(unitp-bunits)];
256 //printf("Testing.. %s\n", name);
258 return "";
259 #undef _eq
262 void unitp_parse_frames(Uint8 anim, unit_p *unitp, const char *value) {
263 char cut[1024];
264 strncpy(cut, value, 1024-1);
265 int nf = 0;
266 char *x = strtok(cut, ",");
267 while (x) {
268 int fr = atoi(x);
269 unitp->anim[anim][nf] = fr;
270 x = strtok(NULL, ",");
271 nf++;
273 unitp->anims[anim] = nf;
276 int rcfg_units_apply(void *ptr, const char *name, const char *value) {
277 #define _eq(STR) (!strcasecmp(name, STR))
278 #define _veq(STR) (!strcasecmp(value, STR))
279 #define _sveq(STR) (!strcasecmp(subvalue, STR))
280 unit_p *unitp = ptr;
281 int id = (unitp-bunits);
282 if (_eq("id")) {
283 strncpy(unitp->id, value, LEN_UNIT_ID);
285 if (pseudo_marker[0]) {
286 char *cc = unit_classes[(unitp-bunits)];
287 strncat(cc, " ", sizeof(unit_classes[0]));
288 strncat(cc, pseudo_marker, sizeof(unit_classes[0]));
290 /* Hack -- initialize */
291 int i;
292 for (i = 0; i < MAX_UAXIS; i++) {
293 //unitp->axis_offset[i].
294 unitp->axis_modifier[i] = 0;
296 unitp->axises = 0;
298 else
299 if (_eq("pseudo")) {
300 if (_veq("last")) {
301 num_bunits = (unitp-bunits);
302 if (num_bunits > MAX_BUNITS) num_bunits = MAX_BUNITS;
303 //printf("LAST! %d\n", num_bunits);
304 //sleep(1);
307 else
308 if (_eq("pseudo-mark")) {
309 printf("GOT MARK: %s\n", value);
310 strncpy(pseudo_marker, value, sizeof(pseudo_marker));
312 else
313 if (_eq("class")) {
314 if (_eq("last")) {
318 char *cc = unit_classes[(unitp-bunits)];
319 strncat(cc, " ", sizeof(unit_classes[0]));
320 strncat(cc, value, sizeof(unit_classes[0]));
321 //printf("Attaching class: %s\n", value);
323 else
324 if (_eq("title")) {
325 strncpy(unitp->title, value, LEN_UNIT_TITLE);
327 else
328 if (_eq("stats")) {
329 int a,b,c,d,e,f;
330 if (sscanf(value, "%d %d %d %d %d %d", &a, &b, &c, &d, &e, &f) == 6) {
331 unitp->base_stat[0] = a;
332 unitp->base_stat[1] = b;
333 unitp->base_stat[2] = c;
334 unitp->base_stat[3] = d;
335 unitp->base_stat[4] = e;
336 unitp->base_stat[5] = f;
337 } else printf("Stats must be in 1 2 3 4 5 6 format (six space-separated numbers)\n");
339 else
340 if (_eq("str")) unitp->base_stat[0] = atoi(value);
341 else
342 if (_eq("dex")) unitp->base_stat[1] = atoi(value);
343 else
344 if (_eq("con")) unitp->base_stat[2] = atoi(value);
345 else
346 if (_eq("int")) unitp->base_stat[3] = atoi(value);
347 else
348 if (_eq("met")) unitp->base_stat[4] = atoi(value);
349 else
350 if (_eq("chr")) unitp->base_stat[5] = atoi(value);
351 else
352 if (_eq("skills")) {
353 int a,b,c,d,e,f;
354 if (sscanf(value, "%d %d %d %d %d %d", &a, &b, &c, &d, &e, &f) == 6) {
355 unitp->base_stat[6] = a;
356 unitp->base_stat[7] = b;
357 unitp->base_stat[8] = c;
358 unitp->base_stat[9] = d;
359 unitp->base_stat[10] = e;
360 unitp->base_stat[11] = f;
361 } else printf("Skills must be in 1 2 3 4 5 6 format (six space-separated numbers)\n");
363 else
364 if (_eq("perception")) {
365 if (_veq("sight")) {
366 unitp->perc = Sight;
368 else if (_veq("smell")) {
369 unitp->perc = Smell;
371 else fprintf(stderr, "Perception must be 'sight' or 'smell'\n");
373 else
374 if (_eq("scent-human")) unitp->base_scent[SCENT_HUMAN] = atoi(value);
375 else
376 if (_eq("scent-animal")) unitp->base_scent[SCENT_ANIMAL] = atoi(value);
377 else
378 if (_eq("scent-magic")) unitp->base_scent[SCENT_MAGIC] = atoi(value);
379 else
380 if (_eq("tile-size")) {
381 int a, b;
382 char aU[4], bU[4];
383 if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
384 if (aU[0] != 't' || aU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
385 if (bU[0] != 't' || bU[1] != 0) {printf("The only unit type supported is 't'\n");return -1;}
386 unitp->w = a;
387 unitp->h = b;
388 } else printf("Tile size must in Nu Nu format (N=number, u=unit(px,t))\n");
389 unitp->plane.w = a * TILE_W;
390 unitp->plane.h = b * TILE_H;
391 //printf("Unit %d plane: %d, %d\n", id, unitp->plane.x, unitp->plane.y);
393 else
394 if (_eq("tile-plane")) {
395 int a, b, c, d;
396 char aU[4], bU[4], cU[4], dU[4];
397 //printf("Scanning '%s'\n", value);
398 if (sscanf(value, "%d%s %d%s %d%s %d%s", &a, aU, &b, bU, &c, cU, &d, dU) == 8) {
399 TL_OR_PIX(a, TILE_W);
400 TL_OR_PIX(b, TILE_H);
401 TL_OR_PIX(c, TILE_W);
402 TL_OR_PIX(d, TILE_H);
403 unitp->plane.x = a;
404 unitp->plane.y = b;
405 unitp->plane.w = c;
406 unitp->plane.h = d;
407 } else if (sscanf(value, "%d%s %d%s", &a, aU, &b, bU) == 4) {
408 TL_OR_PIX(a, TILE_W);
409 TL_OR_PIX(b, TILE_H);
410 c = 512;
411 d = 512;
412 unitp->plane.x = a;
413 unitp->plane.y = b;
414 } else { printf("Tile plane must in Nu Nu or Nu Nu Nu Nu format (N=number, u=unit(px,t))\n"); return -1; }
416 //printf("Unit %d plane: %d, %d\n", id, unitp->plane.x, unitp->plane.y);
418 else
419 if (_eq("tile-axis")) {
420 int a, b, c, d;
421 char subvalue[12], aU[4], bU[4];
422 if (sscanf(value, "%s %d %d %d%s %d%s", subvalue, &c, &d, &a, aU, &b, bU) == 7) {
423 TL_OR_PIX(a, TILE_W);
424 TL_OR_PIX(b, TILE_H);
425 } else if (sscanf(value, "%s %d %d", subvalue, &c, &d) == 3) {
426 a = 0;
427 b = 0;
428 } else { printf("Tile offset must be in S N N or S M M Nu Nu format (N=number, u=unit(px,t), S=string)\n"); return -1;}
429 //printf("Receiving offset '%s' multX %d multY %d offX %d offY %d\n",subvalue, a,b, c,d);
430 if (_sveq("num")) {
431 // if (!unitp->plane.w || !unitp->plane.h) { printf("Can't specify static offset for object with no tile-plane\n"); return; }
432 //unitp->x += c * id;
433 //unitp->y += d * id;
435 unitp->plane.x += c * id * TILE_W;
436 unitp->plane.y += d * id * TILE_H;
437 unitp->plane.x += a;
438 unitp->plane.y += b;
439 //printf("Unit %d new plane: %d, %d\n", id, unitp->plane.x, unitp->plane.y);
441 else
442 if (_sveq("frame")) {
443 SDL_Rect *taxis = &unitp->axis_offset[unitp->axises++];
444 taxis->x = a;
445 taxis->y = b;
446 taxis->w = c * unitp->plane.w;
447 taxis->h = d * unitp->plane.h;
448 unitp->axis_modifier[unitp->axises - 1] = UAXIS_FRAME;
449 //printf("UNIT: %s -- AXISES: %d\n", unitp->id, unitp->axises);
450 //sleep(1);
451 // printf("Saving axis (%d %d %d %d\n", a,b,c*unitp->plane.w,d*unitp->plane.w);
453 else
454 if (_sveq("mode")) {
455 SDL_Rect *taxis = &unitp->axis_offset[unitp->axises++];
456 taxis->x = a;
457 taxis->y = b;
458 taxis->w = c * unitp->plane.w;
459 taxis->h = d * unitp->plane.h;
460 unitp->axis_modifier[unitp->axises - 1] = UAXIS_MODE;
461 //printf("UNIT: %s -- AXISES: %d\n", unitp->id, unitp->axises);
462 // sleep(1);
463 // printf("Saving axis (%d %d %d %d\n", a,b,c*unitp->plane.w,d*unitp->plane.w);
465 else { printf("Please supply hardcoded axis identifier (num, frame)\n"); }
468 else
469 if (_eq("animation-idle")) {
470 //printf("Parsing 'animation-idle'\n");
471 unitp_parse_frames(ANIM_IDLE, unitp, value);
473 else
474 if (_eq("animation-walk")) {
475 unitp_parse_frames(ANIM_WALK, unitp, value);
477 else
478 if (_eq("animation-carry")) {
479 unitp_parse_frames(ANIM_CARRY, unitp, value);
481 else
482 if (_eq("animation-attack")) {
483 unitp_parse_frames(ANIM_HIT, unitp, value);
485 else
486 if (_eq("animation-death")) {
487 unitp_parse_frames(ANIM_DEATH, unitp, value);
489 else
490 if (_eq("animation-face")) {
491 unitp_parse_frames(ANIM_FACE, unitp, value);
493 else printf(" Ignoring value %s = %s for unit %d %s (%s)\n", name, value, id, unitp->title, unitp->id);
494 return 0;
495 #undef _sveq
496 #undef _veq
497 #undef _eq
500 dom_iter rcfg_units_iterator = {
501 NULL,
502 NULL,
503 NULL,
504 NULL,
506 NULL,
507 NULL,
508 NULL,
511 &rcfg_units_count,
512 &rcfg_units_pick,
513 &rcfg_units_test,
514 &rcfg_units_apply,
517 dom_iter rcfg_house_iterator = {
518 NULL,
519 NULL,
520 NULL,
521 NULL,
523 NULL,
524 NULL,
525 NULL,
528 &rcfg_house_count,
529 &rcfg_house_pick,
530 &rcfg_house_test,
531 &rcfg_house_apply,
534 int cfg_load(const char *filename) {
536 css_ruleset *mainCSS;
538 mainCSS = css_load_file(filename);
539 if (mainCSS == NULL) return -1;
541 num_bunits = MAX_BUNITS;
542 num_bhouses = MAX_BHOUSES;
544 //css_fprintf(stdout, mainCSS);
545 css_cascade(&rcfg_units_iterator, &bunits, mainCSS);
546 css_cascade(&rcfg_house_iterator, &bhouses, mainCSS);
548 return 0;