1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-24 21:56:03 +00:00
oot/tools/bootstrap_fx.py
Ethan Roseman e672778b0e
Fx bootstrap (#278)
* script

* update

* dun?
2020-07-19 19:42:59 -04:00

196 lines
6.8 KiB
Python
Executable file

#!/usr/bin/python3
import os
import sys
import re
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = script_dir + "/../"
data_dir = root_dir + "data/overlays/effects"
asm_dir = root_dir + "asm/non_matchings/overlays/effects"
src_dir = root_dir + "src/overlays/effects"
include_dir = root_dir + "include"
indent = " "
effect_enum = [
"EFFECT_SS_DUST",
"EFFECT_SS_KIRAKIRA",
"EFFECT_SS_BOMB",
"EFFECT_SS_BOMB2",
"EFFECT_SS_BLAST",
"EFFECT_SS_G_SPK",
"EFFECT_SS_D_FIRE",
"EFFECT_SS_BUBBLE",
"EFFECT_SS_UNSET",
"EFFECT_SS_G_RIPPLE",
"EFFECT_SS_G_SPLASH",
"EFFECT_SS_G_MAGMA",
"EFFECT_SS_G_FIRE",
"EFFECT_SS_LIGHTNING",
"EFFECT_SS_DT_BUBBLE",
"EFFECT_SS_HAHEN",
"EFFECT_SS_STICK",
"EFFECT_SS_SIBUKI",
"EFFECT_SS_SIBUKI2",
"EFFECT_SS_G_MAGMA2",
"EFFECT_SS_STONE1",
"EFFECT_SS_HITMARK",
"EFFECT_SS_FHG_FLASH",
"EFFECT_SS_K_FIRE",
"EFFECT_SS_SOLDER_SRCH_BALL",
"EFFECT_SS_KAKERA",
"EFFECT_SS_ICE_PIECE",
"EFFECT_SS_EN_ICE",
"EFFECT_SS_FIRE_TAIL",
"EFFECT_SS_EN_FIRE",
"EFFECT_SS_EXTRA",
"EFFECT_SS_FCIRCLE",
"EFFECT_SS_DEAD_DB",
"EFFECT_SS_DEAD_DD",
"EFFECT_SS_DEAD_DS",
"EFFECT_SS_DEAD_SOUND",
"EFFECT_SS_ICE_SMOKE",
]
to_rename = []
def get_regs_enum(short_name):
upper_name = short_name.upper()
return \
"typedef enum {\n" + \
indent + "/* 0x00 */ SS_" + upper_name + "_0,\n" + \
indent + "/* 0x01 */ SS_" + upper_name + "_1,\n" + \
indent + "/* 0x02 */ SS_" + upper_name + "_2,\n" + \
indent + "/* 0x03 */ SS_" + upper_name + "_3,\n" + \
indent + "/* 0x04 */ SS_" + upper_name + "_4,\n" + \
indent + "/* 0x05 */ SS_" + upper_name + "_5,\n" + \
indent + "/* 0x06 */ SS_" + upper_name + "_6,\n" + \
indent + "/* 0x07 */ SS_" + upper_name + "_7,\n" + \
indent + "/* 0x08 */ SS_" + upper_name + "_8,\n" + \
indent + "/* 0x09 */ SS_" + upper_name + "_9,\n" + \
indent + "/* 0x0A */ SS_" + upper_name + "_A,\n" + \
indent + "/* 0x0B */ SS_" + upper_name + "_B,\n" + \
indent + "/* 0x0C */ SS_" + upper_name + "_C,\n" + \
"} " + "EffectSs" + short_name + "Regs;\n"
def bootstrap(ovl_path, ovl_text):
path_split = ovl_path.split(os.path.sep)
z_name = path_split[-1][:-2]
ovl_name = path_split[-2]
short_name = ovl_name[14:]
init_vars_name = ovl_name[4:] + "_InitVars"
top_comment = "/*\n * File: " + z_name + ".c" \
"\n * Overlay: " + ovl_name + "\n * Description:\n */\n"
header_include = "#include \"" + z_name + ".h\"\n"
regs_enum = get_regs_enum(short_name)
with open(os.path.join(data_dir, z_name + ".data.s")) as f:
data_text = f.read()
pattern = re.compile("glabel " + init_vars_name +
"\n.word 0x........\n\.word func_........\n")
init_data = pattern.search(data_text)
if init_data is None or len(init_data.regs) == 0:
return ""
init_data = data_text[init_data.regs[0][0]:init_data.regs[0][1]]
lines = init_data.split("\n")
effect_id = int(lines[1][6:], 16)
init_func = lines[2][6:]
ovl_shortened = ovl_name.replace("ovl", "").replace("_", "")
init_func_name = ovl_shortened + "_Init"
ovl_text = ovl_text.replace(init_func, init_func_name)
to_rename.append((init_func, init_func_name))
effect_id_name = effect_enum[effect_id]
struct_text = "/*\nEffectSsInit " + init_vars_name + \
" = {\n" + indent + effect_id_name + \
",\n" + indent + init_func_name + ",\n};\n*/"
decs = "u32 " + init_func_name + \
"(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx);\n"
decs += "void " + \
init_func_name[:-4] + \
"Draw(GlobalContext* globalCtx, u32 index, EffectSs* this);\n"
decs += "void " + \
init_func_name[:-4] + \
"Update(GlobalContext* globalCtx, u32 index, EffectSs* this);\n"
insert_pos = ovl_text.find("global.h>\n")
return top_comment + "\n" + header_include + "\n" + regs_enum + "\n" + decs + "\n" + struct_text + "\n" + ovl_text[insert_pos + 10:]
def get_header(header_path):
path_split = header_path.split(os.path.sep)
ovl_name = path_split[-2]
short_name = ovl_name[14:]
init_vars_name = "".join(ovl_name[4:].split("_")) + "InitParams"
ifndef = "#ifndef _Z_EFF_SS_" + short_name.upper() + "_H_\n" + \
"#define _Z_EFF_SS_" + short_name.upper() + "_H_\n\n"
includes = "#include <ultra64.h>\n#include <global.h>\n\n"
struct = "typedef struct {\n" + \
indent + "/* 0x00 */ Vec3f pos;\n" + \
indent + "/* 0x0C */ Vec3f velocity;\n" + \
indent + "/* 0x18 */ Vec3f accel;\n" + \
"} " + init_vars_name + "; // size = 0x\n\n#endif\n"
return ifndef + includes + struct
def rename():
# Filenames first
for root, dirs, files in os.walk(root_dir):
for file in files:
for elem in to_rename:
if elem[0] in file:
new_file = file.replace(elem[0], elem[1])
file_path = os.path.join(root, file)
new_file_path = os.path.join(root, new_file)
os.rename(file_path, new_file_path)
# File contents
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith(".c") or file.endswith(".s"):
file_path = os.path.join(root, file)
with open(file_path) as f:
file_text = f.read()
new_file_text = file_text
for elem in to_rename:
# if "func_" in elem[0]:
# new_file_text = new_file_text.replace("glabel " + elem[0], elem[1] + ":")
new_file_text = new_file_text.replace(elem[0], elem[1])
if new_file_text != file_text:
with open(file_path, "w", newline="\n") as f:
f.write(new_file_text)
def main():
for root, dirs, files in os.walk(src_dir):
for file in files:
if file.endswith(".c"):
file_path = os.path.join(root, file)
with open(file_path) as f:
file_text = f.read()
brace_count = file_text.count("{")
if brace_count == 0:
if "dead" in file_path:
dog = 5
header_path = file_path[:-1] + "h"
c_text = bootstrap(file_path, file_text)
header_text = get_header(header_path)
with open(file_path, "w", newline="\n") as f:
f.write(c_text)
with open(header_path, "w", newline="\n") as f:
f.write(header_text)
rename()
main()