Import LDTK maps

This commit is contained in:
Pyrex 2024-02-26 19:51:26 -08:00
parent f6d942c614
commit 055b3dd7b1
7 changed files with 2282 additions and 4 deletions

View File

@ -2,8 +2,8 @@ load("@bazel_skylib//rules:run_binary.bzl", "run_binary")
cc_library(
name = "game",
srcs = glob(["*.c"]) + [":art/game_demo_sprites.c"],
hdrs = glob(["*.h"]) + [":art/game_demo_sprites.h"],
srcs = glob(["*.c"]) + [":art/game_demo_sprites.c", ":map/game_map.c"],
hdrs = glob(["*.h"]) + [":art/game_demo_sprites.h", ":map/game_map.h"],
visibility = ["//visibility:public"],
deps = ["//device:device", "//sys:sys"]
)
@ -20,4 +20,16 @@ run_binary(
srcs = [":art/game_demo_sprites.png"],
outs = [":art/game_demo_sprites.c"],
tool = "//pytools:spritesheet",
)
run_binary(
name = "game_map",
args = [
"game_map",
"$(location :map/crocparty.ldtk)",
"$(location :map/game_map.c)",
],
srcs = [":map/crocparty.ldtk"],
outs = [":map/game_map.c"],
tool = "//pytools:mapdata"
)

2155
game/map/crocparty.ldtk Normal file

File diff suppressed because one or more lines are too long

5
game/map/game_map.h Normal file
View File

@ -0,0 +1,5 @@
#ifndef CROCPARTY_GAME_MAP_H
#define CROCPARTY_GAME_MAP_H
#endif

View File

@ -18,4 +18,14 @@ py_binary(
requirement("Jinja2"),
],
visibility = ["//visibility:public"],
)
py_binary(
name = "mapdata",
srcs = ["mapdata.py", "shared.py"],
deps = [
requirement("pillow"),
requirement("Jinja2"),
],
visibility = ["//visibility:public"],
)

90
pytools/mapdata.py Normal file
View File

@ -0,0 +1,90 @@
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])

View File

@ -16,7 +16,7 @@ sys_sprite {{spritesheet_name}}_data[{{n_sprites}}] = {
{%- endfor %}
};
sys_spritesheet {{spritesheet_name}} = {
.sprites=&{{spritesheet_name}}_data,
.sprites={{spritesheet_name}}_data,
.width={{width}},
.height={{height}},
};

View File

@ -10,6 +10,7 @@
typedef int32_t sys_i32;
typedef uint8_t sys_color;
typedef uint8_t sys_maptile;
typedef uint32_t sys_screen_color;
typedef uint64_t sys_glyph;
typedef struct {
@ -20,6 +21,11 @@ typedef struct {
uint32_t width;
uint32_t height;
} sys_spritesheet;
typedef struct {
sys_maptile* tiles;
uint32_t width;
uint32_t height;
} sys_map;
sys_screen_color sys_make_screen_color(uint8_t r, uint8_t g, uint8_t b);
@ -28,4 +34,4 @@ sys_i32 sys_min_i32(sys_i32 x, sys_i32 y);
sys_i32 sys_abs_i32(sys_i32 x);
sys_i32 sys_sgn_i32(sys_i32 x);
#endif // CROCPARTY_SYS_DATA_H
#endif // CROCPARTY_SYS_DATA_H