From f2b8bd646710fa57e1efafe15c2afabfe62e7a13 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 19 Sep 2026 13:42:14 -0400 Subject: [PATCH 1/5] this should just work:tm: --- fast64_internal/sm64/settings/properties.py | 6 ++++++ fast64_internal/sm64/sm64_level_writer.py | 10 +++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index 0d13cd291..b54a57ae8 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -114,6 +114,11 @@ class SM64_Properties(PropertyGroup): name="Designated Initialization for Animation Tables", description="Extremely recommended but must be off when compiling with IDO. Included in Repo Setting file", ) + camera_volume_path: StringProperty( + name="Camera Volume Export Path", + subtype="FILE_PATH", + default="src/game/camera.c", + ) @property def binary_export(self): @@ -232,6 +237,7 @@ def from_repo_settings(self, data: dict): set_prop_if_in_data(self, "write_all", data, "write_all") set_prop_if_in_data(self, "lighting_engine_presets", data, "lighting_engine_presets") set_prop_if_in_data(self, "designated_prop", data, "designated") + set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path") if "custom_cmds" in data: self.custom_cmds.clear() for preset_data in data.get("custom_cmds", []): diff --git a/fast64_internal/sm64/sm64_level_writer.py b/fast64_internal/sm64/sm64_level_writer.py index f38fbd5d9..16ba6ee55 100644 --- a/fast64_internal/sm64/sm64_level_writer.py +++ b/fast64_internal/sm64/sm64_level_writer.py @@ -885,6 +885,7 @@ def replace_compressed_segment_load(name: str, segment: int, add_compression_fmt def exportLevelC(obj, transformMatrix, level_name, exportDir, savePNG, customExport, levelCameraVolumeName, DLFormat): fileStatus = SM64OptionalFileStatus() + sm64_props: SM64_Properties = bpy.context.scene.fast64.sm64 if customExport: level_dir = os.path.join(exportDir, level_name) @@ -904,7 +905,7 @@ def exportLevelC(obj, transformMatrix, level_name, exportDir, savePNG, customExp fModel = SM64Model( level_name + "_dl", DLFormat, - bpy.context.scene.fast64.sm64.gfx_write_method, + sm64_props.gfx_write_method, ) childAreas = [child for child in obj.children if child.type == "EMPTY" and child.sm64_obj_type == "Area Root"] if len(childAreas) == 0: @@ -920,7 +921,7 @@ def exportLevelC(obj, transformMatrix, level_name, exportDir, savePNG, customExp prev_level_script.custom_cmds.append( custom_props.get_final_cmd( obj, - bpy.context.scene.fast64.sm64.blender_to_sm64_scale, + sm64_props.blender_to_sm64_scale, child.matrix_world @ yUpToZUp, child.matrix_local, name=obj.name, @@ -1067,8 +1068,11 @@ def write_include(path: Path, include: Path, before_endif=False): Path("levels", level_name, "material.inc.h"), ) + def resolveCameraPath(props: SM64_Properties, level_name: str): + return props.camera_volume_path.replace("{level}", level_name) + # Export camera triggers - cameraPath = os.path.join(exportDir, "src/game/camera.c") + cameraPath = os.path.join(exportDir, resolveCameraPath(sm64_props, level_name)) if os.path.exists(cameraPath): overwriteData( "struct\s*CameraTrigger\s*", From 7a9e9443fa77ec9d4752889485a22bf42e8fbc3e Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 19 Sep 2026 14:11:11 -0400 Subject: [PATCH 2/5] Plumb in zoomout masks too and test an export --- fast64_internal/sm64/settings/properties.py | 8 +++++++- fast64_internal/sm64/sm64_level_writer.py | 10 +++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index b54a57ae8..34369aea9 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -119,6 +119,11 @@ class SM64_Properties(PropertyGroup): subtype="FILE_PATH", default="src/game/camera.c", ) + zoom_out_mask_path: StringProperty( + name="Camera Zoom Out Mask Export Path", + subtype="FILE_PATH", + default="src/game/camera.c", + ) @property def binary_export(self): @@ -237,7 +242,8 @@ def from_repo_settings(self, data: dict): set_prop_if_in_data(self, "write_all", data, "write_all") set_prop_if_in_data(self, "lighting_engine_presets", data, "lighting_engine_presets") set_prop_if_in_data(self, "designated_prop", data, "designated") - set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path") + set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path")\ + set_prop_if_in_data(self, "zoom_out_mask_path", data, "zoom_out_mask_path") if "custom_cmds" in data: self.custom_cmds.clear() for preset_data in data.get("custom_cmds", []): diff --git a/fast64_internal/sm64/sm64_level_writer.py b/fast64_internal/sm64/sm64_level_writer.py index 16ba6ee55..764491f51 100644 --- a/fast64_internal/sm64/sm64_level_writer.py +++ b/fast64_internal/sm64/sm64_level_writer.py @@ -4,6 +4,7 @@ from typing import NamedTuple from dataclasses import dataclass, field from bpy.utils import register_class, unregister_class +from .settings.properties import SM64_Properties from ..panels import SM64_Panel from ..operators import ObjectDataExporter from .sm64_constants import cameraTriggerNames, levelIDNames, enumLevelNames @@ -1112,11 +1113,14 @@ def resolveCameraPath(props: SM64_Properties, level_name: str): courseMacro[1][1] = obj.starGetCutscenes.value() courseDefines.write(courseDefinesPath) - if os.path.exists(cameraPath): - zoomMasks = parseZoomMasks(cameraPath) + # Export Zoom Out masks + zoomOutMasksPath = os.path.join(exportDir, sm64_props.zoom_out_mask_path) + + if os.path.exists(zoomOutMasksPath): + zoomMasks = parseZoomMasks(zoomOutMasksPath) zoomMasks.updateMaskCount(len(levelDefines.defineMacros)) zoomMasks.setMask(levelIndex, zoomFlags) - zoomMasks.write(cameraPath) + zoomMasks.write(zoomOutMasksPath) if obj.actSelectorIgnore: add_act_selector_ignore(exportDir, levelEnum) From d92fdc347471a95567cea0f04d4812323769aa1d Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 19 Sep 2026 14:48:01 -0400 Subject: [PATCH 3/5] writeNew logic works --- fast64_internal/sm64/settings/properties.py | 6 +++++- fast64_internal/sm64/sm64_level_writer.py | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index 34369aea9..a5a4ef114 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -46,6 +46,8 @@ def decomp_path_update(self, context: Context): return directory_path_checks(self.abs_decomp_path) fast64_settings.repo_settings_path = as_posix(self.abs_repo_file_path) + # set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path") + # set_prop_if_in_data(self, "zoom_out_mask_path", data, "zoom_out_mask_path") class SM64_Properties(PropertyGroup): @@ -242,7 +244,7 @@ def from_repo_settings(self, data: dict): set_prop_if_in_data(self, "write_all", data, "write_all") set_prop_if_in_data(self, "lighting_engine_presets", data, "lighting_engine_presets") set_prop_if_in_data(self, "designated_prop", data, "designated") - set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path")\ + set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path") set_prop_if_in_data(self, "zoom_out_mask_path", data, "zoom_out_mask_path") if "custom_cmds" in data: self.custom_cmds.clear() @@ -279,6 +281,8 @@ def draw_repo_settings_props(self, layout: UILayout): if self.show_matstack_fix: warning.prop(self, "matstack_fix") warning.prop(self, "lighting_engine_presets") + warning.prop(self, "camera_volume_path") + warning.prop(self, "zoom_out_mask_path") col.separator() draw_custom_cmd_presets(self, col.box()) diff --git a/fast64_internal/sm64/sm64_level_writer.py b/fast64_internal/sm64/sm64_level_writer.py index 764491f51..6f3943efb 100644 --- a/fast64_internal/sm64/sm64_level_writer.py +++ b/fast64_internal/sm64/sm64_level_writer.py @@ -1070,7 +1070,10 @@ def write_include(path: Path, include: Path, before_endif=False): ) def resolveCameraPath(props: SM64_Properties, level_name: str): - return props.camera_volume_path.replace("{level}", level_name) + retPath: str = props.camera_volume_path + if "{level}" in retPath: + retPath = retPath.replace("{level}", level_name) + return retPath # Export camera triggers cameraPath = os.path.join(exportDir, resolveCameraPath(sm64_props, level_name)) @@ -1084,6 +1087,19 @@ def resolveCameraPath(props: SM64_Properties, level_name: str): False, ) fileStatus.cameraC = True + else: + if level_name in cameraPath: + with open(cameraPath, "a+") as f: + pass + overwriteData( + "struct\s*CameraTrigger\s*", + levelCameraVolumeName, + level_data.camera_data, + cameraPath, + None, + False, + ) + fileStatus.cameraC = True # Export puppycam triggers # If this isn't an ultrapuppycam repo, don't try and export ultrapuppycam triggers From baaff93514cae91ca346f87e93cb81f62da1b002 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 19 Sep 2026 18:46:42 -0400 Subject: [PATCH 4/5] i think the reset to default is enough here? --- fast64_internal/sm64/settings/properties.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index a5a4ef114..5181af01a 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -46,9 +46,6 @@ def decomp_path_update(self, context: Context): return directory_path_checks(self.abs_decomp_path) fast64_settings.repo_settings_path = as_posix(self.abs_repo_file_path) - # set_prop_if_in_data(self, "camera_volume_path", data, "camera_volume_path") - # set_prop_if_in_data(self, "zoom_out_mask_path", data, "zoom_out_mask_path") - class SM64_Properties(PropertyGroup): """Global SM64 Scene Properties found under scene.fast64.sm64""" From 3c5c1a81ea6cba47c5a62fbc4c8b784361d1e47b Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 19 Sep 2026 19:14:20 -0400 Subject: [PATCH 5/5] diff reduction --- fast64_internal/sm64/settings/properties.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index 5181af01a..6eddf7332 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -47,6 +47,7 @@ def decomp_path_update(self, context: Context): directory_path_checks(self.abs_decomp_path) fast64_settings.repo_settings_path = as_posix(self.abs_repo_file_path) + class SM64_Properties(PropertyGroup): """Global SM64 Scene Properties found under scene.fast64.sm64"""