summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-03-25 17:56:46 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-03-25 18:04:26 (EDT)
commitc3d4b15d8b4f4ceb4b3fe5901600cd3b94cfb52c (patch)
tree62f87eaf896441b5ab46fe1fddb7f5f1a0163405
parent66a8768bb0655a2924954b3e8aa8f845066368d5 (diff)
downloaddodge-balls-c3d4b15d8b4f4ceb4b3fe5901600cd3b94cfb52c.zip
dodge-balls-c3d4b15d8b4f4ceb4b3fe5901600cd3b94cfb52c.tar.gz
dodge-balls-c3d4b15d8b4f4ceb4b3fe5901600cd3b94cfb52c.tar.bz2
map: Parse and create objects
-rw-r--r--src/map.c236
1 files changed, 234 insertions, 2 deletions
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#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(" </%s> (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(" </%s> (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(" </%s> (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,