28.07.2017

New release: libTMX ver. 1.0


libTMX version 1.0 has just been released!

Reminder: libTMX is an open source C library to load maps made with Tiled, its name comes from the extension of map file: .tmx.

This is a milestone! 1.0 is always a special version for every project, even for small projects.
I have been maintaining that C library for more than four years now, and its version numbers have always followed those of the supported Tiled release.

Even though I do not really decide on version numbers, I wanted to make that release special and implement many new features!

Here's the changelog:

New Features:

  • Use a hashtable to store properties
  • Add more IO options: load maps from a file descriptor, a buffer or using a callback
  • Add a tileset manager to hold references to external tilesets

First, a long time requested feature: access properties via their names. Since the removal of support for JSON formatted map, the XML parser has been the only supported parser, hence it became mandatory (you cannot build libTMX without the XML parser). Therefore libxml2 has became a compulsory dependency of libTMX. Now I have to share a little secret ... libxml2 has an implementation for the hashtable datastructure! I just added a few fuctions that delegate to libxml2's implementation.

/* Returns the tmx_property from given hashtable and key, returns NULL if not found */
TMXEXPORT tmx_property* tmx_get_property(tmx_properties *hash, const char *key);/* ForEach callback type to be used with function tmx_property_foreach(...) */
typedef void (*tmx_property_functor)(tmx_property *property, void *userdata);
/* Calls `callback` for each entry in the property hashtable, order of entries is random */
TMXEXPORT void tmx_property_foreach(tmx_properties *hash, tmx_property_functor callback, void *userdata);

Second, another requested feature, TMX should be able to load a map from a buffer, as libxml2's reader accepts many kind of IO as input, once again I just added new functions that delegates to libxml2.

/* Loads a map from file at `path` and returns the head of the data structure
   returns NULL if an error occurred and set tmx_errno */
TMXEXPORT tmx_map* tmx_load(const char *path);/* Loads a map from file at `path` and returns the head of the data structure
   returns NULL if an error occurred and set tmx_errno */
TMXEXPORT tmx_map* tmx_load_buffer(const char *buffer, int len);/* Loads a map from a file descriptor and returns the head of the data structure
   The file descriptor will not be closed
   returns NULL if an error occurred and set tmx_errno */
TMXEXPORT tmx_map* tmx_load_fd(int fd);/* allback used by tmx_load to delegate reading to client code
   userdata(in): user data passed to tmx_load()
   buffer(in): to store read bytes
   len: how many bytes to read (length of buffer) */
typedef int (*tmx_read_functor)(void *userdata, char *buffer, int len);
/* Loads a map using the given read callback and returns the head of the data structure
   returns NULL if an error occurred and set tmx_errno */
TMXEXPORT tmx_map* tmx_load_callback(tmx_read_functor callback, void *userdata);

The main addition here is the tileset manager, its main purpose is to avoid loading tilesets multiple times, another benefit is to preload tilesets to make them available when using the new IO load methods.

/* Tileset Manager type (private hashtable) */
typedef void tmx_tileset_manager;/* Creates a Tileset Manager that holds a hashtable of loaded tilesets
   Only external tilesets (in .TSX files) are indexed in a tileset manager
   This is particularly useful to only load once tilesets needed by many maps
   The key is the `source` attribute of a tileset element */
TMXEXPORT tmx_tileset_manager* tmx_make_tileset_manager();/* Frees the tilesetManager and all its loaded Tilesets
   All maps holding a pointer to external tileset loaded by the given manager
   now hold a pointer to freed memory */
TMXEXPORT void tmx_free_tileset_manager(tmx_tileset_manager *ts_mgr);/* Loads a tileset from file at `path` and stores it into given tileset manager
   `path` will be used as the key
   Returns 1 on success */
TMXEXPORT int tmx_load_tileset(tmx_tileset_manager *ts_mgr, const char *path);/* Loads a tileset from a buffer and stores it into given tileset manager
   Returns 1 on success */
TMXEXPORT int tmx_load_tileset_buffer(tmx_tileset_manager *ts_mgr, const char *buffer, int len, const char *key);/* Loads a tileset from a file descriptor and stores it into given tileset manager
   The file descriptor will not be closed
   Returns 1 on success */
TMXEXPORT int tmx_load_tileset_fd(tmx_tileset_manager *ts_mgr, int fd, const char *key);/* Loads a tileset using the given read callback and stores it into given tileset manager
   Returns 1 on success */
TMXEXPORT int tmx_load_tileset_callback(tmx_tileset_manager *ts_mgr, tmx_read_functor callback, void *userdata, const char *key);/*
    Load map using a Tileset Manager
*//* Same as tmx_load (tmx.h) but with a Tileset Manager. */
TMXEXPORT tmx_map* tmx_tsmgr_load(tmx_tileset_manager *ts_mgr, const char *path);/* Same as tmx_load_buffer (tmx.h) but with a Tileset Manager. */
TMXEXPORT tmx_map* tmx_tsmgr_load_buffer(tmx_tileset_manager *ts_mgr, const char *buffer, int len);/* Same as tmx_load_fd (tmx.h) but with a Tileset Manager. */
TMXEXPORT tmx_map* tmx_tsmgr_load_fd(tmx_tileset_manager *ts_mgr, int fd);/* Same as tmx_load_callback (tmx.h) but with a Tileset Manager. */
TMXEXPORT tmx_map* tmx_tsmgr_load_callback(tmx_tileset_manager *ts_mgr, tmx_read_functor callback, void *userdata);

Also, because libxml2 has embedded http and ftp support, you can load maps and tilesets from the internet! just pass the URL to load_tmx(), simple isn't it?

Tiled 1.0 TMX format support:

  • Add text object support
  • Add group layer support
  • Add tile type support

See the TMX format changelog for Tiled 1.0 for more details on these new elements and attributes.