diff --git a/src/tilemap.c b/src/tilemap.c index 1d0dd99..58d7595 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -1,54 +1,95 @@ #include "tilemap.h" +#include "libxml/threads.h" +#include "libxml/tree.h" +#include "libxml/xmlstring.h" #include "program.h" #include +#include #include -struct Tilemap tilemap_load(const char* tilemap_file, const char* tileset_file) { +#define XML(__str) (const xmlChar*)__str + +static inline +void tilemap_get_size_from_xml(xmlNodePtr node, int* o_width, int* o_height) { + xmlChar* prop = xmlGetProp(node, XML("width")); + if(prop == NULL) { printf("Nu-uh\n"); return; } + *o_width = atoi((char*)prop); + + prop = xmlGetProp(node, XML("height")); + if(prop == NULL) { printf("Nu-uh\n"); return; } + *o_height = atoi((char*)prop); +} + +static inline +void tilemap_get_tiles_from_xml(xmlDoc* doc, xmlNodePtr node, int* out, int out_len) { + node = node->children; + while(xmlStrcmp(node->name, XML("data")) != 0 && node != NULL) { + node = node->next; + } + + if(node == NULL) { + memset(out, 0x0, out_len * sizeof(int)); + return; + } + + char buffer[5]; buffer[4] = '\0'; + char* buffer_writer = buffer; + int* out_writer = out; + xmlChar* str = xmlNodeGetContent(node); + xmlChar* reader = str; + + while(*reader != '\0') { + while(isspace(*reader)) + reader++; + if(*reader != ',' && *reader != '\0') { + *buffer_writer = (char)*reader; + ++buffer_writer; + } else { + *buffer_writer = '\0'; + buffer_writer = buffer; + *out_writer = atoi(buffer) - 1; + ++out_writer; + } + ++reader; + } +} + +struct Tilemap tilemap_load(const char* tilemap_file) { struct Tilemap self = { .dimensions = {1,1}, .tiles = NULL }; - FILE* fs = fopen(tilemap_file, "r"); - int n = 0; - do { - n = fgetc(fs); - if(n == ',') { - self.dimensions.x++; - } - } while(n != '\n'); - do { - n = fgetc(fs); - if(n == '\n') { - self.dimensions.y++; - } - } while(n != '\0'); + xmlDocPtr doc = xmlParseFile(tilemap_file); + if(doc == NULL) { + printf("Failed to load tilemap file '%s'\n", tilemap_file); + self.dimensions.x = self.dimensions.y = 0; + return self; + } - rewind(fs); + xmlNodePtr reader = xmlDocGetRootElement(doc); + if(reader == NULL) { + printf("Failed to find map node in tilemap '%s'\n", tilemap_file); + self.dimensions.x = self.dimensions.y = 0; + xmlFreeDoc(doc); + return self; + } - self.tiles = malloc(self.dimensions.x * self.dimensions.y * sizeof(int)); - - char csv_buffer[6]; - csv_buffer[5] = '\0'; - char* writer = csv_buffer; - int* tile = self.tiles; + reader = reader->children; do { - n = fgetc(fs); - if(isalnum(n)) { - *writer = n; - ++writer; - } else if(n == ',' || n == '\0' || n == '\n') { - *writer = '\0'; - writer = csv_buffer; - *tile = atoi(csv_buffer); - ++tile; + if(xmlStrcmp(reader->name, XML("layer")) == 0) { + tilemap_get_size_from_xml(reader, &self.dimensions.x, &self.dimensions.y); + printf("sizes: %d %d\n", self.dimensions.x, self.dimensions.y); + self.tiles = malloc(self.dimensions.x * self.dimensions.y * sizeof(int)); + printf("reading layer data\n"); + tilemap_get_tiles_from_xml(doc, reader, self.tiles, self.dimensions.x * self.dimensions.y); + } else if(xmlStrcmp(reader->name, XML("objectgroup"))) { } - } while(n != '\0'); + reader = reader->next; + } while(reader != NULL); - fclose(fs); - - self.tileset = tileset_load(tileset_file); + xmlFreeDoc(doc); return self; } diff --git a/src/tilemap.h b/src/tilemap.h index 3427d87..6cc11a5 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -18,7 +18,7 @@ struct Tilemap { struct Tileset tileset; }; -extern struct Tilemap tilemap_load(const char* tilemap_file, const char* tileset_file); +extern struct Tilemap tilemap_load(const char* tilemap_file); extern struct Tileset tileset_load(const char* filename); extern SDL_Rect tileset_index_to_rect(struct Tileset* self, size_t index);