summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-03-30 02:24:08 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-03-30 02:24:08 (EDT)
commitdb9eca5b58ad505d306fb3b70a70ba1232ddc265 (patch)
tree5debe20cad7a8e8e93785cf8104f2ed113e9efbf
parent1c5f2fa86286137a86da01cbc3f67e204442b558 (diff)
downloaddodge-balls-db9eca5b58ad505d306fb3b70a70ba1232ddc265.zip
dodge-balls-db9eca5b58ad505d306fb3b70a70ba1232ddc265.tar.gz
dodge-balls-db9eca5b58ad505d306fb3b70a70ba1232ddc265.tar.bz2
map: Parse ball collision lines
-rw-r--r--src/map.c180
1 files changed, 155 insertions, 25 deletions
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(" </%s> (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;