fixed scroll and added json2tmap tool
[mdlife] / tools / json2tmap / json2tmap.c
diff --git a/tools/json2tmap/json2tmap.c b/tools/json2tmap/json2tmap.c
new file mode 100644 (file)
index 0000000..a7f2a8e
--- /dev/null
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "json.h"
+
+int ispow2(unsigned int x);
+
+int main(int argc, char **argv)
+{
+       int i, x, y, xtiles, ytiles, idx, tileno;
+       long filesz;
+       FILE *fp;
+       struct json_obj json, *jtileobj;
+       struct json_item *jitem;
+       struct json_arr *jtiles;
+       char *buf;
+       uint16_t *tmap;
+
+       if(!argv[1] || !argv[2]) {
+               fprintf(stderr, "Usage: %s <json file> <tilemap file>\n", argv[0]);
+               return 1;
+       }
+
+       if(!(fp = fopen(argv[1], "rb"))) {
+               fprintf(stderr, "failed to open input file: %s\n", argv[1]);
+               return 1;
+       }
+       fseek(fp, 0, SEEK_END);
+       filesz = ftell(fp);
+       rewind(fp);
+
+       if(!(buf = malloc(filesz + 1))) {
+               fprintf(stderr, "failed to load file: %s\n", argv[1]);
+               return 1;
+       }
+       if(fread(buf, 1, filesz, fp) != filesz) {
+               fprintf(stderr, "unexpected EOF while reading %s\n", argv[1]);
+               return 1;
+       }
+       buf[filesz] = 0;
+       fclose(fp);
+
+       if(json_parse(&json, buf) == -1) {
+               return 1;
+       }
+
+       xtiles = (int)json_lookup_num(&json, "tileswide", -1);
+       ytiles = (int)json_lookup_num(&json, "tileshigh", -1);
+       x = (int)json_lookup_num(&json, "tilewidth", 8);
+       y = (int)json_lookup_num(&json, "tileheight", 8);
+       if(x != 8 || y != 8) {
+               fprintf(stderr, "invalid tile size: %dx%d\n", x, y);
+               return 1;
+       }
+       if(!ispow2(xtiles) || xtiles < 32 || xtiles > 128 || !ispow2(ytiles) ||
+                       ytiles < 32 || ytiles > 128) {
+               fprintf(stderr, "invalid tilemap size: %dx%d\n", xtiles, ytiles);
+               return 1;
+       }
+       if(!(jitem = json_find_item(&json, "layers")) || jitem->val.type != JSON_ARR) {
+               fprintf(stderr, "layers array missing\n");
+               return 1;
+       }
+       if(jitem->val.arr.size > 1) {
+               printf("multiple layers found, ignoring all but the first\n");
+               return 1;
+       }
+       if(!(jitem = json_find_item(&jitem->val.arr.val[0].obj, "tiles")) || jitem->val.type != JSON_ARR) {
+               fprintf(stderr, "tiles array missing\n");
+               return 1;
+       }
+       jtiles = &jitem->val.arr;
+
+       if(!(tmap = calloc(xtiles * ytiles, sizeof *tmap))) {
+               fprintf(stderr, "failed to allocate %dx%d tilemap\n", xtiles, ytiles);
+               return 1;
+       }
+
+       for(i=0; i<jtiles->size; i++) {
+               if(jtiles->val[i].type != JSON_OBJ) {
+                       fprintf(stderr, "invalid tiles array\n");
+                       return 1;
+               }
+               jtileobj = &jtiles->val[i].obj;
+
+               if((idx = json_lookup_num(jtileobj, "index", -1)) == -1) {
+                       continue;
+               }
+               x = json_lookup_num(jtileobj, "x", -1);
+               y = json_lookup_num(jtileobj, "y", -1);
+               if(x < 0 || y < 0) continue;
+               tileno = json_lookup_num(jtileobj, "tile", -1);
+
+               tmap[i] = (tileno << 8) | (tileno >> 8);
+               /* TODO flips */
+       }
+
+       if(!(fp = fopen(argv[2], "wb"))) {
+               fprintf(stderr, "failed to open output file: %s\n", argv[2]);
+               return 1;
+       }
+       fwrite(tmap, xtiles * ytiles, sizeof *tmap, fp);
+       fclose(fp);
+       return 0;
+}
+
+int ispow2(unsigned int x)
+{
+       int i, count = 0;
+
+       for(i=0; i<32; i++) {
+               if(x & 1) {
+                       if(++count > 1) return 0;
+               }
+               x >>= 1;
+       }
+       return 1;
+}