refactored tilemap_load to use tiled xml format
This commit is contained in:
parent
b9e4599d7e
commit
661af077b2
109
src/tilemap.c
109
src/tilemap.c
|
@ -1,54 +1,95 @@
|
||||||
#include "tilemap.h"
|
#include "tilemap.h"
|
||||||
|
#include "libxml/threads.h"
|
||||||
|
#include "libxml/tree.h"
|
||||||
|
#include "libxml/xmlstring.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <libxml/xinclude.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
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 = {
|
struct Tilemap self = {
|
||||||
.dimensions = {1,1},
|
.dimensions = {1,1},
|
||||||
.tiles = NULL
|
.tiles = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
FILE* fs = fopen(tilemap_file, "r");
|
xmlDocPtr doc = xmlParseFile(tilemap_file);
|
||||||
int n = 0;
|
if(doc == NULL) {
|
||||||
do {
|
printf("Failed to load tilemap file '%s'\n", tilemap_file);
|
||||||
n = fgetc(fs);
|
self.dimensions.x = self.dimensions.y = 0;
|
||||||
if(n == ',') {
|
return self;
|
||||||
self.dimensions.x++;
|
|
||||||
}
|
}
|
||||||
} while(n != '\n');
|
|
||||||
do {
|
xmlNodePtr reader = xmlDocGetRootElement(doc);
|
||||||
n = fgetc(fs);
|
if(reader == NULL) {
|
||||||
if(n == '\n') {
|
printf("Failed to find map node in tilemap '%s'\n", tilemap_file);
|
||||||
self.dimensions.y++;
|
self.dimensions.x = self.dimensions.y = 0;
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
} while(n != '\0');
|
|
||||||
|
|
||||||
rewind(fs);
|
reader = reader->children;
|
||||||
|
|
||||||
|
do {
|
||||||
|
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));
|
self.tiles = malloc(self.dimensions.x * self.dimensions.y * sizeof(int));
|
||||||
|
printf("reading layer data\n");
|
||||||
char csv_buffer[6];
|
tilemap_get_tiles_from_xml(doc, reader, self.tiles, self.dimensions.x * self.dimensions.y);
|
||||||
csv_buffer[5] = '\0';
|
} else if(xmlStrcmp(reader->name, XML("objectgroup"))) {
|
||||||
char* writer = csv_buffer;
|
|
||||||
int* tile = self.tiles;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
} while(n != '\0');
|
reader = reader->next;
|
||||||
|
} while(reader != NULL);
|
||||||
|
|
||||||
fclose(fs);
|
xmlFreeDoc(doc);
|
||||||
|
|
||||||
self.tileset = tileset_load(tileset_file);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct Tilemap {
|
||||||
struct Tileset tileset;
|
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 struct Tileset tileset_load(const char* filename);
|
||||||
extern SDL_Rect tileset_index_to_rect(struct Tileset* self, size_t index);
|
extern SDL_Rect tileset_index_to_rect(struct Tileset* self, size_t index);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue