diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/resources/map.c | 126 | ||||
-rw-r--r-- | src/resources/map.h | 8 |
2 files changed, 121 insertions, 13 deletions
diff --git a/src/resources/map.c b/src/resources/map.c index 4b2b9ac..5e30aa2 100644 --- a/src/resources/map.c +++ b/src/resources/map.c @@ -22,6 +22,11 @@ static void XMLCALL tmx_tileset_end(void *, const char *); static void XMLCALL tmx_tilesetemb_end(void *, const char *); static void XMLCALL tmx_tileset_el_start(void *, const char *, const char **); static void XMLCALL tmx_image_end(void *, const char *); +static void XMLCALL tmx_tile_end(void *, const char *); +static void XMLCALL tmx_tile_properties_start(void *, const char *, + const char **); +static void XMLCALL tmx_tile_property_start(void *, const char *, + const char **); static void XMLCALL tmx_layer_el_start(void *, const char *, const char **); static void XMLCALL tmx_layer_end(void *, const char *); static void XMLCALL tmx_data_end(void *, const char *); @@ -336,6 +341,11 @@ tmx_map_el_start(void *pv, const char *name, const char **attr) 1); xml_get_int_attr(p, attr, "tileheight", &ts->tileheight, 1); + if (strcmp(ts->name, "collision") == 0) { + ts->type = TILESET_TYPE_COLLISION; + } else { + ts->type = TILESET_TYPE_IMAGE; + } xml_node_push(p, ts, tmx_tileset_el_start, tmx_tilesetemb_end, NULL); } @@ -369,6 +379,11 @@ tmx_tileset_start(void *pv, const char *name, const char **attr) xml_get_string_attr(p, attr, "name", &ts->name, 1); xml_get_int_attr(p, attr, "tilewidth", &ts->tilewidth, 1); xml_get_int_attr(p, attr, "tileheight", &ts->tileheight, 1); + if (strcmp(ts->name, "collision") == 0) { + ts->type = TILESET_TYPE_COLLISION; + } else { + ts->type = TILESET_TYPE_IMAGE; + } xml_node_push(p, ts, tmx_tileset_el_start, tmx_tileset_end, NULL); } else { @@ -412,6 +427,7 @@ static void XMLCALL tmx_tileset_el_start(void *pv, const char *name, const char **attr) { XML_Parser p = (XML_Parser) pv; + struct tileset *ts; char *dirname; char *source; char *path; @@ -419,27 +435,39 @@ tmx_tileset_el_start(void *pv, const char *name, const char **attr) debug("<%s> (tileset child)", name); + ts = xml_node_peek(p); + if (xml_check_tag(name, "tileoffset")) { /* Not used by engine. */ xml_node_push(p, NULL, tmx_unused_start, tmx_unused_end, NULL); } else if (xml_check_tag(name, "image")) { - dirname = ((struct tileset *) xml_node_peek(p))->dirname; - xml_get_string_attr(p, attr, "source", &source, 0); - path = malloc(strlen(dirname) + strlen(source) + 2); - if (path == NULL) { - return; + xml_get_int_attr(p, attr, "width", &ts->width, 1); + xml_get_int_attr(p, attr, "height", &ts->height, 1); + ts->width /= ts->tilewidth; + ts->height /= ts->tileheight; + img = NULL; + if (ts->type == TILESET_TYPE_IMAGE) { + dirname = ts->dirname; + xml_get_string_attr(p, attr, "source", &source, 0); + path = malloc(strlen(dirname) + strlen(source) + 2); + if (path == NULL) { + return; + } + sprintf(path, "%s/%s", dirname, source); + img = img_png_get(path); + free(source); + } else if (ts->type == TILESET_TYPE_COLLISION) { + ts->collision_tiles = malloc(ts->width * ts->height * + sizeof(*ts->collision_tiles)); + if (ts->collision_tiles == NULL) { + return; + } } - sprintf(path, "%s/%s", dirname, source); - img = img_png_get(path); - free(source); xml_node_push(p, img, tmx_invalid_start, tmx_image_end, NULL); } else if (xml_check_tag(name, "tile")) { - /* TODO */ - xml_node_push(p, NULL, tmx_unused_start, tmx_unused_end, NULL); -#if 0 - xml_node_push(p, img, tmx_tile_properties_start, tmx_tile_end, + xml_get_int_attr(p, attr, "id", &ts->cur_collision_tile, 1); + xml_node_push(p, ts, tmx_tile_properties_start, tmx_tile_end, NULL); -#endif } else { xml_unexpected_start_tag(p, name, "tileoffset, image, tile"); } @@ -464,6 +492,78 @@ tmx_image_end(void *pv, const char *name) } static void XMLCALL +tmx_tile_end(void *pv, const char *name) +{ + XML_Parser p = (XML_Parser) pv; + + debug("</%s> (tile)", name); + + xml_node_pop(p); + + if (xml_check_tag(name, "tile")) { + } else { + xml_unexpected_end_tag(p, name, "tile"); + } +} + +static void XMLCALL +tmx_tile_properties_start(void *pv, const char *name, const char **attr) +{ + XML_Parser p = (XML_Parser) pv; + struct tileset *ts; + + debug("<%s> (tile properties)", name); + + ts = xml_node_peek(p); + + if (xml_check_tag(name, "properties")) { + /* <properties> has no attributes, but GCC warns of an + * "unused parameter ‘attr’". */ + for (; 0; ++attr); + xml_node_push(p, ts, tmx_tile_property_start, tmx_unused_end, + NULL); + } else { + xml_unexpected_start_tag(p, name, "properties"); + } +} + +static void XMLCALL +tmx_tile_property_start(void *pv, const char *name, const char **attr) +{ + XML_Parser p = (XML_Parser) pv; + struct tileset *ts; + char *attr_name; + char *attr_value; + int coll_t, coll_r, coll_b, coll_l; + int n; + + debug("<%s> (tile property)", name); + + ts = xml_node_peek(p); + + if (xml_check_tag(name, "property")) { + xml_get_string_attr(p, attr, "name", &attr_name, 1); + xml_get_string_attr(p, attr, "value", &attr_value, 1); + if (strcmp(attr_name, "collision") ==0) { + n = sscanf(attr_value, "%d,%d,%d,%d", + &coll_t, &coll_r, &coll_b, &coll_l); + if (n != 4) { + return; + } + ts->collision_tiles[ts->cur_collision_tile] = + coll_t << 3 | coll_r << 2 | + coll_b << 1 | coll_l << 0; + } + free(attr_name); + free(attr_value); + for (; 0; ++attr, ++ts); + xml_node_push(p, NULL, tmx_invalid_start, tmx_unused_end, NULL); + } else { + xml_unexpected_start_tag(p, name, "property"); + } +} + +static void XMLCALL tmx_layer_el_start(void *pv, const char *name, const char **attr) { XML_Parser p = (XML_Parser) pv; diff --git a/src/resources/map.h b/src/resources/map.h index e088161..ba264de 100644 --- a/src/resources/map.h +++ b/src/resources/map.h @@ -21,7 +21,15 @@ struct tileset { char *name; int tilewidth; int tileheight; + int width; + int height; + enum { + TILESET_TYPE_IMAGE, + TILESET_TYPE_COLLISION + } type; struct image *image; + Uint8 *collision_tiles; + int cur_collision_tile; }; struct map_tileset { struct tileset *tileset; |