Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for reading tile properties. #5

Merged
merged 3 commits into from
May 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions src/tmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ tmx_map* tmx_load(const char *path) {
const char *extension;
FILE *file;
int fchar;

if (!tmx_alloc_func) tmx_alloc_func = realloc;
if (!tmx_free_func) tmx_free_func = free;

/* is 'path' a JSON or a XML file ? */
extension = strrchr(path, '.'); /* First using the file extension */
if (extension && (!strcmp(extension, ".tmx") || !strcmp(extension, ".xml"))) {
Expand Down Expand Up @@ -57,7 +57,7 @@ tmx_map* tmx_load(const char *path) {
}
}
}

return map;
}

Expand Down Expand Up @@ -106,12 +106,21 @@ static void free_layers(tmx_layer *l) {
}
}

static void free_tiles(tmx_tile *t) {
if (t) {
free_tiles(t->next);
free_props(t->properties);
tmx_free_func(t);
}
}

static void free_ts(tmx_tileset *ts) {
if (ts) {
free_ts(ts->next);
tmx_free_func(ts->name);
free_image(ts->image);
free_props(ts->properties);
free_tiles(ts->tiles);
tmx_free_func(ts);
}
}
Expand All @@ -125,44 +134,77 @@ void tmx_map_free(tmx_map *map) {
}
}

tmx_tileset* tmx_get_tile(tmx_map *map, unsigned int gid, unsigned int *x, unsigned int *y) {
tmx_tileset* tmx_get_tileset(tmx_map *map, unsigned int gid, unsigned int *x, unsigned int *y) {
unsigned int tiles_x_count;
unsigned int ts_w, id, tx, ty;
tmx_tileset *ts;

if (!map) {
tmx_err(E_INVAL, "tmx_get_tile: invalid argument: map is NULL");
return NULL;
}

if (!x || !y) {
tmx_err(E_INVAL, "tmx_get_tile: invalid argument: x or y is NULL");
return NULL;
}

gid &= TMX_FLIP_BITS_REMOVAL;
ts = map->ts_head;

while (ts) {
if (ts->firstgid <= gid) {
if (!ts->next || ts->next->firstgid < ts->firstgid || ts->next->firstgid > gid) {
id = gid - ts->firstgid; /* local id (for this image) */

ts_w = ts->image->width - 2 * (ts->margin) + ts->spacing;

tiles_x_count = ts_w / (ts->tile_width + ts->spacing);

tx = id % tiles_x_count;
ty = id / tiles_x_count;

*x = ts->margin + (tx * ts->tile_width) + (tx * ts->spacing); /* set bitmap's region */
*y = ts->margin + (ty * ts->tile_height) + (ty * ts->spacing); /* x and y coordinates */
return ts;
}
}
ts = ts->next;
}

return NULL;
}

tmx_tile* tmx_get_tile(tmx_map *map, unsigned int gid) {
int id;
tmx_tileset *ts;
tmx_tile* t;

if (!map) {
tmx_err(E_INVAL, "tmx_get_tile: invalid argument: map is NULL");
return NULL;
}

gid &= TMX_FLIP_BITS_REMOVAL;
ts = map->ts_head;

while (ts) {
if (ts->firstgid <= gid) {
if (!ts->next || ts->next->firstgid < ts->firstgid || ts->next->firstgid > gid) {
id = gid - ts->firstgid; /* local id (for this tile) */

t = ts->tiles;

while (t) {
if (t->id == id) {
return t;
}
t = t->next;
}
}
}
ts = ts->next;
}

return NULL;
}
22 changes: 16 additions & 6 deletions src/tmx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Copyright (c) 2013-2014, Bayle Jonathan <baylej@github>

Data Stuctures storing the map and functions prototypes

See : (I'm using names from this documentation)
https://github.com/bjorn/tiled/wiki/TMX-Map-Format
*/
Expand Down Expand Up @@ -60,6 +60,12 @@ typedef struct _tmx_img { /* <image> */
void *resource_image;
} tmx_image;

typedef struct _tmx_tile { /* <tile> */
unsigned int id;
tmx_property *properties;
struct _tmx_tile *next;
} tmx_tile;

typedef struct _tmx_ts { /* <tileset> and <tileoffset> */
unsigned int firstgid;
char *name;
Expand All @@ -69,6 +75,7 @@ typedef struct _tmx_ts { /* <tileset> and <tileoffset> */
/* terraintypes(0.9), tile(0.9) are for the QtTiled terrain feature */
tmx_image *image;
tmx_property *properties;
tmx_tile *tiles;
struct _tmx_ts *next;
} tmx_tileset;

Expand All @@ -90,14 +97,14 @@ typedef struct _tmx_layer { /* <layer>+<data> <objectgroup>+<object> */
int color; /* bytes : RGB */
double opacity;
char visible; /* 0 == false */

enum tmx_layer_type type;
union layer_content {
int32_t *gids;
tmx_object *head;
tmx_image *image;
}content;

void *user_data; /* not freed by tmx_free ! */
tmx_property *properties;
struct _tmx_layer *next;
Expand All @@ -108,7 +115,7 @@ typedef struct _tmx_map { /* <map> (Head of the data structure) */
unsigned int width, height;
unsigned int tile_width, tile_height;
int backgroundcolor; /* bytes : RGB */

tmx_property *properties;
tmx_tileset *ts_head;
tmx_layer *ly_head;
Expand All @@ -127,7 +134,10 @@ void tmx_map_free(tmx_map *map);

/* returns the tileset and the upper-left coordinate on the tileset
of the tile associated with this gid, returns NULL if it fails */
tmx_tileset* tmx_get_tile(tmx_map *map, unsigned int gid, unsigned int *x, unsigned int *y);
tmx_tileset* tmx_get_tileset(tmx_map *map, unsigned int gid, unsigned int *x, unsigned int *y);

/* returns the tile associated with this gid, returns NULL if it fails */
tmx_tile* tmx_get_tile(tmx_map *map, unsigned int gid);

/*
Error handling
Expand Down Expand Up @@ -166,4 +176,4 @@ const char* tmx_strerr(void); /* FIXME errno parameter ? (as strerror) */
}
#endif

#endif /* TMX_H */
#endif /* TMX_H */
37 changes: 30 additions & 7 deletions src/tmx_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static int pjson_objects(json_t *obj_el, tmx_object **obj_headaddr) {
o->next = *obj_headaddr;
*obj_headaddr = o;

if (json_unpack_ex(obj_el, &err, 0, "{s:i, s:i, s:i, s:i, s:b, s:s}",
if (json_unpack_ex(obj_el, &err, 0, "{s:i, s:i, s:i, s:i, s:b, s:s}",
"height", &(o->height), "width", &(o->width),
"x", &(o->x), "y", &(o->y),
"visible", &(o->visible), "name", &name)) {
Expand Down Expand Up @@ -131,7 +131,7 @@ static int pjson_layer(json_t *lay_el, tmx_layer **lay_headaddr, const char *fil
lay->next = *lay_headaddr;
*lay_headaddr = lay;

if (json_unpack_ex(lay_el, &err, 0, "{s:b, s:F, s:s, s:s}",
if (json_unpack_ex(lay_el, &err, 0, "{s:b, s:F, s:s, s:s}",
"visible", &(lay->visible), "opacity", &(lay->opacity),
"type", &type, "name", &name)) {
tmx_err(E_MISSEL, "json parser: (layer) %s", err.text);
Expand Down Expand Up @@ -185,6 +185,25 @@ static int pjson_layer(json_t *lay_el, tmx_layer **lay_headaddr, const char *fil

return 1;
}
static int pjson_tile(json_t *tile_el, tmx_tile **tile_headaddr) {
tmx_tile *tile;
const char *key;
json_t *val;

json_object_foreach(tile_el, key, val) {
if (!(tile = alloc_tile())) return 0;
tile->next = *tile_headaddr;
*tile_headaddr = tile;

tile->id = atoi(key);

if (json_is_object(val)) {
if (!pjson_properties(val, &(tile->properties))) return 0;
}
}

return 1;
}

static int pjson_tileset(json_t *tls_el, tmx_tileset **tst_headaddr, const char *filename) {
json_error_t err;
Expand All @@ -197,7 +216,7 @@ static int pjson_tileset(json_t *tls_el, tmx_tileset **tst_headaddr, const char
ts->next = *tst_headaddr;
*tst_headaddr = ts;

if (json_unpack_ex(tls_el, &err, 0, "{s:i, s:i, s:i, s:i, s:i, s:i, s:i, s:s, s:s}",
if (json_unpack_ex(tls_el, &err, 0, "{s:i, s:i, s:i, s:i, s:i, s:i, s:i, s:s, s:s}",
"spacing", &(ts->spacing), "margin", &(ts->margin),
"tileheight", &(ts->tile_height), "tilewidth", &(ts->tile_width),
"imageheight", &(ts->image->height), "imagewidth", &(ts->image->width),
Expand All @@ -217,6 +236,10 @@ static int pjson_tileset(json_t *tls_el, tmx_tileset **tst_headaddr, const char
if (!pjson_properties(tmp, &(ts->properties))) return 0;
}

if ((tmp = json_object_get(tls_el, "tileproperties")) && json_is_object(tmp)) {
if (!pjson_tile(tmp, &(ts->tiles))) return 0;
}

return 1;
}

Expand All @@ -227,17 +250,17 @@ static tmx_map* pjson_map(json_t *map_el, const char *filename) {
tmx_map *res;
char *col, *orient;
int i;

if (!(res = alloc_map())) return NULL;

if (json_unpack_ex(map_el, &err, 0, "{s:i, s:i, s:i, s:i, s:s}",
if (json_unpack_ex(map_el, &err, 0, "{s:i, s:i, s:i, s:i, s:s}",
"height", &(res->height), "width", &(res->width),
"tileheight", &(res->tile_height), "tilewidth", &(res->tile_width),
"orientation", &orient)) {
tmx_err(E_MISSEL, "json parser: %s", err.text);
goto cleanup;
}

if ((res->orient = parse_orient(orient)) == O_NONE) {
tmx_err(E_JDATA, "json parser: unsupported 'orientation' '%s'", orient);
goto cleanup;
Expand Down Expand Up @@ -272,7 +295,7 @@ tmx_map* parse_json(const char *filename) {
tmx_map *res = NULL;
json_t *parsed = NULL;
json_error_t err;

/* set memory alloc/free functions pointers */
json_set_alloc_funcs(json_malloc, tmx_free_func);

Expand Down
Loading