From a3fffc032d1170fbbb32524c97eb7c51bb959c73 Mon Sep 17 00:00:00 2001 From: Anoliah <173389381+Anoliah@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:46:54 -0800 Subject: [PATCH] change act selector skip to export to bottom of function --- fast64_internal/sm64/sm64_level_writer.py | 75 +++++++++++++---------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/fast64_internal/sm64/sm64_level_writer.py b/fast64_internal/sm64/sm64_level_writer.py index 6df955257..0f4c57a24 100644 --- a/fast64_internal/sm64/sm64_level_writer.py +++ b/fast64_internal/sm64/sm64_level_writer.py @@ -539,49 +539,56 @@ def setStartLevel(basePath, levelEnum): saveDataToFile(filepath, newData) -def addActSelectorIgnore(basePath, levelEnum): - filepath = os.path.join(basePath, "src/game/level_update.c") - data = getDataFromFile(filepath) +def add_act_selector_ignore(base_path, level_enum): + file_path = os.path.join(base_path, "src/game/level_update.c") + data = getDataFromFile(file_path) - checkResult = re.search("if\s*\(gCurrLevelNum\s*==\s*" + levelEnum + "\)\s*return\s*0;", data, re.DOTALL) - if checkResult is not None: - return + function_start = re.search("s32\s*lvl\_set\_current\_level\s*\((((?!\)).)*)\)\s*\{", data, re.DOTALL) - # This won't actually match whole function, but only up to first closing bracket. - # This should be okay though... ? - matchResultFunction = re.search( - "s32\s*lvl\_set\_current\_level\s*\((((?!\)).)*)\)\s*\{" + "(((?!\}).)*)\}", data, re.DOTALL - ) + if function_start is None: + raise PluginError('Could not find lvl_set_current_level in "' + file_path + '".') - if matchResultFunction is None: - raise PluginError('Could not find lvl_set_current_level in "' + filepath + '".') + function_end = re.search("\s*return\s*\!gDebugLevelSelect;\s*", data, re.DOTALL) + if function_end is None: + raise PluginError('Could not find return in lvl_set_current_level in "' + file_path + '".') - functionContents = matchResultFunction.group(3) + function_contents = data[function_start.end() : function_end.start()] - matchResult = re.search("gCurrCourseNum\s*\=\s*gLevelToCourseNumTable(((?!\;).)*)\;", functionContents, re.DOTALL) - if matchResult is None: - raise PluginError('Could not find gCurrCourseNum setting in lvl_set_current_level in "' + filepath + '".') - - functionContents = ( - functionContents[: matchResult.end(0)] - + "\n\tif (gCurrLevelNum == " - + levelEnum - + ") return 0;" - + functionContents[matchResult.end(0) :] + check_result = re.search( + "if\s*\(gCurrLevelNum\s*==\s*" + level_enum + "\)\s*return\s*0;", function_contents, re.DOTALL ) + if check_result is not None: + return - newData = data[: matchResultFunction.start(3)] + functionContents + data[matchResultFunction.end(3) :] + function_contents += "\n\tif (gCurrLevelNum == " + level_enum + ") return 0;" - saveDataToFile(filepath, newData) + new_data = data[: function_start.end()] + function_contents + data[function_end.start() :] + saveDataToFile(file_path, new_data) -def removeActSelectorIgnore(basePath, levelEnum): - filepath = os.path.join(basePath, "src/game/level_update.c") - data = getDataFromFile(filepath) - newData = re.sub("if\s*\(gCurrLevelNum\s*\=\=\s*" + levelEnum + "\)\s*return\s*0\;\n", "", data, re.DOTALL) - if data != newData: - saveDataToFile(filepath, newData) +def remove_act_selector_ignore(base_path, level_enum): + file_path = os.path.join(base_path, "src/game/level_update.c") + data = getDataFromFile(file_path) + + function_start = re.search("s32\s*lvl\_set\_current\_level\s*\((((?!\)).)*)\)\s*\{", data, re.DOTALL) + + if function_start is None: + raise PluginError('Could not find lvl_set_current_level in "' + file_path + '".') + + function_end = re.search("\s*return\s*\!gDebugLevelSelect;\s*", data, re.DOTALL) + if function_end is None: + raise PluginError('Could not find return in lvl_set_current_level in "' + file_path + '".') + + function_contents = data[function_start.end() : function_end.start()] + + new_function_contents = re.sub( + "\s*?if\s*\(gCurrLevelNum\s*==\s*" + level_enum + "\)\s*return\s*0;", "", function_contents, re.DOTALL + ) + + if function_contents != new_function_contents: + new_data = data[: function_start.end()] + new_function_contents + data[function_end.start() :] + saveDataToFile(file_path, new_data) areaNumReg = re.compile(r".*AREA\(([0-9]+),.+\),") @@ -1102,9 +1109,9 @@ def write_include(path: Path, include: Path, before_endif=False): zoomMasks.write(cameraPath) if obj.actSelectorIgnore: - addActSelectorIgnore(exportDir, levelEnum) + add_act_selector_ignore(exportDir, levelEnum) else: - removeActSelectorIgnore(exportDir, levelEnum) + remove_act_selector_ignore(exportDir, levelEnum) if obj.setAsStartLevel: setStartLevel(exportDir, levelEnum)