import sys import json import shared TEMPLATE = """ // generated code! be nice #include "sys/sys.h" sys_i32 {{map_name}}_player_start_x = {{player_start.0}}; sys_i32 {{map_name}}_player_start_y = {{player_start.1}}; sys_maptile {{map_name}}_data[{{width * height}}] = { {{ tiles|join(",") }} }; sys_map {{map_name}} = { .tiles={{map_name}}_data, .width={{width}}, .height={{height}}, }; """.lstrip() def main(map_name, fname_ldtk, fname_c): width, height, tiles, player_start = load_mapdata(fname_ldtk) with open(fname_c, "wt") as output: output.write( shared.templates.from_string(TEMPLATE).render( map_name=map_name, player_start=player_start, tiles=tiles, width=width, height=height, ) ) def load_mapdata(fname_ldtk): sparse_tiles = {} player_start_xy = None with open(fname_ldtk, "rt") as f: data = json.load(f) for level in data["levels"]: level_x = level["worldX"] // 8 level_y = level["worldY"] // 8 for layer in level["layerInstances"]: w = layer["__cWid"] h = layer["__cHei"] if layer["__identifier"] == "vague": # for right now I use the vague layer to assign tiles for x, y, ix in annot_xy(layer["intGridCsv"], w, h): if ix == 0: continue sparse_tiles[level_x + x, level_y + y] = ix if layer["__identifier"] == "entities": for e in layer["entityInstances"]: x, y = e["__grid"] player_start_xy = (level_x + x, level_y + y) assert player_start_xy is not None, "player start not found" x_min = 0 y_min = 0 assert not any(x for (x, _) in sparse_tiles if x < x_min), "level can't be left of (0, 0)" assert not any(y for (_, y) in sparse_tiles if y < y_min), "level can't be up from (0, 0)" width = max(x for (x, _) in sparse_tiles) + 1 height = max(y for (_, y) in sparse_tiles) + 1 dense_tiles = [] for y in range(height): for x in range(width): k = (x, y) if k in sparse_tiles: dense_tiles.append(sparse_tiles[k]) else: dense_tiles.append(0) return width, height, dense_tiles, player_start_xy def annot_xy(lst, w, h): assert len(lst) == w * h for y in range(h): for x in range(w): yield x, y, lst[y * w + x] if __name__ == "__main__": assert len(sys.argv) == 4, \ "there must be three args (map name, src ldtk, out c)" main(sys.argv[1], sys.argv[2], sys.argv[3])