diff options
-rw-r--r-- | src/layer.h | 22 | ||||
-rw-r--r-- | src/resources/Makefile.am | 1 | ||||
-rw-r--r-- | src/resources/layer.h | 14 | ||||
-rw-r--r-- | src/resources/tileset.c | 161 | ||||
-rw-r--r-- | src/resources/tileset.h | 23 | ||||
-rw-r--r-- | src/tileset.h | 12 | ||||
-rw-r--r-- | src/tmx.c | 378 | ||||
-rw-r--r-- | src/tmx.h | 8 |
8 files changed, 0 insertions, 619 deletions
diff --git a/src/layer.h b/src/layer.h deleted file mode 100644 index 85558a6..0000000 --- a/src/layer.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef LAYER_H -#define LAYER_H - -#include <SDL_stdinc.h> - -#if 0 -const int LAYER_GROUND = 0; -const int LAYER_OBJ_LOW = 1; -const int LAYER_CHAR_BOT = 2; -const int LAYER_OBJ_MID = 3; -const int LAYER_CHAR_TOP = 4; -const int LAYER_OBJ_HIGH = 5; -const int LAYER_WEATHER = 6; -#endif - -struct layer { - char *name; - Uint32 *tiles; - struct layer *next; -}; - -#endif diff --git a/src/resources/Makefile.am b/src/resources/Makefile.am index 1829942..839911f 100644 --- a/src/resources/Makefile.am +++ b/src/resources/Makefile.am @@ -1,5 +1,4 @@ src_resources_SOURCES = \ src/resources/resource.c \ src/resources/image.c \ - src/resources/tileset.c \ src/resources/map.c diff --git a/src/resources/layer.h b/src/resources/layer.h deleted file mode 100644 index 82504de..0000000 --- a/src/resources/layer.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef RESOURCE_LAYER_H -#define RESOURCE_LAYER_H - -#include "resource.h" - -struct layer { - struct resource res; - char *name; - char *encoding; - char *compression; - struct layer *next; -}; - -#endif diff --git a/src/resources/tileset.c b/src/resources/tileset.c deleted file mode 100644 index e15224a..0000000 --- a/src/resources/tileset.c +++ /dev/null @@ -1,161 +0,0 @@ -#include <expat.h> -#include "tileset.h" -#include "../xml.h" -#include "../logging.h" - -/* - * Problem: - * xml_tselem_start(), xml_tileset_end(), etc. may be called with one of two - * types of user data. - * Possible solution: - * 1. Create a base (struct xml_doc) in src/xml.h: - * struct xml_doc { - * enum { - * XML_DOC_TMX, - * XML_DOC_TSX - * } type; - * XML_Parser p; - * }; - * 2. Make (struct tmx) and (struct tmx) "extend" it, e.g.: - * struct tsx { - * struct xml_doc doc; - * struct tileset *ts; - * }; - * 3. Make xml_tselem_start(), xml_tileset_end(), etc. check the doc.type - * member of the user data and find the (struct tileset *) accordingly. - * Wait, what?! - * Alternative solution: - * 1. Declare (struct tmx) in src/resources/map.h. - * 2. Add to (struct tsx) the following member: - * struct tmx *parent_tmx; - * 3. In xml_mapelem_start() (src/resources/map.c): - * 1. Allocate a (struct tsx). - * 2. Set the parent_tmx member of the (struct tsx) to tmx. - * 3. Set the ts member of the (struct tsx) to ts. - * 4. Set the (struct tsx) as the user data. - * 4. In xml_tileset_end() (src/resources/tileset.c), add the following code: - * if (tsx->parent_tmx != NULL) { - * XML_SetUserData(tsx->p, tsx->parent_tmx); - * free(tsx); - * XML_SetStartElementHandler(tmx->p, xml_mapelem_start); - * XML_SetEndElementHandler(tmx->p, xml_map_end); - * } - * Alternative alternative solution: - * Something that doesn't suck. - */ -struct tsx { - XML_Parser p; - struct tileset *ts; -}; - -struct resource_table ts_res; - -void XMLCALL -xml_tileset_start(void *data, const char *el, const char **attr) -{ - struct tsx *tsx; - - debug("<%s> (type \"tileset\")", el); - - tsx = (struct tsx *) data; - - if (xml_check_tag(el, "tileset")) { - xml_get_string_attr(tsx->p, attr, "name", - &tsx->ts->name, 1); - xml_get_int_attr(tsx->p, attr, "tilewidth", - &tsx->ts->tilewidth, 1); - xml_get_int_attr(tsx->p, attr, "tileheight", - &tsx->ts->tileheight, 1); -/* XML_SetStartElementHandler(tsx->p, xml_tselem_start);*/ - XML_SetEndElementHandler(tsx->p, xml_tileset_end); - } else { - xml_unexpected_start_tag(tsx->p, el, - "tileset"); - } -} - -void XMLCALL -xml_tileset_end(void *data, const char *el) -{ - struct tsx *tsx; - - debug("</%s> (type \"tileset\")", el); - - tsx = (struct tsx *) data; - - if (xml_check_tag(el, "tileset")) { - XML_SetStartElementHandler(tsx->p, NULL); - XML_SetEndElementHandler(tsx->p, NULL); - } else { - xml_unexpected_end_tag(tsx->p, el, - "tileset"); - } -} - -struct tileset * -tileset_get(const char *path) -{ - struct tsx tsx; - FILE *tsx_fp; - void *tsx_buf; - size_t len; - enum XML_Status status; - - memset(&tsx, 0, sizeof(tsx)); - - tsx.ts = (struct tileset *) resource_get(&ts_res, path); - if (tsx.ts != NULL) { - resource_use((struct resource *) tsx.ts); - return tsx.ts; - } - - tsx.ts = resource_alloc(path, sizeof(*tsx.ts)); - - tsx.p = XML_ParserCreate(NULL); - if (tsx.p == NULL) { - warn("Failed to create TSX parser"); - return NULL; - } - - XML_SetStartElementHandler(tsx.p, xml_tileset_start); - XML_SetEndElementHandler(tsx.p, NULL); - XML_SetCharacterDataHandler(tsx.p, NULL); - - XML_SetUserData(tsx.p, &tsx); - - tsx_fp = fopen(path, "rb"); - if (tsx_fp == NULL) { - warn("Failed to open TSX file"); - XML_ParserFree(tsx.p); - return NULL; - } - - tsx_buf = XML_GetBuffer(tsx.p, 8192); - if (tsx_buf == NULL) { - warn("Failed to create TSX parse buffer"); - XML_ParserFree(tsx.p); - fclose(tsx_fp); - return NULL; - } - - while (!feof(tsx_fp)) { - len = fread(tsx_buf, 1, 8192, tsx_fp); - status = XML_ParseBuffer(tsx.p, len, feof(tsx_fp)); - if (status == XML_STATUS_OK) { - continue; - } - warn("Failed to parse TSX file (%s)", - XML_ErrorString(XML_GetErrorCode(tsx.p))); - XML_ParserFree(tsx.p); - fclose(tsx_fp); - return NULL; - } - - XML_ParserFree(tsx.p); - fclose(tsx_fp); - - resource_use((struct resource *) tsx.ts); - resource_add(&ts_res, path, (struct resource *) tsx.ts); - - return tsx.ts; -} diff --git a/src/resources/tileset.h b/src/resources/tileset.h deleted file mode 100644 index 45de237..0000000 --- a/src/resources/tileset.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef RESOURCE_TILESET_H -#define RESOURCE_TILESET_H - -#include <expat.h> -#include "resource.h" -#include "image.h" - -struct tileset { - struct resource res; - int firstgid; - char *name; - int tilewidth; - int tileheight; - struct image *image; - struct tileset *next; -}; - -struct tileset *tileset_get(const char *path); -void XMLCALL xml_tileset_start(void *data, const char *el, - const char **attr); -void XMLCALL xml_tileset_end(void *data, const char *el); - -#endif diff --git a/src/tileset.h b/src/tileset.h deleted file mode 100644 index 26aec80..0000000 --- a/src/tileset.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef TILESET_H -#define TILESET_H - -struct tileset { - int firstgid; - int tilewidth; - int tileheight; - struct image *image; - struct tileset *next; -}; - -#endif diff --git a/src/tmx.c b/src/tmx.c deleted file mode 100644 index 4695a9e..0000000 --- a/src/tmx.c +++ /dev/null @@ -1,378 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <libgen.h> -#include <expat.h> -#include <SDL.h> -#include "logging.h" -#include "base64.h" -#include "compression.h" -#include "map.h" -#include "resources/image.h" - -struct tmx { - char *dirname; - struct map *map; - enum { - TMX_PARSING_NONE = 0, - TMX_PARSING_MAP, - TMX_PARSING_TILESET, - TMX_PARSING_IMAGE, - TMX_PARSING_LAYER, - TMX_PARSING_DATA - } parsing; - struct tileset *cur_tileset; - struct layer *cur_layer; - enum { - TMX_DATA_ENC_NONE = 0, - TMX_DATA_ENC_BASE64, - TMX_DATA_ENC_CSV - } data_encoding; - enum { - TMX_DATA_COMP_NONE = 0, - TMX_DATA_COMP_GZIP, - TMX_DATA_COMP_ZLIB - } data_compression; - char *layer_data; -}; - -#define foreach_tmx_attr(attr) \ - for (; (attr)[0] != NULL; (attr) += 2) - -#define tmx_get_int_attr(attr, name, p) \ - do { \ - if (strcmp((attr)[0], (name)) == 0) { \ - if (sscanf((attr)[1], "%d", (p)) != 1) { \ - err(1, "Invalid \"%s\" attribute", (name)); \ - } \ - } \ - } while (0); - -#define tmx_get_string_attr(attr, name, p) \ - do { \ - if (strcmp((attr)[0], (name)) == 0) { \ - (p) = strdup((attr)[1]); \ - } \ - } while (0); - -static void -tmx_start_map(struct tmx *cur_tmx, const char **attr) -{ - if (cur_tmx->map != NULL) { - err(1, "Found multiple maps in TMX file"); - } - - cur_tmx->map = malloc(sizeof(*cur_tmx->map)); - if (cur_tmx->map == NULL) { - err(1, "Failed to allocate map"); - } - memset(cur_tmx->map, 0, sizeof(*cur_tmx->map)); - - foreach_tmx_attr (attr) { - tmx_get_int_attr(attr, "width", &cur_tmx->map->width); - tmx_get_int_attr(attr, "height", &cur_tmx->map->height); - tmx_get_int_attr(attr, "tilewidth", &cur_tmx->map->tilewidth); - tmx_get_int_attr(attr, "tileheight", &cur_tmx->map->tileheight); - } -} - -static void -tmx_start_tileset(struct tmx *cur_tmx, const char **attr) -{ - struct tileset *new_tileset; - - if (cur_tmx->map == NULL) { - err(1, "Malformed TMX file"); - } - - new_tileset = malloc(sizeof(*new_tileset)); - if (new_tileset == NULL) { - err(1, "Failed to allocate tileset"); - } - memset(new_tileset, 0, sizeof(*new_tileset)); - - if (cur_tmx->cur_tileset == NULL) { - cur_tmx->map->tilesets = new_tileset; - } else { - cur_tmx->cur_tileset->next = new_tileset; - } - cur_tmx->cur_tileset = new_tileset; - - foreach_tmx_attr (attr) { - tmx_get_int_attr(attr, "firstgid", - &cur_tmx->cur_tileset->firstgid); - tmx_get_int_attr(attr, "tilewidth", - &cur_tmx->cur_tileset->tilewidth); - tmx_get_int_attr(attr, "tileheight", - &cur_tmx->cur_tileset->tileheight); - } - - /* TODO: Parse tilesets referenced in "source" attributes. */ -} - -static void -tmx_start_image(struct tmx *cur_tmx, const char **attr) -{ - char *source; - char *path; - - if (cur_tmx->cur_tileset == NULL) { - err(1, "Malformed TMX file"); - } - - source = NULL; - foreach_tmx_attr (attr) { - tmx_get_string_attr(attr, "source", source); - } - if (source == NULL) { - err(1, "No \"source\" attribute found in \"image\" tag"); - } - - /* TODO: Move to end tag handler and check for "loadimage" property. */ - path = malloc(strlen(cur_tmx->dirname) + strlen(source) + 2); - if (path == NULL) { - err(1, "Failed to allocate resource path string"); - } - sprintf(path, "%s/%s", cur_tmx->dirname, source); - cur_tmx->cur_tileset->image = img_png_get(path); - free(path); - - debug(" Found tileset with firstgid %d and source \"%s\"", - cur_tmx->cur_tileset->firstgid, source); - - free(source); -} - -static void -tmx_start_layer(struct tmx *cur_tmx, const char **attr) -{ - struct layer *new_layer; - - if (cur_tmx->map == NULL) { - err(1, "Malformed TMX file"); - } - - new_layer = malloc(sizeof(*new_layer)); - if (new_layer == NULL) { - err(1, "Failed to allocate layer"); - } - memset(new_layer, 0, sizeof(*new_layer)); - - if (cur_tmx->cur_layer == NULL) { - cur_tmx->map->layers = new_layer; - } else { - cur_tmx->cur_layer->next = new_layer; - } - cur_tmx->cur_layer = new_layer; - - foreach_tmx_attr (attr) { - tmx_get_string_attr(attr, "name", cur_tmx->cur_layer->name); - } - - debug(" Found layer with name \"%s\"", cur_tmx->cur_layer->name); -} - -static void -tmx_start_data(struct tmx *cur_tmx, const char **attr) -{ - if (cur_tmx->cur_layer == NULL) { - err(1, "Malformed TMX file"); - } - - foreach_tmx_attr (attr) { - if (strcmp(attr[0], "encoding") == 0) { - if (strcmp(attr[1], "base64") == 0) { - cur_tmx->data_encoding = TMX_DATA_ENC_BASE64; - } else if (strcmp(attr[1], "csv") == 0) { - cur_tmx->data_encoding = TMX_DATA_ENC_CSV; - } else { - err(1, "Unsupported data encoding in TMX file"); - } - } else if (strcmp(attr[0], "compression") == 0) { - if (strcmp(attr[1], "gzip") == 0) { - cur_tmx->data_compression = TMX_DATA_COMP_GZIP; - } else if (strcmp(attr[1], "zlib") == 0) { - cur_tmx->data_compression = TMX_DATA_COMP_ZLIB; - } else { - err(1, "Unsupported compression in TMX file"); - } - } - } -} - -static void XMLCALL -tmx_start(void *data, const char *el, const char **attr) -{ - struct tmx *cur_tmx; - - cur_tmx = (struct tmx *) data; - - if (strcmp(el, "map") == 0) { - tmx_start_map(cur_tmx, attr); - cur_tmx->parsing = TMX_PARSING_MAP; - } else if (strcmp(el, "tileset") == 0) { - tmx_start_tileset(cur_tmx, attr); - cur_tmx->parsing = TMX_PARSING_TILESET; - } else if (strcmp(el, "image") == 0) { - tmx_start_image(cur_tmx, attr); - cur_tmx->parsing = TMX_PARSING_IMAGE; - } else if (strcmp(el, "layer") == 0) { - tmx_start_layer(cur_tmx, attr); - cur_tmx->parsing = TMX_PARSING_LAYER; - } else if (strcmp(el, "data") == 0) { - tmx_start_data(cur_tmx, attr); - cur_tmx->parsing = TMX_PARSING_DATA; - } - - /* TODO: Handle objectgroup, object, properties, and property tags. */ -} - -static void -tmx_end_data(struct tmx *cur_tmx) -{ - size_t decoded_len; - size_t decomp_len; - char *decoded_buf; - char *decomp_buf; - - decoded_len = strlen(cur_tmx->layer_data); - - decomp_len = 4 * cur_tmx->map->width * cur_tmx->map->height; - debug(" Expected map data size: %d", decomp_len); - - decoded_buf = malloc(decoded_len + 1); - if (decoded_buf == NULL) { - err(1, "Failed to allocate map layer data buffer"); - } - - if (cur_tmx->data_encoding == TMX_DATA_ENC_BASE64) { - debug(" Decoding base 64 layer data..."); - base64_decode(cur_tmx->layer_data, - decoded_buf, decoded_len + 1); - } - - if (cur_tmx->data_compression == TMX_DATA_COMP_NONE) { - debug(" Layer data already decompressed"); - decomp_buf = decoded_buf; - } else if (cur_tmx->data_compression == TMX_DATA_COMP_ZLIB) { - debug(" Decompressing layer data with zlib..."); - decomp_buf = malloc(decomp_len); - if (decomp_buf == NULL) { - err(1, "Failed to allocate map layer data buffer"); - } - decompress(decoded_buf, decoded_len, decomp_buf, decomp_len); - free(decoded_buf); - } else if (cur_tmx->data_compression == TMX_DATA_COMP_GZIP) { - debug(" Decompressing layer data with gzip..."); - decomp_buf = malloc(decomp_len); - if (decomp_buf == NULL) { - err(1, "Failed to allocate map layer data buffer"); - } - decompress(decoded_buf, decoded_len, decomp_buf, decomp_len); - free(decoded_buf); - } else { - /* This should never happen. This branch exists only to silence - * GCC's maybe-uninitialized warning on decomp_buf below. */ - return; - } - - free(cur_tmx->layer_data); - - cur_tmx->cur_layer->tiles = (Uint32 *) decomp_buf; -} - -static void XMLCALL -tmx_end(void *data, const char *el) -{ - struct tmx *cur_tmx; - - cur_tmx = (struct tmx *) data; - - if (strcmp(el, "data") == 0) { - tmx_end_data(cur_tmx); - } - - cur_tmx->parsing = TMX_PARSING_NONE; -} - -static void XMLCALL -tmx_data(void *data, const char *s, int len) -{ - struct tmx *cur_tmx; - char *s_z; - char *s_z_trimmed, *s_z_trimmed_end; - - cur_tmx = (struct tmx *) data; - - if (cur_tmx->parsing != TMX_PARSING_DATA) { - return; - } - - s_z = s_z_trimmed = strndup(s, len); - - while(isspace(*s_z_trimmed)) { - ++s_z_trimmed; - --len; - } - if (*s_z_trimmed == '\0') { - return; - } - s_z_trimmed_end = s_z_trimmed + len - 1; - while (s_z_trimmed_end > s_z_trimmed && isspace(*s_z_trimmed_end)) { - --s_z_trimmed_end; - } - *(s_z_trimmed_end + 1) = '\0'; - - cur_tmx->layer_data = strdup(s_z_trimmed); - - free(s_z); -} - -struct map * -tmx_load(const char *path) -{ - XML_Parser p; - struct tmx cur_tmx; - char *path_dup; - FILE *tmx_fp; - void *tmx_buf; - size_t len; - - debug("Parsing TMX file \"%s\"...", path); - - p = XML_ParserCreate(NULL); - if (p == NULL) { - err(1, "Failed to create TMX parser"); - } - - XML_SetElementHandler(p, tmx_start, tmx_end); - XML_SetCharacterDataHandler(p, tmx_data); - - memset(&cur_tmx, 0, sizeof(cur_tmx)); - path_dup = strdup(path); - cur_tmx.dirname = dirname(path_dup); - XML_SetUserData(p, &cur_tmx); - - tmx_fp = fopen(path, "rb"); - if (tmx_fp == NULL) { - err(1, "Failed to open TMX file"); - } - - tmx_buf = XML_GetBuffer(p, 8192); - if (tmx_buf == NULL) { - err(1, "Failed to create TMX parse buffer"); - } - - while (!feof(tmx_fp)) { - len = fread(tmx_buf, 1, 8192, tmx_fp); - if (XML_ParseBuffer(p, len, feof(tmx_fp)) == XML_STATUS_ERROR) { - err(1, "Failed to parse TMX file (%s)", - XML_ErrorString(XML_GetErrorCode(p))); - } - } - - fclose(tmx_fp); - - free(path_dup); - - return cur_tmx.map; -} diff --git a/src/tmx.h b/src/tmx.h deleted file mode 100644 index e2ab766..0000000 --- a/src/tmx.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef TMX_H -#define TMX_H - -#include "map.h" - -struct map *tmx_load(const char *path); - -#endif |