LibTMJ  1.0.0
A library for loading JSON Tiled maps
tileset.c
Go to the documentation of this file.
1 #include <string.h>
2 
3 #include <jansson.h>
4 
5 #include "log.h"
6 #include "map.h"
7 #include "tmj.h"
8 
13 int unpack_tileset(json_t* tileset, Tileset* ret) {
14  logmsg(TMJ_LOG_DEBUG, "Unpacking tileset");
15 
16  if (tileset == NULL) {
17  return -1;
18  }
19 
20  json_error_t error;
21 
22  json_t* grid = NULL;
23  json_t* tileoffset = NULL;
24  json_t* transformations = NULL;
25  json_t* properties = NULL;
26  json_t* terrains = NULL;
27  json_t* tiles = NULL;
28 
29  // Unpack scalar values
30  int unpk = json_unpack_ex(tileset,
31  &error,
32  0,
33  "{"
34  "s?s, s?s, s?s, s:s, s:s, s?s, s?s, s:s, s?s, s?s, s:s, s:s,"
35  "s:i, s?i, s:i, s:i, s:i, s:i, s:i, s:i, s:i,"
36  "s?o, s?o, s?o, s?o, s?o, s?o"
37  "}",
38  "backgroundcolor",
39  &ret->backgroundcolor,
40  "class",
41  &ret->class,
42  "fillmode",
43  &ret->fillmode,
44  "image",
45  &ret->image,
46  "name",
47  &ret->name,
48  "objectalignment",
49  &ret->objectalignment,
50  "source",
51  &ret->source,
52  "tiledversion",
53  &ret->tiledversion,
54  "tilerendersize",
55  &ret->tilerendersize,
56  "transparentcolor",
57  &ret->transparentcolor,
58  "type",
59  &ret->type,
60  "version",
61  &ret->version,
62  "columns",
63  &ret->columns,
64  "firstgid",
65  &ret->firstgid,
66  "imageheight",
67  &ret->imageheight,
68  "imagewidth",
69  &ret->imagewidth,
70  "margin",
71  &ret->margin,
72  "spacing",
73  &ret->spacing,
74  "tilecount",
75  &ret->tilecount,
76  "tileheight",
77  &ret->tileheight,
78  "tilewidth",
79  &ret->tilewidth,
80  "grid",
81  &grid,
82  "tileoffset",
83  &tileoffset,
84  "transformations",
85  &transformations,
86  "properties",
87  &properties,
88  "terrains",
89  &terrains,
90  "tiles",
91  &tiles);
92 
93  if (unpk == -1) {
94  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset, %s at line %d column %d", error.text, error.line, error.column);
95 
96  return -1;
97  }
98 
99  // Unpack Grid
100  if (grid) {
101  ret->grid = calloc(1, sizeof(Grid));
102 
103  if (ret->grid == NULL) {
104  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->grid, the system is out of memory", ret->name);
105 
106  return -1;
107  }
108 
109  unpk = json_unpack_ex(
110  grid, &error, 0, "{s:i, s:s, s:i}", "height", &ret->grid->height, "orientation", &ret->grid->orientation, "width", &ret->grid->width);
111 
112  if (unpk == -1) {
113  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->grid, %s at line %d column %d", ret->name, error.text, error.line, error.column);
114 
115  goto fail_grid;
116  }
117  }
118 
119  // Unpack TileOffset
120  if (tileoffset) {
121  ret->tileoffset = calloc(1, sizeof(TileOffset));
122 
123  if (ret->tileoffset == NULL) {
124  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tileoffset, the system is out of memory", ret->name);
125 
126  goto fail_grid;
127  }
128 
129  unpk = json_unpack_ex(tileoffset, &error, 0, "{s:i, s:i}", "x", &ret->tileoffset->x, "y", &ret->tileoffset->y);
130 
131  if (unpk == -1) {
132  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tileoffset, %s at line %d column %d", ret->name, error.text, error.line, error.column);
133 
134  goto fail_tileoffset;
135  }
136  }
137 
138  // Unpack Transformations
139  if (transformations) {
140  ret->transformations = calloc(1, sizeof(Transformations));
141 
142  if (ret->transformations == NULL) {
143  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->transformations, the system is out of memory", ret->name);
144 
145  goto fail_tileoffset;
146  }
147 
148  unpk = json_unpack_ex(transformations,
149  &error,
150  0,
151  "{s:b, s:b, s:b, s:b}",
152  "hflip",
153  &ret->transformations->hflip,
154  "vfilp",
155  &ret->transformations->vflip,
156  "rotate",
157  &ret->transformations->rotate,
158  "preferuntransformed",
160 
161  if (unpk == -1) {
163  "Unable to unpack tileset[%s]->transformations, %s at line %d column %d",
164  ret->name,
165  error.text,
166  error.line,
167  error.column);
168 
169  goto fail_transformations;
170  }
171  }
172 
173  // Unpack Properties
174  if (properties) {
175  if ((ret->properties = unpack_properties(properties)) == NULL) {
176  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->properties", ret->name);
177 
178  goto fail_transformations;
179  }
180 
181  ret->property_count = json_array_size(properties);
182  }
183 
184  // Unpack Terrains
185  if (terrains) {
186  if (!json_is_array(terrains)) {
187  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->terrains, terrains must be an array of Terrains", ret->name);
188 
189  goto fail_properties;
190  }
191 
192  ret->terrain_count = json_array_size(terrains);
193 
194  ret->terrains = calloc(ret->terrain_count, sizeof(Terrain));
195 
196  if (ret->terrains == NULL) {
197  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->terrains, the system is out of memory", ret->name);
198 
199  goto fail_properties;
200  }
201 
202  size_t idx;
203  json_t* terrain;
204 
205  json_array_foreach(terrains, idx, terrain) {
206  properties = NULL;
207 
208  unpk = json_unpack_ex(terrain,
209  &error,
210  0,
211  "{s:s, s:i, s?o}",
212  "name",
213  &ret->terrains[idx].name,
214  "tile",
215  &ret->terrains[idx].tile,
216  "properties",
217  &properties);
218 
219  if (unpk == -1) {
221  "Unable to unpack tileset[%s]->terrains, %s at line %d column %d",
222  ret->name,
223  error.text,
224  error.line,
225  error.column);
226 
227  goto fail_terrains;
228  }
229 
230  if (properties) {
231  if ((ret->terrains[idx].properties = unpack_properties(properties)) == NULL) {
232  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->terrain[%s]->properties", ret->name, ret->terrains[idx].name);
233 
234  goto fail_terrains;
235  }
236 
237  ret->terrains[idx].property_count = json_array_size(properties);
238  }
239  }
240  }
241 
242  // Unpack Tiles
243  if (tiles) {
244  if (!json_is_array(tiles)) {
245  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles, tiles must be an array of Tiles", ret->name);
246 
247  goto fail_terrains;
248  }
249 
250  ret->tile_count = json_array_size(tiles);
251 
252  ret->tiles = calloc(ret->tile_count, sizeof(Tile));
253 
254  if (ret->tiles == NULL) {
255  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles, the system is out of memory", ret->name);
256 
257  goto fail_terrains;
258  }
259 
260  size_t idx = 0;
261  json_t* tile = NULL;
262 
263  json_array_foreach(tiles, idx, tile) {
264  // Unpack Tile scalar values
265  json_t* animation = NULL;
266  json_t* objectgroup = NULL;
267  json_t* properties = NULL;
268  json_t* terrain = NULL;
269 
270  unpk = json_unpack_ex(tile,
271  &error,
272  0,
273  "{"
274  "s?s, s?s,"
275  "s:i, s?i, s?i, s?i, s?i, s?i, s?i,"
276  "s?F,"
277  "s?o, s?o, s?o, s?o"
278  "}",
279  "image",
280  &ret->tiles[idx].image,
281  "type",
282  &ret->tiles[idx].type,
283  "id",
284  &ret->tiles[idx].id,
285  "imageheight",
286  &ret->tiles[idx].imageheight,
287  "imagewidth",
288  &ret->tiles[idx].imagewidth,
289  "x",
290  &ret->tiles[idx].x,
291  "y",
292  &ret->tiles[idx].y,
293  "width",
294  &ret->tiles[idx].width,
295  "height",
296  &ret->tiles[idx].height,
297  "probability",
298  &ret->tiles[idx].probability,
299  "animation",
300  &animation,
301  "objectgroup",
302  &objectgroup,
303  "properties",
304  &properties,
305  "terrain",
306  &terrain);
307 
308  if (unpk == -1) {
309  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles, %s at line %d column %d", ret->name, error.text, error.line, error.column);
310 
311  goto fail_tiles;
312  }
313 
314  // Unpack Tile objectgroup
315  if (objectgroup) {
316  ret->tiles[idx].objectgroup = calloc(1, sizeof(Layer));
317 
318  if (ret->tiles[idx].objectgroup == NULL) {
320  "Unable to unpack tileset[%s]->tiles[%d]->objectgroup, the system is out of memory",
321  ret->name,
322  ret->tiles[idx].id);
323 
324  goto fail_tiles;
325  }
326 
327  json_t* objects = NULL;
328  json_t* layer_properties = NULL;
329 
330  unpk = json_unpack_ex(objectgroup,
331  &error,
332  0,
333  "{"
334  "s?b, s:b,"
335  "s?s, s?s, s:s, s?s, s:s,"
336  "s?i, s?i, s?i,"
337  "s?F, s?F, s:F, s?F, s?F,"
338  "s?o, s?o"
339  "}",
340  "locked",
341  &ret->tiles[idx].objectgroup->locked,
342  "visible",
343  &ret->tiles[idx].objectgroup->visible,
344  "class",
345  &ret->tiles[idx].objectgroup->class,
346  "draworder",
347  &ret->tiles[idx].objectgroup->draworder,
348  "name",
349  &ret->tiles[idx].objectgroup->name,
350  "tintcolor",
351  &ret->tiles[idx].objectgroup->tintcolor,
352  "type",
353  &ret->tiles[idx].objectgroup->type,
354  "id",
355  &ret->tiles[idx].objectgroup->id,
356  "x",
357  &ret->tiles[idx].objectgroup->x,
358  "y",
359  &ret->tiles[idx].objectgroup->y,
360  "offsetx",
361  &ret->tiles[idx].objectgroup->offsetx,
362  "offsety",
363  &ret->tiles[idx].objectgroup->offsety,
364  "opacity",
365  &ret->tiles[idx].objectgroup->opacity,
366  "parallaxx",
367  &ret->tiles[idx].objectgroup->parallaxx,
368  "parallaxy",
369  &ret->tiles[idx].objectgroup->parallaxy,
370  "objects",
371  &objects,
372  "properties",
373  &layer_properties);
374 
375  if (unpk == -1) {
377  "Unable to unpack tileset[%s]->tiles[%d]->objectgroup, %s at line %d column %d",
378  ret->name,
379  ret->tiles[idx].id,
380  error.text,
381  error.line,
382  error.column);
383 
384  goto fail_tiles;
385  }
386 
387  if (objects) {
388  ret->tiles[idx].objectgroup->objects = unpack_objects(objects);
389 
390  if (ret->tiles[idx].objectgroup->objects == NULL) {
391  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles[%d]->objectgroup->objects", ret->name, ret->tiles[idx].id);
392 
393  goto fail_tiles;
394  }
395 
396  ret->tiles[idx].objectgroup->object_count = json_array_size(objects);
397  }
398 
399  if (layer_properties) {
400  ret->tiles[idx].objectgroup->properties = unpack_properties(layer_properties);
401 
402  if (ret->tiles[idx].objectgroup->properties == NULL) {
403  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles[%d]->objectgroup->properties", ret->name, ret->tiles[idx].id);
404 
405  goto fail_tiles;
406  }
407 
408  ret->tiles[idx].objectgroup->property_count = json_array_size(layer_properties);
409  }
410  }
411 
412  // Unpack Tile animation
413  if (animation) {
414  if (!json_is_array(animation)) {
416  "Unable to unpack tileset[%s]->tiles[%d]->animation, animation must be an array of Frames",
417  ret->name,
418  ret->tiles[idx].id);
419 
420  goto fail_tiles;
421  }
422 
423  ret->tiles[idx].animation = calloc(json_array_size(animation), sizeof(Frame));
424 
425  if (ret->tiles[idx].animation == NULL) {
427  "Unable to unpack tileset[%s]->tiles[%d]->animation, the system is out of memory",
428  ret->name,
429  ret->tiles[idx].id);
430 
431  goto fail_tiles;
432  }
433 
434  size_t idx2 = 0;
435  json_t* frame = NULL;
436 
437  json_array_foreach(animation, idx2, frame) {
438  unpk = json_unpack_ex(frame,
439  &error,
440  0,
441  "{"
442  "s:i, s:i"
443  "}",
444  "duration",
445  &ret->tiles[idx].animation[idx2].duration,
446  "tileid",
447  &ret->tiles[idx].animation[idx2].tileid);
448 
449  if (unpk == -1) {
451  "Unable to unpack tileset[%s]->tiles[%d]->animation, %s at line %d column %d",
452  ret->name,
453  ret->tiles[idx].id,
454  error.text,
455  error.line,
456  error.column);
457 
458  goto fail_tiles;
459  }
460  }
461 
462  ret->tiles[idx].animation_count = json_array_size(animation);
463  }
464 
465  // Unpack Tile properties
466  if (properties) {
467  ret->tiles[idx].properties = unpack_properties(properties);
468 
469  if (ret->tiles[idx].properties == NULL) {
470  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]->tiles[%d]->properties", ret->name, ret->tiles[idx].id);
471 
472  goto fail_tiles;
473  }
474 
475  ret->tiles[idx].property_count = json_array_size(properties);
476  }
477 
478  // Unpack Tile terrain
479  if (terrain) {
480  if (!json_is_array(terrain)) {
482  "Unable to unpack tileset[%s]->tiles[%d]->terrain, terrain must be an array of terrain "
483  "indexes",
484  ret->name,
485  ret->tiles[idx].id);
486 
487  goto fail_tiles;
488  }
489 
490  size_t idx2 = 0;
491  json_t* terrain_idx = NULL;
492 
493  json_array_foreach(terrain, idx2, terrain_idx) {
494  if (!json_is_integer(terrain_idx)) {
496  "Unable to unpack tileset[%s]->tiles[%d]->terrain, terrain must be an array of "
497  "integers");
498 
499  goto fail_tiles;
500  }
501 
502  ret->tiles[idx].terrain[idx2] = (int)json_integer_value(terrain_idx);
503  }
504  }
505  }
506  }
507 
508  return 0;
509 
510 fail_tiles:
511  for (size_t i = 0; i < ret->tile_count; i++) {
512  free(ret->tiles[i].animation);
513 
514  if (ret->tiles[i].objectgroup != NULL) {
515  free(ret->tiles[i].objectgroup->properties);
517  }
518 
519  free(ret->tiles[i].objectgroup);
520  free(ret->tiles[i].properties);
521  }
522 
523  free(ret->tiles);
524 
525 fail_terrains:
526  for (size_t i = 0; i < ret->terrain_count; i++) {
527  free(ret->terrains[i].properties);
528  }
529 
530  free(ret->terrains);
531 
532 fail_properties:
533  free(ret->properties);
534 
535 fail_transformations:
536  free(ret->transformations);
537 
538 fail_tileoffset:
539  free(ret->tileoffset);
540 
541 fail_grid:
542  free(ret->grid);
543 
544  return -1;
545 }
546 
550 void tilesets_free(Tileset* tilesets, size_t tileset_count) {
551  for (size_t i = 0; i < tileset_count; i++) {
552  // Free tiles
553  if (tilesets[i].tiles) {
554  for (size_t j = 0; j < tilesets[i].tile_count; j++) {
555  free(tilesets[i].tiles[j].animation);
556  if (tilesets[i].tiles[j].objectgroup != NULL) {
557  free(tilesets[i].tiles[j].objectgroup->properties);
558  free_objects(tilesets[i].tiles[j].objectgroup->objects, tilesets[i].tiles[j].objectgroup->object_count);
559  }
560  free(tilesets[i].tiles[j].objectgroup);
561  free(tilesets[i].tiles[j].properties);
562  }
563 
564  free(tilesets[i].tiles);
565  }
566 
567  // Free terrains
568  if (tilesets[i].terrains) {
569  for (size_t j = 0; j < tilesets[i].terrain_count; j++) {
570  free(tilesets[i].terrains[j].properties);
571  }
572 
573  free(tilesets[i].terrains);
574  }
575 
576  // Free everything else
577  free(tilesets[i].properties);
578  free(tilesets[i].transformations);
579  free(tilesets[i].tileoffset);
580  free(tilesets[i].grid);
581 
582  json_decref(tilesets[i].root);
583  }
584 
585  free(tilesets);
586 }
587 
588 Tileset* tmj_tileset_loadf(const char* path, bool check_extension) {
589  logmsg(TMJ_LOG_DEBUG, "Loading JSON tileset file '%s'", path);
590 
591  char* ext = strrchr(path, '.');
592 
593  if (check_extension) {
594  if (ext == NULL) {
595  logmsg(TMJ_LOG_ERR, "Tileset filename '%s' has no extension", path);
596 
597  return NULL;
598  }
599 
600  if (strcmp(ext, ".tsj") != 0 && strcmp(ext, ".json") != 0) {
601  logmsg(TMJ_LOG_ERR, "Tileset filename '%s' has unknown extension, '%s'", path, ext);
602  logmsg(TMJ_LOG_ERR, "Tileset filename '%s' must have '.tsj' or '.json' extension to be loaded", path);
603 
604  return NULL;
605  }
606  }
607 
608  json_error_t error;
609  json_t* root = json_load_file(path, JSON_REJECT_DUPLICATES, &error);
610 
611  if (root == NULL) {
612  logmsg(TMJ_LOG_ERR, "Could not load tileset '%s', %s at line %d column %d", path, error.text, error.line, error.column);
613 
614  return NULL;
615  }
616 
617  Tileset* ret = calloc(1, sizeof(Tileset));
618 
619  if (ret == NULL) {
620  logmsg(TMJ_LOG_ERR, "Unable to load tileset[%s], the system is out of memory", path);
621 
622  return NULL;
623  }
624 
625  if (unpack_tileset(root, ret) == -1) {
626  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset[%s]", path);
627 
628  free(ret);
629 
630  return NULL;
631  }
632 
633  ret->root = root;
634 
635  return ret;
636 }
637 
638 Tileset* tmj_tileset_load(const char* tileset) {
639  logmsg(TMJ_LOG_DEBUG, "Loading JSON tileset from string");
640 
641  json_error_t error;
642  json_t* root = json_loads(tileset, JSON_REJECT_DUPLICATES, &error);
643 
644  if (root == NULL) {
645  logmsg(TMJ_LOG_ERR, "Could not load tileset, %s at line %d column %d", error.text, error.line, error.column);
646 
647  return NULL;
648  }
649 
650  Tileset* ret = calloc(1, sizeof(Tileset));
651 
652  if (ret == NULL) {
653  logmsg(TMJ_LOG_ERR, "Unable to load tileset, the system is out of memory");
654 
655  return NULL;
656  }
657 
658  if (unpack_tileset(root, ret) == -1) {
659  logmsg(TMJ_LOG_ERR, "Unable to unpack tileset");
660 
661  free(ret);
662 
663  return NULL;
664  }
665 
666  ret->root = root;
667 
668  return ret;
669 }
670 
671 void tmj_tileset_free(Tileset* tileset) {
672  tilesets_free(tileset, 1);
673 }
void logmsg(tmj_log_priority priority, char *msg,...)
Processes log messages and passes them to the active logging callback, if there is one.
Definition: log.c:23
void tmj_tileset_free(Tileset *tileset)
Frees the memory associated with the given tileset.
Definition: tileset.c:671
Tileset * tmj_tileset_load(const char *tileset)
Loads the Tiled tileset from the given JSON object string.
Definition: tileset.c:638
Tileset * tmj_tileset_loadf(const char *path, bool check_extension)
Loads the Tiled tileset at the given path.
Definition: tileset.c:588
@ TMJ_LOG_ERR
Definition: tmj.h:500
@ TMJ_LOG_DEBUG
Definition: tmj.h:497
Object * unpack_objects(json_t *objects)
Definition: map.c:257
Property * unpack_properties(json_t *properties)
Definition: map.c:13
void free_objects(Object *objects, size_t object_count)
Helper function to free Objects.
Definition: map.c:423
https://doc.mapeditor.org/en/stable/reference/json-map-format/#frame
Definition: tmj.h:202
int tileid
Definition: tmj.h:204
int duration
Definition: tmj.h:203
https://doc.mapeditor.org/en/stable/reference/json-map-format/#grid
Definition: tmj.h:283
int height
Definition: tmj.h:286
int width
Definition: tmj.h:287
char * orientation
Definition: tmj.h:284
https://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
Definition: tmj.h:127
char * class
Definition: tmj.h:133
size_t property_count
Definition: tmj.h:173
int x
Definition: tmj.h:155
char * tintcolor
Definition: tmj.h:139
char * draworder
Definition: tmj.h:135
Property * properties
Definition: tmj.h:174
double offsetx
Definition: tmj.h:158
double parallaxy
Definition: tmj.h:162
Object * objects
Definition: tmj.h:171
double opacity
Definition: tmj.h:160
double parallaxx
Definition: tmj.h:161
char * type
Definition: tmj.h:141
bool locked
Definition: tmj.h:128
int y
Definition: tmj.h:156
size_t object_count
Definition: tmj.h:170
char * name
Definition: tmj.h:138
int id
Definition: tmj.h:151
double offsety
Definition: tmj.h:159
bool visible
Definition: tmj.h:131
https://doc.mapeditor.org/en/stable/reference/json-map-format/#terrain
Definition: tmj.h:190
Property * properties
Definition: tmj.h:196
char * name
Definition: tmj.h:191
int tile
Definition: tmj.h:193
size_t property_count
Definition: tmj.h:195
https://doc.mapeditor.org/en/stable/reference/json-map-format/#tile-offset
Definition: tmj.h:293
int y
Definition: tmj.h:295
int x
Definition: tmj.h:294
https://doc.mapeditor.org/en/stable/reference/json-map-format/#tile-definition
Definition: tmj.h:210
Frame * animation
Definition: tmj.h:225
int terrain[4]
Definition: tmj.h:227
int height
Definition: tmj.h:220
double probability
Definition: tmj.h:222
int y
Definition: tmj.h:218
int id
Definition: tmj.h:214
char * image
Definition: tmj.h:211
char * type
Definition: tmj.h:212
int x
Definition: tmj.h:217
size_t animation_count
Definition: tmj.h:224
int imageheight
Definition: tmj.h:215
Property * properties
Definition: tmj.h:230
Layer * objectgroup
Definition: tmj.h:232
int imagewidth
Definition: tmj.h:216
size_t property_count
Definition: tmj.h:229
int width
Definition: tmj.h:219
https://doc.mapeditor.org/en/stable/reference/json-map-format/#tileset
Definition: tmj.h:303
char * fillmode
Definition: tmj.h:312
size_t tile_count
Definition: tmj.h:339
char * transparentcolor
Definition: tmj.h:319
int tileheight
Definition: tmj.h:330
char * name
Definition: tmj.h:314
char * image
Definition: tmj.h:313
Grid * grid
Definition: tmj.h:345
int imagewidth
Definition: tmj.h:326
char * tiledversion
Definition: tmj.h:317
char * objectalignment
Definition: tmj.h:315
char * source
Definition: tmj.h:316
int firstgid
Definition: tmj.h:324
TileOffset * tileoffset
Definition: tmj.h:347
int tilewidth
Definition: tmj.h:331
char * tilerendersize
Definition: tmj.h:318
size_t property_count
Definition: tmj.h:333
size_t terrain_count
Definition: tmj.h:336
int margin
Definition: tmj.h:327
char * class
Definition: tmj.h:311
Property * properties
Definition: tmj.h:334
json_t * root
The root object returned by jansson after parsing.
Definition: tmj.h:308
int tilecount
Definition: tmj.h:329
char * backgroundcolor
Definition: tmj.h:310
int columns
Definition: tmj.h:323
char * version
Definition: tmj.h:321
Transformations * transformations
Definition: tmj.h:349
Tile * tiles
Definition: tmj.h:340
Terrain * terrains
Definition: tmj.h:337
int spacing
Definition: tmj.h:328
char * type
Definition: tmj.h:320
int imageheight
Definition: tmj.h:325
https://doc.mapeditor.org/en/stable/reference/json-map-format/#transformations
Definition: tmj.h:180
bool preferuntransformed
Definition: tmj.h:182
bool hflip
Definition: tmj.h:181
bool rotate
Definition: tmj.h:183
bool vflip
Definition: tmj.h:184
int unpack_tileset(json_t *tileset, Tileset *ret)
Definition: tileset.c:13
void tilesets_free(Tileset *tilesets, size_t tileset_count)
Helper function for freeing tilesets embedded in maps.
Definition: tileset.c:550
The libtmj API.