117 lines
3.2 KiB
Python
Executable File
117 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import urllib.request
|
|
import re
|
|
|
|
COLLISION_URL = "https://raw.githubusercontent.com/n64decomp/sm64/06ec56df7f951f88da05f468cdcacecba496145a/levels/bob/areas/1/collision.inc.c"
|
|
SCRIPT_URL = "https://raw.githubusercontent.com/n64decomp/sm64/06ec56df7f951f88da05f468cdcacecba496145a/levels/bob/script.c"
|
|
|
|
|
|
LEVEL_H = """#pragma once
|
|
|
|
#include "../src/libsm64.h"
|
|
|
|
extern const struct SM64Surface surfaces[];
|
|
extern const size_t surfaces_count;
|
|
"""
|
|
|
|
|
|
def extract_surface(token):
|
|
token = token.strip()
|
|
if "SURFACE_" in token:
|
|
token = token[token.find("SURFACE_"):]
|
|
if "," in token:
|
|
token = token.split(",")[0].strip()
|
|
return token
|
|
|
|
|
|
def parse_collision(raw):
|
|
verts = []
|
|
tris = []
|
|
current_surface = "SURFACE_DEFAULT"
|
|
|
|
for line in raw:
|
|
line = line.strip()
|
|
|
|
if "COL_VERTEX(" in line:
|
|
inside = line[line.find("(") + 1:line.rfind(")")]
|
|
t = [x.strip() for x in inside.split(",")]
|
|
verts.append((int(t[0]), int(t[1]), int(t[2])))
|
|
|
|
elif "COL_TRI_INIT(" in line:
|
|
inside = line[line.find("(") + 1:line.rfind(")")]
|
|
t = [x.strip() for x in inside.split(",")]
|
|
current_surface = extract_surface(t[0])
|
|
|
|
elif "COL_TRI(" in line:
|
|
inside = line[line.find("(") + 1:line.rfind(")")]
|
|
t = [x.strip() for x in inside.split(",")]
|
|
tris.append((int(t[0]), int(t[1]), int(t[2]), current_surface))
|
|
|
|
return verts, tris
|
|
|
|
|
|
def parse_script(raw):
|
|
current_area = None
|
|
area_terrain = {}
|
|
|
|
for line in raw:
|
|
line = line.strip()
|
|
|
|
m_area = re.search(r"AREA\s*\(\s*(\d+)", line)
|
|
if m_area:
|
|
current_area = int(m_area.group(1))
|
|
|
|
m_terrain = re.search(r"TERRAIN_TYPE\s*\(\s*([A-Z_0-9]+)\s*\)", line)
|
|
if m_terrain and current_area is not None:
|
|
area_terrain[current_area] = m_terrain.group(1)
|
|
|
|
return area_terrain
|
|
|
|
|
|
def main():
|
|
print("Downloading collision...")
|
|
collision_raw = urllib.request.urlopen(COLLISION_URL).read().decode("utf8").splitlines()
|
|
|
|
print("Downloading script...")
|
|
script_raw = urllib.request.urlopen(SCRIPT_URL).read().decode("utf8").splitlines()
|
|
|
|
verts, tris = parse_collision(collision_raw)
|
|
area_terrain = parse_script(script_raw)
|
|
|
|
current_terrain = area_terrain.get(1, "TERRAIN_GRASS")
|
|
|
|
out_lines = []
|
|
|
|
for tri in tris:
|
|
v1 = verts[tri[0]]
|
|
v2 = verts[tri[1]]
|
|
v3 = verts[tri[2]]
|
|
surf = tri[3]
|
|
|
|
out_lines.append(
|
|
"{%s,0,%s,0,{{%d,%d,%d},{%d,%d,%d},{%d,%d,%d}}}" % (
|
|
surf,
|
|
current_terrain,
|
|
v1[0], v1[1], v1[2],
|
|
v2[0], v2[1], v2[2],
|
|
v3[0], v3[1], v3[2],
|
|
)
|
|
)
|
|
|
|
out_str = ",\n".join(out_lines)
|
|
|
|
out_str = "const struct SM64Surface surfaces[] = {\n" + out_str + "\n};\n\n"
|
|
out_str += "const size_t surfaces_count = sizeof(surfaces) / sizeof(surfaces[0]);\n"
|
|
out_str = '#include "../src/decomp/include/surface_terrains.h"\n' + out_str
|
|
out_str = '#include "level.h"\n' + out_str
|
|
|
|
with open("test/level.c", "w") as f:
|
|
f.write(out_str)
|
|
|
|
with open("test/level.h", "w") as f:
|
|
f.write(LEVEL_H)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|