diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index 0d13cd291..6eddf7332 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -114,6 +114,16 @@ 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", + ) + 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): @@ -232,6 +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, "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", []): @@ -267,6 +279,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 f38fbd5d9..6f3943efb 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 @@ -885,6 +886,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 +906,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 +922,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 +1069,14 @@ 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): + 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, "src/game/camera.c") + cameraPath = os.path.join(exportDir, resolveCameraPath(sm64_props, level_name)) if os.path.exists(cameraPath): overwriteData( "struct\s*CameraTrigger\s*", @@ -1079,6 +1087,19 @@ def write_include(path: Path, include: Path, before_endif=False): 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 @@ -1108,11 +1129,14 @@ def write_include(path: Path, include: Path, before_endif=False): 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)