From db9eca5b58ad505d306fb3b70a70ba1232ddc265 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Tue, 30 Mar 2021 02:24:08 -0400 Subject: map: Parse ball collision lines --- diff --git a/src/map.c b/src/map.c index f33782f..f2f4263 100644 --- a/src/map.c +++ b/src/map.c @@ -40,6 +40,14 @@ struct db_map_layer { struct db_map_layer *next; }; +struct db_map_line { + int x1; + int y1; + int x2; + int y2; + struct db_map_line *next; +}; + struct db_map { char *game_id; int w; @@ -75,6 +83,8 @@ struct db_map { struct db_ball *ball_tail; Uint8 *p_col; Uint8 *b_col; + struct db_map_line *line_head; + struct db_map_line *line_tail; }; static char * @@ -527,6 +537,98 @@ _db_tmx_object_properties_start(void *pv, const char *name, } static void XMLCALL +_db_tmx_polyline_end(void *pv, const char *name) +{ + XML_Parser p; + + db_dbg(" (polyline)", name); + + p = (XML_Parser) pv; + + if (db_xml_check_tag(name, "polyline")) { + db_xml_node_pop(p); + } else { + db_xml_unexpected_end_tag(p, name, "polyline"); + } +} + +static void XMLCALL +_db_tmx_polyline_start(void *pv, const char *name, + const char **attr __attribute__((__unused__))) +{ + XML_Parser p; + struct db_map *map; + char *points; + char *points_end; + SDL_bool first; + SDL_bool last; + int x; + int y; + struct db_map_line *line; + + db_dbg(" <%s> (polyline)", name); + + p = (XML_Parser) pv; + map = db_xml_node_peek(p); + + if (db_xml_check_tag(name, "polyline")) { + db_xml_get_string_attr(p, attr, "points", &points, 1); + points_end = points; + first = SDL_TRUE; + last = SDL_FALSE; + while (1) { + while (*points_end != ' ' && *points_end != '\0') { + ++points_end; + } + if (*points_end == '\0') { + last = SDL_TRUE; + } + *points_end = '\0'; + if (sscanf(points, "%d,%d", &x, &y) != 2) { + db_warn("Malformed coordinates"); + XML_StopParser(p, XML_FALSE); + return; + } + x += map->obj_x; + y += map->obj_y; + if (!first) { + map->line_tail->x2 = x; + map->line_tail->y2 = y; + db_dbg(" Line: (%d,%d) to (%d,%d)", + map->line_tail->x1, + map->line_tail->y1, + map->line_tail->x2, + map->line_tail->y2); + } + first = SDL_FALSE; + if (last) { + break; + } else { + line = calloc(1, sizeof(*line)); + if (line == NULL) { + db_err("Failed to allocate memory"); + XML_StopParser(p, XML_FALSE); + return; + } + line->x1 = x; + line->y1 = y; + if (map->line_tail == NULL) { + map->line_head = line; + } else { + map->line_tail->next = line; + } + map->line_tail = line; + } + points = ++points_end; + } + db_xml_node_push(p, map, _db_tmx_invalid_start, + _db_tmx_polyline_end, NULL); + } else { + db_xml_unexpected_start_tag(p, name, "polyline"); + } +} + +static void XMLCALL _db_tmx_object_end(void *pv, const char *name) { XML_Parser p; @@ -538,32 +640,36 @@ _db_tmx_object_end(void *pv, const char *name) 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; - map->player_gid = map->obj_gid; - } 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; - map->target_gid = map->obj_gid; - } 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->tileset_head, map->obj_gid, - map, 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; + if (map->obj_gid != -1) { + 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; + map->player_gid = map->obj_gid; + } 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; + map->target_gid = map->obj_gid; + } 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->tileset_head, map->obj_gid, + map, 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); } - free(map->obj_type); db_xml_node_pop(p); } else { db_xml_unexpected_end_tag(p, name, "object"); @@ -586,7 +692,15 @@ _db_tmx_object_start(void *pv, const char *name, const char **attr) 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); + map->obj_gid = -1; + db_xml_get_int_attr(p, attr, "gid", &map->obj_gid, 0); + if (map->obj_gid == -1) { + db_xml_get_int_attr(p, attr, "x", &map->obj_x, 1); + db_xml_get_int_attr(p, attr, "y", &map->obj_y, 1); + db_xml_node_push(p, map, _db_tmx_polyline_start, + _db_tmx_object_end, NULL); + return; + } db_xml_get_int_attr(p, attr, "x", &x, 1); db_xml_get_int_attr(p, attr, "y", &y, 1); db_xml_get_int_attr(p, attr, "width", &w, 1); @@ -927,6 +1041,7 @@ db_map_render(struct db_map *map, SDL_Renderer *renderer) SDL_Texture *texture; SDL_Texture *old_target; struct db_map_layer *layer; + struct db_map_line *line; /* < FIXME: Debugging < */ texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, map->w * map->tw, @@ -949,6 +1064,21 @@ db_map_render(struct db_map *map, SDL_Renderer *renderer) } } + /* \/ FIXME: Debugging \/ */ + if (SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF) != 0) { + db_err("Failed to set drawing color (%s)", SDL_GetError()); + return NULL; + } + for (line = map->line_head; line != NULL; line = line->next) { + if (SDL_RenderDrawLine(renderer, + line->x1, line->y1, + line->x2, line->y2) != 0) { + db_err("Failed to draw line (%s)", SDL_GetError()); + return NULL; + } + } + /* /\ FIXME: Debugging /\ */ + SDL_SetRenderTarget(renderer, old_target); return texture; -- cgit v0.9.1