From c3d4b15d8b4f4ceb4b3fe5901600cd3b94cfb52c Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Thu, 25 Mar 2021 17:56:46 -0400 Subject: map: Parse and create objects --- diff --git a/src/map.c b/src/map.c index 0e79a81..759edaf 100644 --- a/src/map.c +++ b/src/map.c @@ -22,6 +22,7 @@ #include #include #include +#include "ball.h" #include "base64.h" #include "compression.h" #include "defs.h" @@ -53,6 +54,23 @@ struct db_map { struct db_tileset *tileset_tail; struct db_map_layer *layer_head; struct db_map_layer *layer_tail; + int obj_gid; + char *obj_type; + int obj_x; + int obj_y; + int obj_r; + int obj_a; + int obj_d; + int obj_sr; + double obj_s; + int player_x; + int player_y; + int player_r; + int target_x; + int target_y; + int target_r; + struct db_ball *ball_head; + struct db_ball *ball_tail; }; static char * @@ -360,6 +378,221 @@ _db_tmx_layer_end(void *pv, const char *name) } static void XMLCALL +_db_tmx_object_property_end(void *pv, const char *name) +{ + XML_Parser p; + + db_dbg(" (property)", name); + + p = (XML_Parser) pv; + + if (db_xml_check_tag(name, "property")) { + db_xml_node_pop(p); + } else { + db_xml_unexpected_end_tag(p, name, "property"); + } +} + +static void XMLCALL +_db_tmx_object_property_start(void *pv, const char *name, const char **attr) +{ + XML_Parser p; + struct db_map *map; + char *p_name; + char *p_type; + char *dir; + + db_dbg(" <%s> (property)", name); + + p = (XML_Parser) pv; + map = db_xml_node_peek(p); + + if (db_xml_check_tag(name, "property")) { + db_xml_get_string_attr(p, attr, "name", &p_name, 1); + if (strcmp(p_name, "type") == 0) { + db_xml_get_string_attr(p, attr, "value", &map->obj_type, + 1); + db_dbg(" Object type: %s", map->obj_type); + } else if (strcmp(p_name, "speed") == 0) { + db_xml_get_string_attr(p, attr, "type", &p_type, 1); + if (strcmp(p_type, "int") == 0) { + db_xml_get_int_attr(p, attr, "value", + (int *) &map->obj_s, 1); + } else if (strcmp(p_type, "float") == 0) { + db_xml_get_float_attr(p, attr, "value", + (float *) &map->obj_s, 1); + } else { + db_err("Object speed must be an integer or " + "float"); + free(p_name); + free(p_type); + XML_StopParser(p, XML_FALSE); + return; + } + free(p_type); + db_dbg(" Object speed: %f", map->obj_s); + } else if (strcmp(p_name, "direction") == 0) { + db_xml_get_string_attr(p, attr, "value", &dir, 1); + if (strcmp(dir, "lr") == 0) { + map->obj_a = (rand() / (RAND_MAX / 2)) * 180.0; + db_dbg(" Object direction: " + "left and right"); + } else if (strcmp(dir, "ud") == 0) { + map->obj_a = (rand() / (RAND_MAX / 2)) * 180.0 + + 90.0; + db_dbg(" Object direction: " + "up and down"); + } else if (strcmp(dir, "random") == 0) { + map->obj_a = rand() / (RAND_MAX / 360); + db_dbg(" Object direction: " + "random"); + } else if (strcmp(dir, "cw") == 0) { + map->obj_d = -1; + db_dbg(" Object direction: " + "clockwise"); + } else if (strcmp(dir, "ccw") == 0) { + map->obj_d = 1; + db_dbg(" Object direction: " + "counter-clockwise"); + } + } else if (strcmp(p_name, "radius") == 0) { + db_xml_get_string_attr(p, attr, "type", &p_type, 1); + if (strcmp(p_type, "int") != 0) { + db_err("Object spin radius must be an integer"); + free(p_name); + free(p_type); + XML_StopParser(p, XML_FALSE); + return; + } + free(p_type); + db_xml_get_int_attr(p, attr, "value", &map->obj_sr, 1); + db_dbg(" Object spin radius: %d", + map->obj_sr); + } else { + db_dbg("Skipping unknown property \"%s\"", p_name); + } + free(p_name); + db_xml_node_push(p, map, _db_tmx_invalid_start, + _db_tmx_object_property_end, NULL); + } else { + db_xml_unexpected_start_tag(p, name, "property"); + } +} + +static void XMLCALL +_db_tmx_object_properties_end(void *pv, const char *name) +{ + XML_Parser p; + + db_dbg(" (properties)", name); + + p = (XML_Parser) pv; + + if (db_xml_check_tag(name, "properties")) { + db_xml_node_pop(p); + } else { + db_xml_unexpected_end_tag(p, name, "properties"); + } +} + +static void XMLCALL +_db_tmx_object_properties_start(void *pv, const char *name, + const char **attr __attribute__((__unused__))) +{ + XML_Parser p; + struct db_map *map; + + db_dbg(" <%s> (properties)", name); + + p = (XML_Parser) pv; + map = db_xml_node_peek(p); + + if (db_xml_check_tag(name, "properties")) { + db_xml_node_push(p, map, _db_tmx_object_property_start, + _db_tmx_object_properties_end, NULL); + } else { + db_xml_unexpected_start_tag(p, name, "properties"); + } +} + +static void XMLCALL +_db_tmx_object_end(void *pv, const char *name) +{ + XML_Parser p; + struct db_map *map; + + db_dbg(" (object)", name); + + p = (XML_Parser) pv; + map = db_xml_node_peek(p); + + if (db_xml_check_tag(name, "object")) { + if (strcmp(map->obj_type, "player") == 0) { + map->player_x = map->obj_x; + map->player_y = map->obj_y; + map->player_r = map->obj_r; + } else if (strcmp(map->obj_type, "target") == 0) { + map->target_x = map->obj_x; + map->target_y = map->obj_y; + map->target_r = map->obj_r; + } else if (strcmp(map->obj_type, "ball") == 0) { + map->ball_tail = db_ball_new(map->obj_x, map->obj_y, + map->obj_r, map->obj_a, map->obj_d, + map->obj_sr, map->obj_s, + map->ball_tail); + if (map->ball_tail == NULL) { + XML_StopParser(p, XML_FALSE); + free(map->obj_type); + return; + } + if (map->ball_head == NULL) { + map->ball_head = map->ball_tail; + } + } + free(map->obj_type); + db_xml_node_pop(p); + } else { + db_xml_unexpected_end_tag(p, name, "object"); + } +} + +static void XMLCALL +_db_tmx_object_start(void *pv, const char *name, const char **attr) +{ + XML_Parser p; + struct db_map *map; + int x; + int y; + int w; + int h; + + db_dbg(" <%s> (object)", name); + + p = (XML_Parser) pv; + map = db_xml_node_peek(p); + + if (db_xml_check_tag(name, "object")) { + db_xml_get_int_attr(p, attr, "gid", &map->obj_gid, 1); + db_xml_get_int_attr(p, attr, "x", &x, 1); + db_xml_get_int_attr(p, attr, "x", &y, 1); + db_xml_get_int_attr(p, attr, "width", &w, 1); + db_xml_get_int_attr(p, attr, "height", &h, 1); + if (w != h) { + db_err("Objects must be circular"); + XML_StopParser(p, XML_FALSE); + return; + } + map->obj_x = (x + w) / 2; + map->obj_y = (y + h) / 2; + map->obj_r = w / 2; + db_xml_node_push(p, map, _db_tmx_object_properties_start, + _db_tmx_object_end, NULL); + } else { + db_xml_unexpected_start_tag(p, name, "object"); + } +} + +static void XMLCALL _db_tmx_objectgroup_end(void *pv, const char *name) { XML_Parser p; @@ -411,8 +644,7 @@ _db_tmx_map_el_start(void *pv, const char *name, const char **attr) db_xml_node_push(p, map, _db_tmx_data_start, _db_tmx_layer_end, NULL); } else if (db_xml_check_tag(name, "objectgroup")) { - /* TODO: object */ - db_xml_node_push(p, map, _db_tmx_invalid_start, + db_xml_node_push(p, map, _db_tmx_object_start, _db_tmx_objectgroup_end, NULL); } else { db_xml_unexpected_start_tag(p, name, -- cgit v0.9.1