#!/usr/bin/python3 import os import sys import re from disassemble import get_z_name script_dir = os.path.dirname(os.path.realpath(__file__)) root_dir = script_dir + "/../" data_dir = root_dir + "data/overlays/actors" asm_dir = root_dir + "asm/non_matchings/overlays/actors" src_dir = root_dir + "src/overlays/actors" include_dir = root_dir + "include" indent = " " to_rename = [] with open(os.path.join(include_dir, "z64actor.h")) as f: z64actor_text = f.read() with open(os.path.join(include_dir, "z64object.h")) as f: z64object_text = f.read() def get_actor_id_name(actor_id): matches = re.findall(actor_id + " .*\n", z64actor_text) if len(matches) == 0: return "0x" + actor_id match = matches[-1] match = match.replace(",", "").strip().split(" ")[-1] return match def get_actor_type_name(actor_type): matches = re.findall(actor_type + " .*\n", z64actor_text) for m in matches: if "ACTORCAT" in m: match = m.replace(",", "").strip().split(" ")[-1] return match return "0x" + actor_type def get_object_id_name(object_id): matches = re.findall(object_id + " .*\n", z64object_text) if len(matches) == 0: return "0x" + object_id match = matches[-1] match = match.replace(",", "").strip().split(" ")[-1] return match def create_struct(name, size): ret = "typedef struct\n{\n" + indent + "/* 0x0000 */ Actor actor;\n" leftover = int(size, 16) - int("0x14C", 16) if leftover > 0: ret += indent + "/* 0x014C */ char unk_14C[0x" + hex(leftover).upper()[2:] + "];\n" ret += "} " + name + "; // size = 0x" + size + "\n" return ret 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 bootstrap(ovl_path, ovl_text): path_split = ovl_path.split(os.path.sep) z_name = path_split[-1][:-2] ovl_name = path_split[-2] init_vars_name = ovl_name[4:] + "_InitVars" with open(os.path.join(data_dir, z_name + ".data.s")) as f: data_text = f.read() pattern = re.compile("glabel D_........\n .word 0x........, 0x........, 0x........, 0x........\n(\.word func_........\n|\.word 0x00000000\n|\.word Actor_Noop\n){4}") 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") init_var_label = lines[0][7:] init_func = lines[2][6:] destroy_func = lines[3][6:] update_func = lines[4][6:] draw_func = lines[5][6:] ovl_shortened = ovl_name.replace("ovl", "").replace("_", "") init_func_name = ovl_shortened + "_Init" destroy_func_name = ovl_shortened + "_Destroy" update_func_name = ovl_shortened + "_Update" draw_func_name = ovl_shortened + "_Draw" to_rename.append((init_var_label, init_vars_name)) if init_func != "0x00000000" and init_func != "Actor_Noop": to_rename.append((init_func, init_func_name)) if destroy_func != "0x00000000" and destroy_func != "Actor_Noop": to_rename.append((destroy_func, destroy_func_name)) if update_func != "0x00000000" and update_func != "Actor_Noop": to_rename.append((update_func, update_func_name)) if draw_func != "0x00000000" and draw_func != "Actor_Noop": to_rename.append((draw_func, draw_func_name)) init_var_data = lines[1] init_data = init_var_data[7:53].replace("0x", "").split(", ") actor_id = init_data[0][0:4] actor_type = init_data[0][4:6] room = init_data[0][6:8] flags = init_data[1] object_id = init_data[2][0:4] struct_size = init_data[3][4:8] actor_id_name = get_actor_id_name(actor_id) actor_type_name = get_actor_type_name(actor_type) object_id_name = get_object_id_name(object_id) struct_name = ovl_shortened struct_text = create_struct(struct_name, struct_size) defines = "#define ROOM 0x" + room + "\n#define FLAGS 0x" + flags + "\n" decs = "" if init_func != "0x00000000" and init_func != "Actor_Noop": decs += "void " + init_func_name + "(" + struct_name + "* this, GlobalContext* globalCtx);\n" if destroy_func != "0x00000000" and destroy_func != "Actor_Noop": decs += "void " + destroy_func_name + "(" + struct_name + "* this, GlobalContext* globalCtx);\n" if update_func != "0x00000000" and update_func != "Actor_Noop": decs += "void " + update_func_name + "(" + struct_name + "* this, GlobalContext* globalCtx);\n" if draw_func != "0x00000000" and draw_func != "Actor_Noop": decs += "void " + draw_func_name + "(" + struct_name + "* this, GlobalContext* globalCtx);\n" init_vars = "const ActorInit " + init_vars_name + " =\n{\n" init_vars += indent + actor_id_name + ",\n" init_vars += indent + actor_type_name + ",\n" init_vars += indent + "ROOM,\n" + indent + "FLAGS,\n" init_vars += indent + object_id_name + ",\n" init_vars += indent + "sizeof(" + struct_name + "),\n" if init_func == "0x00000000": init_vars += indent + "NULL,\n" elif init_func == "Actor_Noop": init_vars += indent + "(ActorFunc)Actor_Noop,\n" else: init_vars += indent + "(ActorFunc)" + init_func_name + ",\n" if destroy_func == "0x00000000": init_vars += indent + "NULL,\n" elif destroy_func == "Actor_Noop": init_vars += indent + "(ActorFunc)Actor_Noop,\n" else: init_vars += indent + "(ActorFunc)" + destroy_func_name + ",\n" if update_func == "0x00000000": init_vars += indent + "NULL,\n" elif update_func == "Actor_Noop": init_vars += indent + "(ActorFunc)Actor_Noop,\n" else: init_vars += indent + "(ActorFunc)" + update_func_name + ",\n" if draw_func == "0x00000000": init_vars += indent + "NULL,\n" elif draw_func == "Actor_Noop": init_vars += indent + "(ActorFunc)Actor_Noop,\n" else: init_vars += indent + "(ActorFunc)" + draw_func_name + ",\n" init_vars += "};\n" return struct_text + "\n" + defines + "\n" + decs + "\n/*\n" + init_vars + "*/" 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: bootstrap_text = bootstrap(file_path, file_text) if bootstrap_text != "": newline_spot = file_text.find("\n\n") + 1 newfile_text = file_text[:newline_spot] + "\n" + bootstrap_text + file_text[newline_spot:] newfile_text = newfile_text.replace("\n\n\n\n\n", "\n") with open(file_path, "w", newline="\n") as f: f.write(newfile_text) else: dog = 5 rename() main()