tools/generate: move maps to a new module
This commit is contained in:
parent
b03055c3a5
commit
e37d56b729
2
Makefile
2
Makefile
@ -75,6 +75,6 @@ main.elf: $(OBJ)
|
||||
|
||||
clean: clean-sh
|
||||
clean-sh:
|
||||
rm -rf res
|
||||
rm -rf res gen
|
||||
|
||||
PHONY: generated-headers
|
||||
|
@ -1,207 +1,21 @@
|
||||
from pathlib import Path
|
||||
from pprint import pprint
|
||||
import io
|
||||
import sys
|
||||
|
||||
from parse import parse
|
||||
|
||||
def sorted_map_headers():
|
||||
# hack to remove unused/duplicate underground_path_route_7
|
||||
map_headers = sorted(parse.map_headers, key=lambda m: m.name2)
|
||||
return filter(lambda m: m.name1 != "UndergroundPathRoute7Copy", map_headers)
|
||||
|
||||
def includes():
|
||||
for map_header in sorted_map_headers():
|
||||
block_path = parse.maps_blocks_list[map_header.blocks()]
|
||||
yield f'#include "../res/{block_path}.h"'
|
||||
for tileset_name in sorted(parse.tileset_constants_list):
|
||||
tileset_index = parse.tileset_constants_list[tileset_name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
yield f'#include "../res/{blockset_path}.h"'
|
||||
yield f'#include "../res/{gfx_path}.h"'
|
||||
yield ""
|
||||
|
||||
def struct_start_size_t():
|
||||
return [
|
||||
"struct start_size_t {",
|
||||
"uint8_t const * const start;",
|
||||
"uint32_t size;",
|
||||
"};",
|
||||
]
|
||||
|
||||
def struct_tileset_t():
|
||||
tileset_names = (
|
||||
f"{name.lower()},"
|
||||
for name in sorted(parse.tileset_constants_list)
|
||||
)
|
||||
return [
|
||||
"struct tileset_t {",
|
||||
"start_size_t blockset;",
|
||||
"start_size_t tileset;",
|
||||
"",
|
||||
"enum tileset {",
|
||||
*tileset_names,
|
||||
"};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def struct_map_t():
|
||||
map_names = (
|
||||
f"{map_header.name2.lower()},"
|
||||
for map_header in sorted_map_headers()
|
||||
)
|
||||
return [
|
||||
"struct map_t {",
|
||||
"start_size_t blocks;",
|
||||
"enum tileset_t::tileset tileset;",
|
||||
"uint32_t width;",
|
||||
"uint32_t height;",
|
||||
"",
|
||||
"enum map {",
|
||||
*map_names,
|
||||
"};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def binary_res(path, suffix):
|
||||
# _binary_res_gfx_blocksets_overworld_bst_start
|
||||
name = path.replace('/', '_').replace('.', '_')
|
||||
return f"_binary_res_{name}_{suffix}"
|
||||
|
||||
def start_size_value(path):
|
||||
start = binary_res(path, "start")
|
||||
size = binary_res(path, "size")
|
||||
|
||||
return [
|
||||
f"reinterpret_cast<uint8_t*>(&{start}),",
|
||||
f"reinterpret_cast<uint32_t>(&{size}),",
|
||||
]
|
||||
|
||||
def blockset_tileset(name: str):
|
||||
tileset_index = parse.tileset_constants_list[name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
return [
|
||||
f"[tileset_t::{name.lower()}] = {{",
|
||||
".blockset = {",
|
||||
*start_size_value(blockset_path),
|
||||
"},",
|
||||
".tileset = {",
|
||||
*start_size_value(gfx_path),
|
||||
"}",
|
||||
"},"
|
||||
]
|
||||
|
||||
def tilesets_header():
|
||||
yield "extern const tileset_t tilesets[];"
|
||||
|
||||
def tilesets():
|
||||
yield "const tileset_t tilesets[] = {"
|
||||
for tileset in sorted(parse.tileset_constants_list):
|
||||
yield from blockset_tileset(tileset)
|
||||
yield "};"
|
||||
|
||||
def map(map_header):
|
||||
block_path = parse.maps_blocks_list[map_header.blocks()]
|
||||
map_constant = parse.map_constants_list[map_header.name2]
|
||||
return [
|
||||
f"[map_t::{map_header.name2.lower()}] = {{",
|
||||
".blocks = {",
|
||||
*start_size_value(block_path),
|
||||
"},",
|
||||
f".tileset = tileset_t::{map_header.tileset.lower()},",
|
||||
f".width = {map_constant.width},",
|
||||
f".height = {map_constant.height},",
|
||||
"},",
|
||||
]
|
||||
|
||||
def maps_header():
|
||||
yield "extern const map_t maps[];"
|
||||
|
||||
def maps():
|
||||
yield "const map_t maps[] = {"
|
||||
for map_header in sorted_map_headers():
|
||||
yield from map(map_header)
|
||||
yield "};"
|
||||
|
||||
def _render(out, lines):
|
||||
indent = " "
|
||||
level = 0
|
||||
for l in lines:
|
||||
if l and l[0] == "}":
|
||||
level -= 2
|
||||
assert level >= 0, out.getvalue()
|
||||
|
||||
out.write(indent * level + l + "\n")
|
||||
|
||||
if l and l[-1] == "{":
|
||||
level += 2
|
||||
|
||||
if level == 0 and l and l[-1] == ";":
|
||||
out.write("\n")
|
||||
return out
|
||||
|
||||
def renderer():
|
||||
out = io.StringIO()
|
||||
def render(lines):
|
||||
return _render(out, lines)
|
||||
return render, out
|
||||
|
||||
def generate_maps_header():
|
||||
render, out = renderer()
|
||||
render(includes())
|
||||
render(struct_start_size_t())
|
||||
render(struct_tileset_t())
|
||||
render(struct_map_t())
|
||||
render(tilesets_header());
|
||||
render(maps_header());
|
||||
return out
|
||||
|
||||
def include_maps_header():
|
||||
yield '#include "maps.hpp"'
|
||||
yield ""
|
||||
|
||||
def generate_maps_source():
|
||||
render, out = renderer()
|
||||
render(include_maps_header())
|
||||
render(tilesets())
|
||||
render(maps())
|
||||
return out
|
||||
from generate import maps
|
||||
|
||||
def generate(base_path):
|
||||
files = [
|
||||
(generate_maps_header, "maps.hpp"),
|
||||
(generate_maps_source, "maps.cpp"),
|
||||
(maps.generate_maps_header, "maps.hpp"),
|
||||
(maps.generate_maps_source, "maps.cpp"),
|
||||
]
|
||||
|
||||
for func, filename in files:
|
||||
path = base_path / filename
|
||||
with open(path, 'w') as f:
|
||||
f.write(func().getvalue())
|
||||
print(path)
|
||||
|
||||
# sys.argv[1] is secretly used in parse
|
||||
base_path = Path(sys.argv[2])
|
||||
generate(base_path)
|
||||
|
||||
"""
|
||||
map_headers[0].tileset == 'OVERWORLD'
|
||||
map_headers[0].name1 = 'PalletTown'
|
||||
map_headers[0].name2 = 'PALLET_TOWN'
|
||||
map_headers[0].blocks() == 'PalletTown_Blocks'
|
||||
map_constants_list['PALLET_TOWN'] == MapConstant(10, 19)
|
||||
maps_blocks_list['PalletTown_Blocks'] == 'maps/PalletTown.blk'
|
||||
tileset_constants_list['OVERWORLD'] == 0
|
||||
tileset_headers_list[0].name == 'Overworld'
|
||||
tileset_headers_list[0].blockset() == 'Overworld_Block'
|
||||
tileset_headers_list[0].gfx() == 'Overworld_GFX'
|
||||
gfx_tilesets_list['Overworld_Block'] == 'gfx/blocksets/overworld.bst'
|
||||
gfx_tilesets_list['Overworld_GFX'] == 'gfx/tilesets/overworld.2bpp'
|
||||
"""
|
||||
|
@ -1,3 +1,24 @@
|
||||
from pathlib import Path
|
||||
import io
|
||||
|
||||
prefix = Path(sys.argv[2])
|
||||
def _render(out, lines):
|
||||
indent = " "
|
||||
level = 0
|
||||
for l in lines:
|
||||
if l and l[0] == "}":
|
||||
level -= 2
|
||||
assert level >= 0, out.getvalue()
|
||||
|
||||
out.write(indent * level + l + "\n")
|
||||
|
||||
if l and l[-1] == "{":
|
||||
level += 2
|
||||
|
||||
if level == 0 and l and l[-1] == ";":
|
||||
out.write("\n")
|
||||
return out
|
||||
|
||||
def renderer():
|
||||
out = io.StringIO()
|
||||
def render(lines):
|
||||
return _render(out, lines)
|
||||
return render, out
|
||||
|
166
tools/generate/maps.py
Normal file
166
tools/generate/maps.py
Normal file
@ -0,0 +1,166 @@
|
||||
from parse import parse
|
||||
|
||||
from generate.generate import renderer
|
||||
|
||||
def sorted_map_headers():
|
||||
# hack to remove unused/duplicate underground_path_route_7
|
||||
map_headers = sorted(parse.map_headers, key=lambda m: m.name2)
|
||||
return filter(lambda m: m.name1 != "UndergroundPathRoute7Copy", map_headers)
|
||||
|
||||
def includes():
|
||||
for map_header in sorted_map_headers():
|
||||
block_path = parse.maps_blocks_list[map_header.blocks()]
|
||||
yield f'#include "../res/{block_path}.h"'
|
||||
for tileset_name in sorted(parse.tileset_constants_list):
|
||||
tileset_index = parse.tileset_constants_list[tileset_name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
yield f'#include "../res/{blockset_path}.h"'
|
||||
yield f'#include "../res/{gfx_path}.h"'
|
||||
yield ""
|
||||
|
||||
def struct_start_size_t():
|
||||
return [
|
||||
"struct start_size_t {",
|
||||
"uint8_t const * const start;",
|
||||
"uint32_t size;",
|
||||
"};",
|
||||
]
|
||||
|
||||
def struct_tileset_t():
|
||||
tileset_names = (
|
||||
f"{name.lower()},"
|
||||
for name in sorted(parse.tileset_constants_list)
|
||||
)
|
||||
return [
|
||||
"struct tileset_t {",
|
||||
"start_size_t blockset;",
|
||||
"start_size_t tileset;",
|
||||
"",
|
||||
"enum tileset {",
|
||||
*tileset_names,
|
||||
"};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def struct_map_t():
|
||||
map_names = (
|
||||
f"{map_header.name2.lower()},"
|
||||
for map_header in sorted_map_headers()
|
||||
)
|
||||
return [
|
||||
"struct map_t {",
|
||||
"start_size_t blocks;",
|
||||
"enum tileset_t::tileset tileset;",
|
||||
"uint32_t width;",
|
||||
"uint32_t height;",
|
||||
"",
|
||||
"enum map {",
|
||||
*map_names,
|
||||
"};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def binary_res(path, suffix):
|
||||
# _binary_res_gfx_blocksets_overworld_bst_start
|
||||
name = path.replace('/', '_').replace('.', '_')
|
||||
return f"_binary_res_{name}_{suffix}"
|
||||
|
||||
def start_size_value(path):
|
||||
start = binary_res(path, "start")
|
||||
size = binary_res(path, "size")
|
||||
|
||||
return [
|
||||
f"reinterpret_cast<uint8_t*>(&{start}),",
|
||||
f"reinterpret_cast<uint32_t>(&{size}),",
|
||||
]
|
||||
|
||||
def blockset_tileset(name: str):
|
||||
tileset_index = parse.tileset_constants_list[name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
return [
|
||||
f"[tileset_t::{name.lower()}] = {{",
|
||||
".blockset = {",
|
||||
*start_size_value(blockset_path),
|
||||
"},",
|
||||
".tileset = {",
|
||||
*start_size_value(gfx_path),
|
||||
"}",
|
||||
"},"
|
||||
]
|
||||
|
||||
def tilesets_header():
|
||||
yield "extern const tileset_t tilesets[];"
|
||||
|
||||
def tilesets():
|
||||
yield "const tileset_t tilesets[] = {"
|
||||
for tileset in sorted(parse.tileset_constants_list):
|
||||
yield from blockset_tileset(tileset)
|
||||
yield "};"
|
||||
|
||||
def map(map_header):
|
||||
block_path = parse.maps_blocks_list[map_header.blocks()]
|
||||
map_constant = parse.map_constants_list[map_header.name2]
|
||||
return [
|
||||
f"[map_t::{map_header.name2.lower()}] = {{",
|
||||
".blocks = {",
|
||||
*start_size_value(block_path),
|
||||
"},",
|
||||
f".tileset = tileset_t::{map_header.tileset.lower()},",
|
||||
f".width = {map_constant.width},",
|
||||
f".height = {map_constant.height},",
|
||||
"},",
|
||||
]
|
||||
|
||||
def maps_header():
|
||||
yield "extern const map_t maps[];"
|
||||
|
||||
def maps():
|
||||
yield "const map_t maps[] = {"
|
||||
for map_header in sorted_map_headers():
|
||||
yield from map(map_header)
|
||||
yield "};"
|
||||
|
||||
def generate_maps_header():
|
||||
render, out = renderer()
|
||||
render(includes())
|
||||
render(struct_start_size_t())
|
||||
render(struct_tileset_t())
|
||||
render(struct_map_t())
|
||||
render(tilesets_header());
|
||||
render(maps_header());
|
||||
return out
|
||||
|
||||
def include_maps_header():
|
||||
yield '#include "maps.hpp"'
|
||||
yield ""
|
||||
|
||||
def generate_maps_source():
|
||||
render, out = renderer()
|
||||
render(include_maps_header())
|
||||
render(tilesets())
|
||||
render(maps())
|
||||
return out
|
||||
|
||||
|
||||
"""
|
||||
map_headers[0].tileset == 'OVERWORLD'
|
||||
map_headers[0].name1 = 'PalletTown'
|
||||
map_headers[0].name2 = 'PALLET_TOWN'
|
||||
map_headers[0].blocks() == 'PalletTown_Blocks'
|
||||
map_constants_list['PALLET_TOWN'] == MapConstant(10, 19)
|
||||
maps_blocks_list['PalletTown_Blocks'] == 'maps/PalletTown.blk'
|
||||
tileset_constants_list['OVERWORLD'] == 0
|
||||
tileset_headers_list[0].name == 'Overworld'
|
||||
tileset_headers_list[0].blockset() == 'Overworld_Block'
|
||||
tileset_headers_list[0].gfx() == 'Overworld_GFX'
|
||||
gfx_tilesets_list['Overworld_Block'] == 'gfx/blocksets/overworld.bst'
|
||||
gfx_tilesets_list['Overworld_GFX'] == 'gfx/tilesets/overworld.2bpp'
|
||||
"""
|
@ -81,6 +81,4 @@ def parse(path):
|
||||
def parse_all(prefix):
|
||||
base_path = prefix / 'data/maps/headers'
|
||||
paths = [p for p in base_path.iterdir() if p.is_file()]
|
||||
from pprint import pprint
|
||||
pprint(paths)
|
||||
return [parse(path) for path in paths]
|
||||
|
Loading…
x
Reference in New Issue
Block a user