Rework scripts to work for single tileset
This commit is contained in:
@@ -1,11 +1,19 @@
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class ExtractFileWriter:
|
||||
indent_width = 4
|
||||
indent_level = 0
|
||||
indention = ""
|
||||
content = ""
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name.upper()
|
||||
|
||||
def to_file(self, path):
|
||||
with open(path, "w") as f:
|
||||
f.write(self.content)
|
||||
|
||||
def indent(self):
|
||||
self.indent_level += self.indent_width
|
||||
self.indention = " " * self.indent_level
|
||||
@@ -14,51 +22,274 @@ class ExtractFileWriter:
|
||||
self.indent_level -= self.indent_width
|
||||
self.indention = " " * self.indent_level
|
||||
|
||||
def output_anim_sequence_struct(self):
|
||||
self.output("typedef struct AnimationSequence {\n")
|
||||
self.indent()
|
||||
self.output("BzTile startFrame;\n")
|
||||
self.output("i32 frameCount;\n")
|
||||
self.unindent()
|
||||
self.output("} AnimationSequence;\n")
|
||||
self.empty_line()
|
||||
|
||||
def output_anim_frame_struct(self):
|
||||
self.output("typedef struct AnimationFrame {\n")
|
||||
self.indent()
|
||||
self.output("BzTile frame;\n")
|
||||
self.output("f32 duration;\n")
|
||||
self.unindent()
|
||||
self.output("} AnimationFrame;\n")
|
||||
self.empty_line()
|
||||
|
||||
def header_guard_start(self):
|
||||
print(f"#ifndef {self.name}")
|
||||
print(f"#define {self.name}")
|
||||
print()
|
||||
self.content += f"#ifndef {self.name}_H\n"
|
||||
self.content += f"#define {self.name}_H\n"
|
||||
self.content += "\n"
|
||||
|
||||
def header_guard_stop(self):
|
||||
print(f"#endif // {self.name}")
|
||||
self.content += f"#endif // {self.name}_H\n"
|
||||
|
||||
def include(self, header):
|
||||
print(f"${self.indention}#include {header}")
|
||||
self.content += f"{self.indention}#include {header}\n"
|
||||
|
||||
def enum_start(self, name):
|
||||
print(f"{self.indention}typedef enum {name} {{")
|
||||
self.content += f"{self.indention}typedef enum {name} {{\n"
|
||||
self.indent()
|
||||
|
||||
def enum_stop(self, name):
|
||||
self.unindent()
|
||||
print(f"}} {name};")
|
||||
print()
|
||||
self.content += f"}} {name};\n\n"
|
||||
|
||||
def enum_list(self, name, enums):
|
||||
self.enum_start(name)
|
||||
for enum in enums:
|
||||
print(f"{self.indention}{enum},")
|
||||
self.content += f"{self.indention}{enum},\n"
|
||||
self.enum_stop(name)
|
||||
|
||||
def enum_dict(self, name, enums):
|
||||
self.enum_start(name)
|
||||
for enum, v in enums.items():
|
||||
print(f"{self.indention}{enum} = {v},")
|
||||
self.content += f"{self.indention}{enum} = {v},\n"
|
||||
self.enum_stop(name)
|
||||
|
||||
def output(self, out):
|
||||
print(f"{self.indention}{out}", end="")
|
||||
self.content += self.indention
|
||||
self.content += out
|
||||
|
||||
def output_line(self):
|
||||
print()
|
||||
def empty_line(self):
|
||||
self.content += '\n'
|
||||
|
||||
def only_output(self, out):
|
||||
print(out, end="")
|
||||
self.content += out
|
||||
|
||||
def block_start(self):
|
||||
print(f"{{")
|
||||
self.content += f"{{\n"
|
||||
self.indent()
|
||||
|
||||
def block_end(self):
|
||||
self.unindent()
|
||||
print(f"{self.indention}}}")
|
||||
self.content += f"{self.indention}}}\n"
|
||||
|
||||
|
||||
def group_by_class(tiles):
|
||||
groups = defaultdict(list)
|
||||
for tile in tiles:
|
||||
if 'type' not in tile:
|
||||
continue
|
||||
tile_class = tile['type']
|
||||
groups[tile_class].append(tile)
|
||||
return groups
|
||||
|
||||
|
||||
class EnumWriter:
|
||||
def __init__(self, writer: ExtractFileWriter, prefix, tiles):
|
||||
self.writer = writer
|
||||
self.prefix = prefix
|
||||
self.all_tiles = tiles
|
||||
self.tiles = group_by_class(tiles)
|
||||
self.enums = []
|
||||
self.enums += [self.to_enum(x) for x in self.tiles.keys()]
|
||||
self.enums.append(self.to_enum("count"))
|
||||
self.enums.append(self.to_enum("none"))
|
||||
self.enum_type = f"{prefix.capitalize()}Type"
|
||||
|
||||
def to_enum(self, name):
|
||||
return f"{self.prefix.upper()}_{name.upper()}"
|
||||
|
||||
def to_anim_enum(self, name):
|
||||
return f"ANIM_{name.upper()}"
|
||||
|
||||
def output_enum(self):
|
||||
self.writer.enum_list(self.enum_type, self.enums)
|
||||
|
||||
def output_tile_to_enum(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static {self.enum_type} {func_name}(BzTile tile) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (tile) ")
|
||||
writer.block_start()
|
||||
|
||||
for key, tiles in self.tiles.items():
|
||||
ids = [x['id'] for x in tiles]
|
||||
for id in ids:
|
||||
writer.output(f"case {id}:\n")
|
||||
writer.output(f" return {self.to_enum(key)};\n")
|
||||
writer.output(f"default:\n")
|
||||
writer.output(f" return {self.enums[-1]};\n")
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_enum_to_tile(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static {self.enum_type} {func_name}({self.enum_type} type) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (type) ")
|
||||
writer.block_start()
|
||||
|
||||
for key, tiles in self.tiles.items():
|
||||
ids = sorted([x['id'] for x in tiles])
|
||||
writer.output(f"case {self.to_enum(key)}: return {ids[0]};\n")
|
||||
writer.output(f"default: return -1;\n")
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_str_to_enum(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static {self.enum_type} {func_name}(const char *str) ")
|
||||
writer.block_start()
|
||||
|
||||
for name in self.tiles.keys():
|
||||
writer.output(f"if (strncmp(\"{name}\", str, {len(name)}) == 0) return {self.to_enum(name)};\n")
|
||||
writer.output(f"return {self.enums[-1]};\n")
|
||||
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_enum_to_str(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static const char *{func_name}({self.enum_type} type) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (type) ")
|
||||
writer.block_start()
|
||||
|
||||
for name in self.tiles.keys():
|
||||
writer.output(f"case {self.to_enum(name)}: return \"{name}\";\n")
|
||||
writer.output(f"default: return NULL;\n")
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_enum_tile_size(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(
|
||||
f"static {self.enum_type} {func_name}({self.enum_type} type, BzTile *outWidth, BzTile *outHeight) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (type) ")
|
||||
writer.block_start()
|
||||
|
||||
for key, tiles in self.tiles.items():
|
||||
ids = [x['id'] for x in tiles]
|
||||
w = 1
|
||||
h = 1
|
||||
for curr, next in zip(ids, ids[1:]):
|
||||
if next > curr + 1:
|
||||
h += 1
|
||||
elif h == 1:
|
||||
w += 1
|
||||
writer.output(f"case {self.to_enum(key)}:\n")
|
||||
writer.indent()
|
||||
writer.output(f"if (outWidth) *outWidth = {w};\n")
|
||||
writer.output(f"if (outHeight) *outHeight = {h};\n")
|
||||
writer.output("break;\n")
|
||||
writer.unindent()
|
||||
writer.output("default:\n")
|
||||
writer.indent()
|
||||
writer.output("if (outWidth) *outWidth = 0;\n")
|
||||
writer.output("if (outHeight) *outHeight = 0;\n")
|
||||
writer.output("break;\n")
|
||||
writer.unindent()
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_tile_has_anim(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static bool {func_name}(BzTile tile) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (tile) ")
|
||||
writer.block_start()
|
||||
ids = sorted([x['id'] for x in self.all_tiles if 'animation' in x])
|
||||
for id in ids:
|
||||
writer.output(f"case {id}:\n")
|
||||
writer.indent()
|
||||
writer.output("return true;\n")
|
||||
writer.unindent()
|
||||
writer.output("default:\n")
|
||||
writer.indent()
|
||||
writer.output("return false;\n")
|
||||
writer.unindent()
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_tile_anim_sequence(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static AnimationSequence {func_name}(BzTile tile) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (tile) ")
|
||||
writer.block_start()
|
||||
anim_tiles = [x for x in self.all_tiles if 'animation' in x]
|
||||
for tile in anim_tiles:
|
||||
anim = tile['animation']
|
||||
num_frames = len(anim)
|
||||
anim_id = min([x['tileid'] for x in anim])
|
||||
ret = f"(AnimationSequence) {{.startFrame = {anim_id}, .frameCount = {num_frames}}}"
|
||||
writer.output(f"case {tile['id']}: return {ret};\n")
|
||||
writer.output("default:\n")
|
||||
writer.indent()
|
||||
writer.output("BZ_ASSERT(0);\n")
|
||||
writer.output("return (AnimationSequence) {0, 0};\n")
|
||||
writer.unindent()
|
||||
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
def output_tile_anim_frame(self, func_name):
|
||||
writer = self.writer
|
||||
writer.output(f"static AnimationFrame {func_name}(BzTile tile, i32 frameIdx) ")
|
||||
writer.block_start()
|
||||
|
||||
writer.output("switch (tile) ")
|
||||
writer.block_start()
|
||||
anim_tiles = [x for x in self.all_tiles if 'animation' in x]
|
||||
for tile in anim_tiles:
|
||||
anim = tile['animation']
|
||||
# num_frames = len(anim)
|
||||
frames = [str(x['tileid']) for x in anim]
|
||||
durations = [str(x['duration']) for x in anim]
|
||||
|
||||
anim_frames = [f"{{{frame}, {duration}}}" for frame, duration in zip(frames, durations)]
|
||||
|
||||
ret = f"((AnimationFrame []) {{{', '.join(anim_frames)}}}) [frameIdx]"
|
||||
writer.output(f"case {tile['id']}: return {ret};\n")
|
||||
writer.output("default:\n")
|
||||
writer.indent()
|
||||
writer.output("BZ_ASSERT(0);\n")
|
||||
writer.output("return (AnimationFrame) {0, 0};\n")
|
||||
writer.unindent()
|
||||
writer.block_end()
|
||||
writer.block_end()
|
||||
writer.empty_line()
|
||||
|
||||
Reference in New Issue
Block a user