""" REL Sieve finds RELs that are good candidates for matching. RELs have a bunch of dependencies on the main DOL, not all of which are decomped or have correct headers set up yet, so we can't start matching every REL right now. The REL sieve finds rels where dependencies *are* set up already and suggests good candidates for matching. The approach is that we start with the assumption that every REL *can* be matched right now, and then when you look at a REL you may find dependencies that block this REL (usually in terms of a function call). You then add this function label to the list in this file and re-run the script, at which point this REL and any others that call this function will be filtered out. You then repeat the process until you find a REL you can somewhat easily match. When a system in the DOL becomes available (via headers or a full-on decomp) you can remove the corresponding function label here and more RELs may become available. Of course, some of these RELs may have other dependencies, which you can then add etc. The hope is that this helps us keep an overview over which RELs can be matched and which DOL systems are good candidates for decomping. """ import glob import json import os import pathlib BLOCKING_SYMBOLS = [ ['fn_800C3EC0', 'ActorEventFlowManagerRelated::checkEventFinished'], ['fn_800275C0', 'EffectsStruct::ctor'], ['fn_80027610', 'EffectsStruct::ctor'], ['fn_80016C10', 'AnimModelWrapper::ctor'], ['fn_802E32B0', 'm2d::FrameCtrl_c::setFrame'], ['fn_802F04A0', 'mFader_c::draw'], ['fn_801695F0', 'LytCommonTitle::ctor'], ['fn_80067020', 'matrixCreateFromPosRotYScale'], ['fn_800C43D0', 'ActorEventFlowManagerRelated *FUN_800c43d0'], ['fn_8037DCC0', 'EnemySoundMgr'], ['fn_800A6690', 'ActorOnRail::ctor'], ['fn_800975D0', 'initializeDowsingTarget'], ['fn_800A0680', 'getCurrentEventActor'], ['fn_80390FE0', 'something harp sound'], ['fn_801BB6F0', 'getCamera'], ['fn_800225F0', 'something light'], ['fn_80179250', 'shutter fence list'], ['fn_383_D10', 'getAcOStageSink_ptr'], ] def main(): matched_names = set() with open('./objdiff.json') as f: objdiff = json.load(f) for unit in objdiff["units"]: if unit.get("metadata", {}).get("complete", False): matched_names.add(unit["name"].split('/')[-1]) data = {} for folder in os.listdir('./build/SOUE01'): if folder.startswith('d_') and not folder[:-2] in matched_names: data[folder] = [] s_files = glob.glob(f'./build/SOUE01/{folder}/asm/REL/d/**/*.s', recursive=True) for f in s_files: text = pathlib.Path(f).read_text() for [sym, comment] in BLOCKING_SYMBOLS: if sym in text: data[folder].append(comment) output = sorted([ [rel, deps] for rel, deps in data.items() ], key=lambda x: -len(x[1])) for [rel, deps] in output: print(rel + ':', ", ".join(deps) if len(deps) else "No identified blockers! Go decomp this REL, or add a blocker to this script") if __name__ == "__main__": main()