#!/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()