From 68f957d3eb5efe83d0d65a64717a7501c5be1224 Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Thu, 7 Apr 2016 14:21:16 +1000 Subject: [PATCH] Very basic tiled.tmx converter --- tools/mapgen/Makefile | 7 + tools/mapgen/file.c | 39 ++++++ tools/mapgen/file.h | 7 + tools/mapgen/mapgen.c | 138 +++++++++++++++++++ tools/mapgen/mapgen.h | 25 ++++ tools/mapgen/tmx.c | 300 ++++++++++++++++++++++++++++++++++++++++++ tools/mapgen/utils.c | 13 ++ tools/mapgen/utils.h | 4 + 8 files changed, 533 insertions(+) create mode 100644 tools/mapgen/Makefile create mode 100644 tools/mapgen/file.c create mode 100644 tools/mapgen/file.h create mode 100755 tools/mapgen/mapgen.c create mode 100644 tools/mapgen/mapgen.h create mode 100644 tools/mapgen/tmx.c create mode 100644 tools/mapgen/utils.c create mode 100644 tools/mapgen/utils.h diff --git a/tools/mapgen/Makefile b/tools/mapgen/Makefile new file mode 100644 index 0000000..f865c2e --- /dev/null +++ b/tools/mapgen/Makefile @@ -0,0 +1,7 @@ +PROGRAM=./out/mapgen +OBJS=out/mapgen.o out/file.o out/utils.o out/tmx.o +LIBS=-ltmx -lz -lxml2 +EXTRA_CFLAGS= + +include ../../shared/tools.mk + diff --git a/tools/mapgen/file.c b/tools/mapgen/file.c new file mode 100644 index 0000000..248c300 --- /dev/null +++ b/tools/mapgen/file.c @@ -0,0 +1,39 @@ +#include "mapgen.h" + +FILE * +file_openWrite(const char * s, ...) +{ + char buffer[4096]; + va_list args; + va_start(args, s); + vsprintf(buffer, s, args); + va_end(args); + + if (config.verbose) { + printf("Opening %s for writing\n", buffer); + } + + FILE* fp = fopen(buffer, "w+"); + if (!fp) { + abort_("Failed to open %s for writing\n", buffer); + } + return fp; +} + + +FILE * +file_openRead(const char * s, ...) +{ + char buffer[4096]; + va_list args; + va_start(args, s); + vsprintf(buffer, s, args); + va_end(args); + + FILE* fp = fopen(buffer, "r"); + if (!fp) { + abort_("Failed to open %s for reading\n", buffer); + } + return fp; +} + diff --git a/tools/mapgen/file.h b/tools/mapgen/file.h new file mode 100644 index 0000000..f68d4fd --- /dev/null +++ b/tools/mapgen/file.h @@ -0,0 +1,7 @@ +#pragma once + +FILE * +file_openWrite(const char * s, ...); + +FILE * +file_openRead(const char * s, ...); diff --git a/tools/mapgen/mapgen.c b/tools/mapgen/mapgen.c new file mode 100755 index 0000000..94fca7f --- /dev/null +++ b/tools/mapgen/mapgen.c @@ -0,0 +1,138 @@ +#include +#include +#include + +#include "mapgen.h" + +config_t config = { + .verbose = 0, + .bitDepth = 4, + .inputFile = 0 + +}; + + +static unsigned +get_tile_address(tmx_map *m, unsigned int gid) +{ + printf("get_tile_address %d\n", gid); + + tmx_tileset* ts = m->ts_head; + unsigned baseAddress = 0; + while (ts != 0) { + for (unsigned int i = 0; i < ts->tilecount; i++) { + tmx_tile* t = ts->tiles; + if (t[i].id+ts->firstgid == gid) { + unsigned address = baseAddress + (t[i].ul_y * ((ts->image->width/8) * config.bitDepth)) + (t[i].ul_x/8); + printf("%s - baseAddress = %d address = %d\n", ts->name, baseAddress, address); + return address; + } + } + baseAddress += ((ts->image->width/8) * config.bitDepth * ts->image->height); + ts = ts->next; + } + + return 0; +} + + +static void +output_map_asm(tmx_map *m, tmx_layer *l) +{ + if (!l) { + abort_("output_map_asm: empty layer"); + } + + FILE* fp = file_openWrite("%s-map.s", l->name); + + if (l->type == L_LAYER && l->content.gids) { + for (unsigned int x = 0; x < m->width; x++) { + for (unsigned int y = 0; y < m->height; y++) { + fprintf(fp, "\tdc.w %d\n", get_tile_address(m, l->content.gids[(y*m->width)+x] & TMX_FLIP_BITS_REMOVAL)); + } + } + } + fclose(fp); + + if (l) { + if (l->next) { + output_map_asm(m, l->next); + } + } +} + + +static void +process_map(tmx_map *m) +{ + output_map_asm(m, m->ly_head); +} + + +void +usage() +{ + fprintf(stderr, + "%s: --input \n"\ + "options:\n"\ + " --help\n"\ + " --verbose\n", config.argv[0]); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + int c; + tmx_map *m; + + config.argv = argv; + + while (1) { + static struct option long_options[] = { + {"verbose", no_argument, &config.verbose, 1}, + {"help", no_argument, 0, '?'}, + {"input", required_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + + int option_index = 0; + + c = getopt_long (argc, argv, "i:?", long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: + break; + case 'i': + config.inputFile = optarg; + break; + case '?': + usage(); + break; + default: + usage(); + break; + } + } + + + if (config.inputFile == 0) { + usage(); + abort(); + } + + m = tmx_load(config.inputFile); + + if (!m) { + tmx_perror("error"); + } + + process_map(m); + tmx_map_free(m); + + return EXIT_SUCCESS; +} diff --git a/tools/mapgen/mapgen.h b/tools/mapgen/mapgen.h new file mode 100644 index 0000000..02179cb --- /dev/null +++ b/tools/mapgen/mapgen.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "utils.h" +#include "file.h" + +#define str_bool(b) (b==0? "false": "true") + +typedef struct { + int verbose; + char* inputFile; + char** argv; + int bitDepth; +} config_t; + +extern config_t config; diff --git a/tools/mapgen/tmx.c b/tools/mapgen/tmx.c new file mode 100644 index 0000000..2322711 --- /dev/null +++ b/tools/mapgen/tmx.c @@ -0,0 +1,300 @@ +#include "mapgen.h" + +/* + Copyright (c) 2013, Bayle Jonathan + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +void +print_orient(enum tmx_map_orient orient) +{ + switch(orient) { + case O_NONE: printf("none"); break; + case O_ORT: printf("ortho"); break; + case O_ISO: printf("isome"); break; + case O_STA: printf("stagg"); break; + case O_HEX: printf("hexag"); break; + default: printf("unknown"); + } +} + +void +print_stagger_index(enum tmx_stagger_index index) +{ + switch(index) { + case SI_NONE: printf("none"); break; + case SI_EVEN: printf("even"); break; + case SI_ODD: printf("odd"); break; + default: printf("unknown"); + } +} + +void +print_stagger_axis(enum tmx_stagger_axis axis) +{ + switch(axis) { + case SA_NONE: printf("none"); break; + case SA_X: printf("x"); break; + case SA_Y: printf("y"); break; + default: printf("unknown"); + } +} + +void +print_renderorder(enum tmx_map_renderorder ro) +{ + switch(ro) { + case R_NONE: printf("none"); break; + case R_RIGHTDOWN: printf("rightdown"); break; + case R_RIGHTUP: printf("rightup"); break; + case R_LEFTDOWN: printf("leftdown"); break; + case R_LEFTUP: printf("leftup"); break; + default: printf("unknown"); + } +} + +void +print_draworder(enum tmx_objgr_draworder dro) +{ + switch(dro) { + case G_NONE: printf("none"); break; + case G_INDEX: printf("index"); break; + case G_TOPDOWN: printf("topdown"); break; + default: printf("unknown"); + } +} + +void +mk_padding(char pad[11], int depth) { + if (depth>10) depth=10; + if (depth>0) memset(pad, '\t', depth); + pad[depth] = '\0'; +} + +void +dump_prop(tmx_property *p, int depth) +{ + char padding[11]; mk_padding(padding, depth); + + printf("\n%s" "properties={", padding); + if (!p) { + printf(" (NULL) }"); + } else { + while (p) { + printf("\n%s\t" "'%s'='%s'", padding, p->name, p->value); + p = p->next; + } + printf("\n" "%s}", padding); + } +} + +void +print_shape(enum tmx_shape shape) { + switch(shape) { + case S_NONE: printf("none"); break; + case S_SQUARE: printf("square"); break; + case S_ELLIPSE: printf("ellipse"); break; + case S_POLYGON: printf("polygon"); break; + case S_POLYLINE: printf("polyline"); break; + default: printf("unknown"); + } +} + + + +void +dump_image(tmx_image *i, int depth) +{ + char padding[11]; mk_padding(padding, depth); + + printf("\n%s" "image={", padding); + if (i) { + printf("\n%s\t" "source='%s'", padding, i->source); + printf("\n%s\t" "height=%lu", padding, i->height); + printf("\n%s\t" "width=%lu", padding, i->width); + printf("\n%s\t" "uses_trans=%s", padding, str_bool(i->uses_trans)); + printf("\n%s\t" "trans=#%.6X", padding, i->trans); + printf("\n%s}", padding); + } else { + printf(" (NULL) }"); + } +} + +void +dump_points(double **p, int pl) { + int i; + for (i=0; iid); + printf("\n%s\t" "name='%s'", padding, o->name); + printf("\n%s\t" "type='%s'", padding, o->type); + printf("\n%s\t" "shape=", padding); print_shape(o->shape); + printf("\n%s\t" "x=%f", padding, o->x); + printf("\n%s\t" "y=%f", padding, o->y); + printf("\n%s\t" "number of points='%d'", padding, o->points_len); + printf("\n%s\t" "rotation=%f", padding, o->rotation); + printf("\n%s\t" "visible=%s", padding, str_bool(o->visible)); + if (o->points_len) { + printf("\n%s\t" "points=", padding); + dump_points(o->points, o->points_len); + } + dump_prop(o->properties, depth+1); + printf("\n%s}", padding); + } + + if (o && o->next) { + dump_objects(o->next, depth); + } +} + + + +void +dump_tile(tmx_tile *t, unsigned int tilecount) { + unsigned int i, j; + for (i=0; iname); + printf("\n\t" "tilecount=%u", t->tilecount); + printf("\n\t" "firstgid=%u", t->firstgid); + printf("\n\t" "tile_height=%u", t->tile_height); + printf("\n\t" "tile_width=%u", t->tile_width); + printf("\n\t" "firstgid=%u", t->firstgid); + printf("\n\t" "margin=%u", t->margin); + printf("\n\t" "spacing=%u", t->spacing); + printf("\n\t" "x_offset=%d", t->x_offset); + printf("\n\t" "y_offset=%d", t->y_offset); + dump_image(t->image, 1); + dump_tile(t->tiles, t->tilecount); + dump_prop(t->properties, 1); + printf("\n}"); + } else { + printf(" (NULL) }"); + } + + if (t && t->next) { + dump_tileset(t->next); + } +} + + + + +void +dump_layer(tmx_layer *l, unsigned int tc) +{ + unsigned int i; + printf("\nlayer={"); + if (!l) { + printf(" (NULL) }"); + } else { + printf("\n\t" "name='%s'", l->name); + printf("\n\t" "visible=%s", str_bool(l->visible)); + printf("\n\t" "opacity='%f'", l->opacity); + printf("\n\t" "offsetx=%d", l->offsetx); + printf("\n\t" "offsety=%d", l->offsety); + if (l->type == L_LAYER && l->content.gids) { + printf("\n\t" "type=Layer" "\n\t" "tiles="); + for (i=0; icontent.gids[i] & TMX_FLIP_BITS_REMOVAL); + } + } else if (l->type == L_OBJGR) { + printf("\n\t" "color=#%.6X", l->content.objgr->color); + printf("\n\t" "draworder="); print_draworder(l->content.objgr->draworder); + printf("\n\t" "type=ObjectGroup"); + dump_objects(l->content.objgr->head, 1); + } else if (l->type == L_IMAGE) { + printf("\n\t" "type=ImageLayer"); + dump_image(l->content.image, 1); + } + dump_prop(l->properties, 1); + printf("\n}"); + } + + if (l) { + if (l->next) dump_layer(l->next, tc); + } +} + + +void dump_map(tmx_map *m) { + fputs("map={", stdout); + if (m) { + printf("\n\t" "orient="); print_orient(m->orient); + printf("\n\t" "renderorder=%d", m->renderorder); + printf("\n\t" "height=%u", m->height); + printf("\n\t" "width=%u", m->width); + printf("\n\t" "theight=%u", m->tile_height); + printf("\n\t" "twidth=%u", m->tile_width); + printf("\n\t" "bgcol=#%.6X", m->backgroundcolor); + printf("\n\t" "staggerindex="); print_stagger_index(m->stagger_index); + printf("\n\t" "staggeraxis="); print_stagger_axis(m->stagger_axis); + printf("\n\t" "hexsidelength=%d", m->hexsidelength); + } else { + fputs("\n(NULL)", stdout); + } + puts("\n}"); + + if (m) { + dump_tileset(m->ts_head); + dump_layer(m->ly_head, m->height * m->width); + dump_prop(m->properties, 0); + } +} diff --git a/tools/mapgen/utils.c b/tools/mapgen/utils.c new file mode 100644 index 0000000..b013284 --- /dev/null +++ b/tools/mapgen/utils.c @@ -0,0 +1,13 @@ +#include "mapgen.h" + +void +abort_(const char * s, ...) +{ + fprintf(stderr, "%s: ", config.argv[0]); + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} diff --git a/tools/mapgen/utils.h b/tools/mapgen/utils.h new file mode 100644 index 0000000..b771622 --- /dev/null +++ b/tools/mapgen/utils.h @@ -0,0 +1,4 @@ +#pragma once + +void +abort_(const char * s, ...);