4 #include "libs/lazyass/lazyass.h"
5 #include "libs/libcsslike/cssdom.h"
11 unit_p bunits
[MAX_BUNITS
];
12 house_p bhouses
[MAX_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); \
32 int rcfg_house_count(dom_iter
* this, void* ptr
) {
35 for (i
= 0; i
< MAX_BHOUSES
; i
++) {
36 house_p
*housep
= &bhouses
[i
];
44 int rcfg_house_pick(dom_iter
* this, void* ptr
) {
46 house_p
*housep
= ptr
;
52 this->next
= (housep
+1);
56 if (this->cursor
++ > num_bhouses
) {
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";
72 snprintf(buf
, sizeof(buf
), "%d", num
);
81 return house_classes
[num
];
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);
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 */
109 housep
->tex
= ASS_LoadTexture("runelord.bmp", &_white
);
114 num_bhouses
= (housep
- bhouses
);
115 if (num_bhouses
> MAX_BHOUSES
) num_bhouses
= MAX_HOUSES
;
119 if (_eq("pseudo-mark")) {
120 strncpy(pseudo_marker
, value
, sizeof(pseudo_marker
));
124 char *cc
= house_classes
[num
];
125 strncat(cc
, " ", sizeof(house_classes
[0]));
126 strncat(cc
, value
, sizeof(house_classes
[0]));
130 strncpy(housep
->title
, value
, LEN_HOUSE_TITLE
);
133 if (_eq("icon")) housep
->icon
= atoi(value
);
135 if (_eq("gold")) housep
->gold_cost
= atoi(value
);
137 if (_eq("tile-plane")) {
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
);
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
);
159 } else { printf("Tile plane must in `Nu Nu` or `Nu Nu Nu Nu` format (N=number, u=unit(px,t))\n"); return -1; }
162 if (_eq("tile-size")) {
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;}
170 } else { printf("Tile size must in `Nu Nu` format (N=number, u=unit(px,t))\n"); }
173 if (_eq("offset-unbuilt")) {
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"); }
184 if (_eq("offset-idle")) {
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
); }
202 int rcfg_units_count(dom_iter
* this, void* ptr
) {
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;
217 int rcfg_units_pick(dom_iter
* this, void* ptr
) {
225 this->next
= (unitp
+1);
229 if (this->cursor
++ > num_bunits
) {
236 char* rcfg_units_test(void *ptr
, const char *name
) {
237 #define _eq(STR) (!strcasecmp(name, STR))
240 if (_eq("type")) return "unit";
244 sprintf(buf
, "%d", (unitp
-bunits
));
253 return unit_classes
[(unitp
-bunits
)];
256 //printf("Testing.. %s\n", name);
262 void unitp_parse_frames(Uint8 anim
, unit_p
*unitp
, const char *value
) {
264 strncpy(cut
, value
, 1024-1);
266 char *x
= strtok(cut
, ",");
269 unitp
->anim
[anim
][nf
] = fr
;
270 x
= strtok(NULL
, ",");
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))
281 int id
= (unitp
-bunits
);
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 */
292 for (i
= 0; i
< MAX_UAXIS
; i
++) {
293 //unitp->axis_offset[i].
294 unitp
->axis_modifier
[i
] = 0;
301 num_bunits
= (unitp
-bunits
);
302 if (num_bunits
> MAX_BUNITS
) num_bunits
= MAX_BUNITS
;
303 //printf("LAST! %d\n", num_bunits);
308 if (_eq("pseudo-mark")) {
309 printf("GOT MARK: %s\n", value
);
310 strncpy(pseudo_marker
, value
, sizeof(pseudo_marker
));
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);
325 strncpy(unitp
->title
, value
, LEN_UNIT_TITLE
);
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");
340 if (_eq("str")) unitp
->base_stat
[0] = atoi(value
);
342 if (_eq("dex")) unitp
->base_stat
[1] = atoi(value
);
344 if (_eq("con")) unitp
->base_stat
[2] = atoi(value
);
346 if (_eq("int")) unitp
->base_stat
[3] = atoi(value
);
348 if (_eq("met")) unitp
->base_stat
[4] = atoi(value
);
350 if (_eq("chr")) unitp
->base_stat
[5] = atoi(value
);
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");
364 if (_eq("perception")) {
368 else if (_veq("smell")) {
371 else fprintf(stderr
, "Perception must be 'sight' or 'smell'\n");
374 if (_eq("scent-human")) unitp
->base_scent
[SCENT_HUMAN
] = atoi(value
);
376 if (_eq("scent-animal")) unitp
->base_scent
[SCENT_ANIMAL
] = atoi(value
);
378 if (_eq("scent-magic")) unitp
->base_scent
[SCENT_MAGIC
] = atoi(value
);
380 if (_eq("tile-size")) {
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;}
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);
394 if (_eq("tile-plane")) {
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
);
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
);
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);
419 if (_eq("tile-axis")) {
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) {
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);
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
;
439 //printf("Unit %d new plane: %d, %d\n", id, unitp->plane.x, unitp->plane.y);
442 if (_sveq("frame")) {
443 SDL_Rect
*taxis
= &unitp
->axis_offset
[unitp
->axises
++];
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);
451 // printf("Saving axis (%d %d %d %d\n", a,b,c*unitp->plane.w,d*unitp->plane.w);
455 SDL_Rect
*taxis
= &unitp
->axis_offset
[unitp
->axises
++];
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);
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"); }
469 if (_eq("animation-idle")) {
470 //printf("Parsing 'animation-idle'\n");
471 unitp_parse_frames(ANIM_IDLE
, unitp
, value
);
474 if (_eq("animation-walk")) {
475 unitp_parse_frames(ANIM_WALK
, unitp
, value
);
478 if (_eq("animation-carry")) {
479 unitp_parse_frames(ANIM_CARRY
, unitp
, value
);
482 if (_eq("animation-attack")) {
483 unitp_parse_frames(ANIM_HIT
, unitp
, value
);
486 if (_eq("animation-death")) {
487 unitp_parse_frames(ANIM_DEATH
, unitp
, value
);
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
);
500 dom_iter rcfg_units_iterator
= {
517 dom_iter rcfg_house_iterator
= {
534 int cfg_load(const char *filename
) {
540 file
= SDL_RWFromFile(filename
, "rb");
541 if (file
== NULL
) return -1;
543 css_parser
*state
= css_parser_create();
548 n
= SDL_RWread(file
, buf
, sizeof(char), sizeof(buf
));
551 err
= css_parse(state
, buf
, n
);
557 sheet
= css_parser_done(state
);
558 if (sheet
== NULL
) return -1;
560 num_bunits
= MAX_BUNITS
;
561 num_bhouses
= MAX_BHOUSES
;
563 //css_fprintf(stdout, mainCSS);
564 css_cascade(&rcfg_units_iterator
, &bunits
, sheet
);
565 css_cascade(&rcfg_house_iterator
, &bhouses
, sheet
);