Mercurial > molko
diff tools/map/map.c @ 116:0a6683615c73
cmake: change build system, continue #2487 @3h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 03 Oct 2020 18:32:01 +0200 |
parents | tools/molko-map.c@d4a72fa16225 |
children | 70e6ed74940d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/map/map.c Sat Oct 03 18:32:01 2020 +0200 @@ -0,0 +1,304 @@ +/* + * molko-map.c -- convert tiled tiled JSON files into custom files + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdnoreturn.h> +#include <string.h> + +#include <jansson.h> + +static void +die(const char *fmt, ...) +{ + assert(fmt); + + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +static bool +is_layer(const char *name) +{ + return strcmp(name, "background") == 0 || + strcmp(name, "foreground") == 0 || + strcmp(name, "objects") == 0; +} + +static const json_t * +find_property(const json_t *props, const char *which) +{ + json_t *value; + size_t index; + + json_array_foreach(props, index, value) { + if (!json_is_object(value)) + continue; + + const json_t *key = json_object_get(value, "name"); + + if (json_is_string(key) && strcmp(json_string_value(key), which) == 0) + return value; + } + + return NULL; +} + +static void +write_title(const json_t *props) +{ + const json_t *prop_title = find_property(props, "title"); + + if (!prop_title) + return; + + const json_t *title = json_object_get(prop_title, "value"); + + if (title && json_is_string(title)) + printf("title|%s\n", json_string_value(title)); +} + +static void +write_origin(const json_t *props) +{ + const json_t *prop_origin_x = find_property(props, "origin-x"); + const json_t *prop_origin_y = find_property(props, "origin-y"); + + if (!prop_origin_x || !prop_origin_y) + return; + + const json_t *origin_x = json_object_get(prop_origin_x, "value"); + const json_t *origin_y = json_object_get(prop_origin_y, "value"); + + if (!origin_x || !json_is_integer(origin_x) || + !origin_y || !json_is_integer(origin_y)) + return; + + printf("origin|%lld|%lld\n", json_integer_value(origin_x), + json_integer_value(origin_y)); +} + +static void +write_properties(const json_t *props) +{ + write_title(props); + write_origin(props); +} + +static void +write_metadata(const json_t *document) +{ + json_t *width = json_object_get(document, "width"); + json_t *height = json_object_get(document, "height"); + json_t *tilewidth = json_object_get(document, "tilewidth"); + json_t *tileheight = json_object_get(document, "tileheight"); + + if (!width || !json_is_integer(width)) + die("missing 'width' property\n"); + if (!height || !json_is_integer(height)) + die("missing 'height' property\n"); + if (!tilewidth || !json_is_integer(tilewidth)) + die("missing 'tilewidth' property\n"); + if (!tileheight || !json_is_integer(tileheight)) + die("missing 'tileheight' property\n"); + + printf("width|%lld\n", json_integer_value(width)); + printf("height|%lld\n", json_integer_value(height)); + printf("tilewidth|%lld\n", json_integer_value(tilewidth)); + printf("tileheight|%lld\n", json_integer_value(tileheight)); +} + +static void +write_object_property(int id, const json_t *property) +{ + assert(json_is_object(property)); + + json_t *name = json_object_get(property, "name"); + json_t *type = json_object_get(property, "type"); + json_t *value = json_object_get(property, "value"); + + if (!name || !json_is_string(name)) + die("invalid 'name' property in object"); + if (!type || !json_is_string(type)) + die("invalid 'type' property in object"); + if (!value || !json_is_string(value)) + die("invalid 'value' property in object"); + + printf("object-property|%d|%s|%s\n", + id, + json_string_value(name), + json_string_value(value) + ); +} + +static void +write_object(const json_t *object) +{ + assert(json_is_object(object)); + + json_t *id = json_object_get(object, "id"); + json_t *x = json_object_get(object, "x"); + json_t *y = json_object_get(object, "y"); + json_t *width = json_object_get(object, "width"); + json_t *height = json_object_get(object, "height"); + json_t *type = json_object_get(object, "type"); + json_t *props = json_object_get(object, "properties"); + + if (!id || !json_is_integer(id)) + die("invalid 'id' property in object\n"); + if (!x || !json_is_real(x)) + die("invalid 'x' property in object\n"); + if (!y || !json_is_real(y)) + die("invalid 'y' property in object\n"); + if (!width || !json_is_real(width)) + die("invalid 'width' property in object\n"); + if (!height || !json_is_real(height)) + die("invalid 'height' property in object\n"); + if (!type || !json_is_string(type)) + die("invalid 'type' property in object\n"); + + /* In tiled, those properties are float but we only use ints in MA */ + printf("object|%lld|%s|%d|%d|%d|%d\n", + json_integer_value(id), + json_string_value(type), + (int)json_real_value(x), + (int)json_real_value(y), + (int)json_real_value(width), + (int)json_real_value(height) + ); + + if (json_is_array(props)) { + json_t *prop; + size_t index; + + json_array_foreach(props, index, prop) { + if (!json_is_object(prop)) + die("invalid property in object\n"); + + write_object_property(json_integer_value(id), prop); + } + } +} + +static void +write_layer(const json_t *layer) +{ + json_t *objects = json_object_get(layer, "objects"); + json_t *data = json_object_get(layer, "data"); + json_t *name = json_object_get(layer, "name"); + json_t *tile, *object; + size_t index; + + if (!name || !json_is_string(name)) + die("invalid 'name' property in layer"); + if (!is_layer(json_string_value(name))) + die("invalid 'name' layer: %s\n", json_string_value(name)); + + printf("layer|%s\n", json_string_value(name)); + + /* Only foreground/background have 'data' property */ + if (json_is_array(data)) { + json_array_foreach(data, index, tile) { + if (!json_is_integer(tile)) + die("invalid 'data' property in layer\n"); + + printf("%lld\n", json_integer_value(tile)); + } + } + + /* Only objects has 'objects' property */ + if (json_is_array(objects)) { + json_array_foreach(objects, index, object) { + if (!json_is_object(object)) + die("invalid 'objects' property in layer\n"); + + write_object(object); + } + } +} + +static void +write_layers(const json_t *layers) +{ + size_t index; + json_t *layer; + + if (!layers) + return; + + json_array_foreach(layers, index, layer) { + if (!json_is_object(layer)) + die("layer is not an object\n"); + + write_layer(layer); + } +} + +static void +write_tileset(const json_t *tileset) +{ + json_t *image = json_object_get(tileset, "image"); + + if (!image || !json_is_string(image)) + die("invalid 'image' property in tileset"); + + printf("tileset|%s\n", json_string_value(image)); +} + +static void +write_tilesets(const json_t *tilesets) +{ + json_t *tileset; + size_t index; + + if (!json_is_array(tilesets)) + die("invalid 'tilesets' property"); + + json_array_foreach(tilesets, index, tileset) { + if (!json_is_object(tileset)) + die("invalid tileset"); + + write_tileset(tileset); + } +} + +int +main(void) +{ + json_t *document; + json_error_t error; + + document = json_loadf(stdin, 0, &error); + + if (!document) + die("%d:%d: %s\n", error.line, error.column, error.text); + + write_properties(json_object_get(document, "properties")); + write_metadata(document); + write_layers(json_object_get(document, "layers")); + write_tilesets(json_object_get(document, "tilesets")); + + json_decref(document); +}