99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
import sys
|
|
import json
|
|
import shared
|
|
|
|
TEMPLATE = """
|
|
// generated code! be nice
|
|
#include "sys/sys.h"
|
|
|
|
sys_maptile map_{{map_name}}_data[{{width * height}}] = { {{ tiles|join(",") }} };
|
|
sys_map map_{{map_name}} = {
|
|
.tiles=map_{{map_name}}_data,
|
|
.width={{width}},
|
|
.height={{height}},
|
|
};
|
|
|
|
{% for entity_type in entity_types %}
|
|
void map_{{map_name}}_{{entity_type}}_create(sys_i32 x, sys_i32 y);
|
|
{% endfor %}
|
|
|
|
void map_{{map_name}}_create_entities() {
|
|
{% for entity in entities %}
|
|
map_{{map_name}}_{{entity.type}}_create({{entity.x}}, {{entity.y}});
|
|
{% endfor %}
|
|
}
|
|
""".lstrip()
|
|
|
|
def main(map_name, fname_ldtk, fname_c):
|
|
width, height, tiles, entities = load_mapdata(fname_ldtk)
|
|
|
|
with open(fname_c, "wt") as output:
|
|
output.write(
|
|
shared.templates.from_string(TEMPLATE).render(
|
|
map_name=map_name,
|
|
tiles=tiles,
|
|
width=width,
|
|
height=height,
|
|
entity_types=sorted(set(i["type"] for i in entities)),
|
|
entities=entities,
|
|
)
|
|
)
|
|
|
|
|
|
def load_mapdata(fname_ldtk):
|
|
sparse_tiles = {}
|
|
entities = []
|
|
|
|
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"]:
|
|
if layer["__identifier"] == "conceptual":
|
|
# for right now I use the vague layer to assign tiles
|
|
for tile in layer["autoLayerTiles"]:
|
|
x, y = tile["px"]
|
|
x //= 8
|
|
y //= 8
|
|
ix = tile["t"]
|
|
sparse_tiles[level_x + x, level_y + y] = ix
|
|
|
|
if layer["__identifier"] == "entities":
|
|
for e in layer["entityInstances"]:
|
|
# TODO: Other fields?
|
|
entities.append({
|
|
"type": e["__identifier"],
|
|
"x": e["__worldX"] // 8,
|
|
"y": e["__worldY"] // 8,
|
|
})
|
|
|
|
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(255)
|
|
|
|
return width, height, dense_tiles, entities
|
|
|
|
|
|
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]) |