comparison 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
comparison
equal deleted inserted replaced
115:3bd0d3a39e30 116:0a6683615c73
1 /*
2 * molko-map.c -- convert tiled tiled JSON files into custom files
3 *
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <stdarg.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdnoreturn.h>
25 #include <string.h>
26
27 #include <jansson.h>
28
29 static void
30 die(const char *fmt, ...)
31 {
32 assert(fmt);
33
34 va_list ap;
35
36 va_start(ap, fmt);
37 vfprintf(stderr, fmt, ap);
38 va_end(ap);
39 exit(1);
40 }
41
42 static bool
43 is_layer(const char *name)
44 {
45 return strcmp(name, "background") == 0 ||
46 strcmp(name, "foreground") == 0 ||
47 strcmp(name, "objects") == 0;
48 }
49
50 static const json_t *
51 find_property(const json_t *props, const char *which)
52 {
53 json_t *value;
54 size_t index;
55
56 json_array_foreach(props, index, value) {
57 if (!json_is_object(value))
58 continue;
59
60 const json_t *key = json_object_get(value, "name");
61
62 if (json_is_string(key) && strcmp(json_string_value(key), which) == 0)
63 return value;
64 }
65
66 return NULL;
67 }
68
69 static void
70 write_title(const json_t *props)
71 {
72 const json_t *prop_title = find_property(props, "title");
73
74 if (!prop_title)
75 return;
76
77 const json_t *title = json_object_get(prop_title, "value");
78
79 if (title && json_is_string(title))
80 printf("title|%s\n", json_string_value(title));
81 }
82
83 static void
84 write_origin(const json_t *props)
85 {
86 const json_t *prop_origin_x = find_property(props, "origin-x");
87 const json_t *prop_origin_y = find_property(props, "origin-y");
88
89 if (!prop_origin_x || !prop_origin_y)
90 return;
91
92 const json_t *origin_x = json_object_get(prop_origin_x, "value");
93 const json_t *origin_y = json_object_get(prop_origin_y, "value");
94
95 if (!origin_x || !json_is_integer(origin_x) ||
96 !origin_y || !json_is_integer(origin_y))
97 return;
98
99 printf("origin|%lld|%lld\n", json_integer_value(origin_x),
100 json_integer_value(origin_y));
101 }
102
103 static void
104 write_properties(const json_t *props)
105 {
106 write_title(props);
107 write_origin(props);
108 }
109
110 static void
111 write_metadata(const json_t *document)
112 {
113 json_t *width = json_object_get(document, "width");
114 json_t *height = json_object_get(document, "height");
115 json_t *tilewidth = json_object_get(document, "tilewidth");
116 json_t *tileheight = json_object_get(document, "tileheight");
117
118 if (!width || !json_is_integer(width))
119 die("missing 'width' property\n");
120 if (!height || !json_is_integer(height))
121 die("missing 'height' property\n");
122 if (!tilewidth || !json_is_integer(tilewidth))
123 die("missing 'tilewidth' property\n");
124 if (!tileheight || !json_is_integer(tileheight))
125 die("missing 'tileheight' property\n");
126
127 printf("width|%lld\n", json_integer_value(width));
128 printf("height|%lld\n", json_integer_value(height));
129 printf("tilewidth|%lld\n", json_integer_value(tilewidth));
130 printf("tileheight|%lld\n", json_integer_value(tileheight));
131 }
132
133 static void
134 write_object_property(int id, const json_t *property)
135 {
136 assert(json_is_object(property));
137
138 json_t *name = json_object_get(property, "name");
139 json_t *type = json_object_get(property, "type");
140 json_t *value = json_object_get(property, "value");
141
142 if (!name || !json_is_string(name))
143 die("invalid 'name' property in object");
144 if (!type || !json_is_string(type))
145 die("invalid 'type' property in object");
146 if (!value || !json_is_string(value))
147 die("invalid 'value' property in object");
148
149 printf("object-property|%d|%s|%s\n",
150 id,
151 json_string_value(name),
152 json_string_value(value)
153 );
154 }
155
156 static void
157 write_object(const json_t *object)
158 {
159 assert(json_is_object(object));
160
161 json_t *id = json_object_get(object, "id");
162 json_t *x = json_object_get(object, "x");
163 json_t *y = json_object_get(object, "y");
164 json_t *width = json_object_get(object, "width");
165 json_t *height = json_object_get(object, "height");
166 json_t *type = json_object_get(object, "type");
167 json_t *props = json_object_get(object, "properties");
168
169 if (!id || !json_is_integer(id))
170 die("invalid 'id' property in object\n");
171 if (!x || !json_is_real(x))
172 die("invalid 'x' property in object\n");
173 if (!y || !json_is_real(y))
174 die("invalid 'y' property in object\n");
175 if (!width || !json_is_real(width))
176 die("invalid 'width' property in object\n");
177 if (!height || !json_is_real(height))
178 die("invalid 'height' property in object\n");
179 if (!type || !json_is_string(type))
180 die("invalid 'type' property in object\n");
181
182 /* In tiled, those properties are float but we only use ints in MA */
183 printf("object|%lld|%s|%d|%d|%d|%d\n",
184 json_integer_value(id),
185 json_string_value(type),
186 (int)json_real_value(x),
187 (int)json_real_value(y),
188 (int)json_real_value(width),
189 (int)json_real_value(height)
190 );
191
192 if (json_is_array(props)) {
193 json_t *prop;
194 size_t index;
195
196 json_array_foreach(props, index, prop) {
197 if (!json_is_object(prop))
198 die("invalid property in object\n");
199
200 write_object_property(json_integer_value(id), prop);
201 }
202 }
203 }
204
205 static void
206 write_layer(const json_t *layer)
207 {
208 json_t *objects = json_object_get(layer, "objects");
209 json_t *data = json_object_get(layer, "data");
210 json_t *name = json_object_get(layer, "name");
211 json_t *tile, *object;
212 size_t index;
213
214 if (!name || !json_is_string(name))
215 die("invalid 'name' property in layer");
216 if (!is_layer(json_string_value(name)))
217 die("invalid 'name' layer: %s\n", json_string_value(name));
218
219 printf("layer|%s\n", json_string_value(name));
220
221 /* Only foreground/background have 'data' property */
222 if (json_is_array(data)) {
223 json_array_foreach(data, index, tile) {
224 if (!json_is_integer(tile))
225 die("invalid 'data' property in layer\n");
226
227 printf("%lld\n", json_integer_value(tile));
228 }
229 }
230
231 /* Only objects has 'objects' property */
232 if (json_is_array(objects)) {
233 json_array_foreach(objects, index, object) {
234 if (!json_is_object(object))
235 die("invalid 'objects' property in layer\n");
236
237 write_object(object);
238 }
239 }
240 }
241
242 static void
243 write_layers(const json_t *layers)
244 {
245 size_t index;
246 json_t *layer;
247
248 if (!layers)
249 return;
250
251 json_array_foreach(layers, index, layer) {
252 if (!json_is_object(layer))
253 die("layer is not an object\n");
254
255 write_layer(layer);
256 }
257 }
258
259 static void
260 write_tileset(const json_t *tileset)
261 {
262 json_t *image = json_object_get(tileset, "image");
263
264 if (!image || !json_is_string(image))
265 die("invalid 'image' property in tileset");
266
267 printf("tileset|%s\n", json_string_value(image));
268 }
269
270 static void
271 write_tilesets(const json_t *tilesets)
272 {
273 json_t *tileset;
274 size_t index;
275
276 if (!json_is_array(tilesets))
277 die("invalid 'tilesets' property");
278
279 json_array_foreach(tilesets, index, tileset) {
280 if (!json_is_object(tileset))
281 die("invalid tileset");
282
283 write_tileset(tileset);
284 }
285 }
286
287 int
288 main(void)
289 {
290 json_t *document;
291 json_error_t error;
292
293 document = json_loadf(stdin, 0, &error);
294
295 if (!document)
296 die("%d:%d: %s\n", error.line, error.column, error.text);
297
298 write_properties(json_object_get(document, "properties"));
299 write_metadata(document);
300 write_layers(json_object_get(document, "layers"));
301 write_tilesets(json_object_get(document, "tilesets"));
302
303 json_decref(document);
304 }