From c845cc787e820a85e509eddb379fbf1730952c78 Mon Sep 17 00:00:00 2001 From: Lila <87947656+Lilaa3@users.noreply.github.com> Date: Thu, 25 Apr 2024 07:55:49 +0100 Subject: [PATCH] b --- fast64_internal/sm64/animation/classes.py | 2 +- fast64_internal/sm64/animation/operators.py | 28 ++--- fast64_internal/sm64/animation/panels.py | 8 +- fast64_internal/sm64/animation/properties.py | 110 +++++++++++++++---- fast64_internal/sm64/settings/properties.py | 1 + 5 files changed, 112 insertions(+), 37 deletions(-) diff --git a/fast64_internal/sm64/animation/classes.py b/fast64_internal/sm64/animation/classes.py index ddd0bb4ee..fea1fc309 100644 --- a/fast64_internal/sm64/animation/classes.py +++ b/fast64_internal/sm64/animation/classes.py @@ -50,7 +50,7 @@ def read_binary(self, indices_reader: RomReading, values_reader: RomReading): max_frame = indices_reader.read_value(2, signed=False) value_offset = indices_reader.read_value(2, signed=False) * 2 - values_reader = values_reader.branch(values_reader.address + value_offset) + values_reader = values_reader.branch(values_reader.start_address + value_offset) for _ in range(max_frame): value = values_reader.read_value(2, signed=True) self.values.append(value) diff --git a/fast64_internal/sm64/animation/operators.py b/fast64_internal/sm64/animation/operators.py index 3892063d0..d294b95c2 100644 --- a/fast64_internal/sm64/animation/operators.py +++ b/fast64_internal/sm64/animation/operators.py @@ -100,7 +100,7 @@ def execute_operator(self, context: Context): scene = context.scene scene_anim_props = scene.fast64.sm64.animation - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = context.object.fast64.sm64.animation else: animation_props: SM64_AnimProps = scene_anim_props @@ -154,7 +154,7 @@ class SM64_TableOperations(Operator): header_variant: IntProperty() def execute_operator(self, context: Context): - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = context.object.fast64.sm64.animation else: animation_props: SM64_AnimProps = context.scene.fast64.sm64.animation @@ -269,7 +269,7 @@ def execute_operator(self, context: Context): scene = context.scene sm64_props: SM64_Properties = scene.fast64.sm64 armature_obj: Object = context.selected_objects[0] - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = armature_obj.fast64.sm64.animation else: animation_props: SM64_AnimProps = sm64_props.animation @@ -384,7 +384,7 @@ def execute_operator(self, context: Context): sm64_props: SM64_Properties = scene.fast64.sm64 armature_obj: Object = context.selected_objects[0] - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = armature_obj.fast64.sm64.animation else: animation_props: SM64_AnimProps = sm64_props.animation @@ -488,7 +488,7 @@ def execute_operator(self, context): sm64_props: SM64_Properties = scene.fast64.sm64 armature_obj: Object = context.selected_objects[0] - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = armature_obj.fast64.sm64.animation else: animation_props: SM64_AnimProps = sm64_props.animation @@ -500,7 +500,9 @@ def execute_operator(self, context): mario_dma_table_address = 0x4EC000 if import_props.import_type == "Binary": - with open(bpy.path.abspath(sm64_props.import_rom), "rb") as rom: + rom_path = abspath(import_props.rom if import_props.rom else sm64_props.import_rom) + import_rom_checks(rom_path) + with open(rom_path, "rb") as rom: rom_data = rom.read() for entrie_str, name, _ in marioAnimationNames[1:]: entrie_num = int(entrie_str) @@ -550,7 +552,7 @@ def execute_operator(self, context): scene = context.scene sm64_props: SM64_Properties = scene.fast64.sm64 armature_obj: Object = context.selected_objects[0] - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": animation_props: SM64_AnimProps = armature_obj.fast64.sm64.animation else: animation_props: SM64_AnimProps = sm64_props.animation @@ -564,9 +566,9 @@ def execute_operator(self, context): if import_props.import_type == "Binary" or ( import_props.import_type == "Insertable Binary" and import_props.insertable_read_from_rom ): - import_rom_path = abspath(sm64_props.import_rom) - import_rom_checks(import_rom_path) - with open(import_rom_path, "rb") as rom_file: + rom_path = abspath(import_props.rom if import_props.rom else sm64_props.import_rom) + import_rom_checks(rom_path) + with open(rom_path, "rb") as rom_file: rom_data = rom_file.read() segment_data = parseLevelAtPointer(rom_file, level_pointers[import_props.level]).segmentData else: @@ -576,9 +578,7 @@ def execute_operator(self, context): assumed_bone_count = len(anim_bones) if import_props.assume_bone_count else None if import_props.import_type == "Binary": - address = eval_num_from_str( - import_props.dma_table_address if import_props.binary_import_type == "DMA" else import_props.address - ) + address = import_props.address if import_props.binary_import_type != "DMA" and import_props.is_segmented_address: address = decodeSegmentedAddr(address.to_bytes(4, "big"), segment_data) import_binary_animations( @@ -649,7 +649,7 @@ def execute(self, context): scene = context.scene sm64_props: SM64_Properties = scene.fast64.sm64 armature_obj: Object = context.selected_objects[0] - if context.space_data.context == "OBJECT": + if context.space_data.type != "VIEW_3D" and context.space_data.context == "OBJECT": import_props: SM64_AnimImportProps = armature_obj.fast64.sm64.animation.importing else: import_props: SM64_AnimImportProps = sm64_props.animation.anim_import.importing diff --git a/fast64_internal/sm64/animation/panels.py b/fast64_internal/sm64/animation/panels.py index 30a8491f4..281a0e415 100644 --- a/fast64_internal/sm64/animation/panels.py +++ b/fast64_internal/sm64/animation/panels.py @@ -43,7 +43,13 @@ def poll(cls, context): def draw(self, context: Context): box = self.layout.box().column() box.box().label(text=self.bl_label) - context.object.fast64.sm64.animation.draw_props(box, context.scene.fast64.sm64.export_type) + sm64_props: SM64_Properties = context.scene.fast64.sm64 + context.object.fast64.sm64.animation.draw_props( + self.layout.column(), + sm64_props.export_type, + sm64_props.show_importing_menus, + sm64_props.import_rom, + ) panels = ( diff --git a/fast64_internal/sm64/animation/properties.py b/fast64_internal/sm64/animation/properties.py index c63bcc97c..05ca64b94 100644 --- a/fast64_internal/sm64/animation/properties.py +++ b/fast64_internal/sm64/animation/properties.py @@ -3,7 +3,7 @@ from typing import Optional import bpy -from bpy.types import PropertyGroup, Action, UILayout, Object +from bpy.types import PropertyGroup, Action, UILayout, Object, Scene from bpy.utils import register_class, unregister_class from bpy.props import ( BoolProperty, @@ -56,7 +56,7 @@ marioAnimationNames, enumAnimExportTypes, ) -from .utility import get_anim_pose_bones +from .utility import get_anim_pose_bones, eval_num_from_str from .exporting import get_animation_pairs @@ -666,7 +666,7 @@ def draw_props( col = col.column() col.scale_y = header_scale_y - if specific_variant: + if specific_variant is not None: self.headers[specific_variant].draw_props( layout=col, action=action, @@ -1021,16 +1021,17 @@ class SM64_AnimImportProps(PropertyGroup): description="When enabled, the selected armature's bone count will be used instead of the header's, " "as old fast64 binary exports did no export this value", ) - address: StringProperty(name="Address", default="0600FC48") - is_segmented_address: BoolProperty(name="Is Segmented Address") - level: EnumProperty(items=level_enums, name="Level", default="IC") - read_entire_table: BoolProperty( name="Read All Animations", ) + + rom: StringProperty(name="Import ROM", subtype="FILE_PATH") table_index: IntProperty(name="Table Index", min=0) ignore_null: BoolProperty(name="Ignore NULL Delimiter") - + table_address: StringProperty(name="Address", default="0x0600FC48") # Toad animation table + animation_address: StringProperty(name="Address", default="0x0600B75C") # Toad animation 0 + is_segmented_address: BoolProperty(name="Is Segmented Address", default=True) + level: EnumProperty(items=level_enums, name="Level", default="IC") dma_table_address: StringProperty(name="DMA Table Address", default="0x4EC000") mario_animation: IntProperty(name="Selected Preset Mario Animation") @@ -1062,16 +1063,28 @@ def mario_or_table_index(self): else self.table_index ) + @property + def address(self): + return eval_num_from_str( + self.dma_table_address + if self.binary_import_type == "DMA" + else (self.table_address if self.binary_import_type == "Table" else self.animation_address) + ) + def draw_c(self, layout: UILayout): col = layout.column() col.prop(self, "remove_name_footer") col.prop(self, "use_custom_name") - def draw_binary(self, layout: UILayout, import_rom_path: str): + def draw_binary(self, layout: UILayout, import_rom: os.PathLike | None = None): col = layout.column() + + col.prop(self, "rom") + col.label(text="Uses scene import ROM by default", icon="INFO") try: - import_rom_checks(abspath(import_rom_path)) + if self.rom or import_rom is None: + import_rom_checks(abspath(self.rom)) except Exception as exc: multilineLabel(col.box(), str(exc), "ERROR") col = col.column() @@ -1091,17 +1104,18 @@ def draw_binary(self, layout: UILayout, import_rom_path: str): col.box().label(text=f"{marioAnimationNames[self.mario_animation + 1][1]}") else: prop_split(col, self, "level", "Level") - col.prop(self, "is_segmented_address") - prop_split(col, self, "address", "Address") if self.binary_import_type == "Table": + prop_split(col, self, "table_address", "Address") col.prop(self, "read_entire_table") if not self.read_entire_table: prop_split(col, self, "table_index", "List Index") col.prop(self, "ignore_null") + elif self.binary_import_type == "Animation": + prop_split(col, self, "animation_address", "Address") - def draw_insertable_binary(self, layout: UILayout, import_rom_path: str): + def draw_insertable_binary(self, layout: UILayout, import_rom: os.PathLike | None = None): col = layout.column() col.label(text="Type will be read from the data type of the files") @@ -1110,12 +1124,15 @@ def draw_insertable_binary(self, layout: UILayout, import_rom_path: str): from_rom_box = col.box().column() from_rom_box.prop(self, "insertable_read_from_rom") if self.insertable_read_from_rom: + col.label(text="Uses scene import ROM by default", icon="INFO") try: - import_rom_checks(abspath(import_rom_path)) + if self.rom or import_rom is None: + import_rom_checks(abspath(self.rom)) except Exception as exc: multilineLabel(from_rom_box.box(), str(exc), "ERROR") from_rom_box = from_rom_box.column() from_rom_box.enabled = False + prop_split(from_rom_box, self, "level", "Level") from_rom_box.prop(self, "is_segmented_address") prop_split(from_rom_box, self, "address", "Address") @@ -1127,7 +1144,7 @@ def draw_insertable_binary(self, layout: UILayout, import_rom_path: str): prop_split(table_box, self, "table_index", "List Index") table_box.prop(self, "ignore_null") - def draw_props(self, layout: UILayout, import_rom_path: str): + def draw_props(self, layout: UILayout, import_rom: os.PathLike | None = None): col = layout.column() prop_split(col, self, "import_type", "Type") @@ -1141,9 +1158,9 @@ def draw_props(self, layout: UILayout, import_rom_path: str): if self.import_type == "C": self.draw_c(col) elif self.import_type == "Binary": - self.draw_binary(col, import_rom_path) + self.draw_binary(col, import_rom) elif self.import_type == "Insertable Binary": - self.draw_insertable_binary(col, import_rom_path) + self.draw_insertable_binary(col, import_rom) col.separator() col.operator(SM64_ImportAnim.bl_idname, icon="IMPORT") @@ -1190,6 +1207,57 @@ class SM64_AnimProps(PropertyGroup): name="Quick Data Read", default=True, description="Read fcurves directly, should work with the majority of rigs" ) + def update_version_0(self, scene: Scene): + importing: SM64_AnimImportProps = self.importing + importing.address = importing.get("levelAnimImport", importing.address) + # del bpy.types.Scene.levelAnimImport + # del bpy.types.Scene.animStartImport + # del bpy.types.Scene.animListIndexImport + if importing.get("isDMAImport", False): + importing.binary_import_type = "DMA" + elif importing.get("animIsAnimList", True): + importing.binary_import_type = "Table" + # del bpy.types.Scene.animExportStart + # del bpy.types.Scene.animExportEnd + # del bpy.types.Scene.levelAnimExport + self.is_binary_dma = importing.get("isDMAExport", self.is_binary_dma) + # del bpy.types.Scene.DMAStartAddress + # del bpy.types.Scene.DMAEntryAddress + loop_animation = scene.get("loopAnimation", True) + if not loop_animation: + for action in bpy.data.actions: + action.fast64.sm64.header.no_loop = True + # del bpy.types.Scene.setAnimListIndex + # del bpy.types.Scene.overwrite_0x28 + # del bpy.types.Scene.addr_0x27 + # del bpy.types.Scene.addr_0x28 + # del bpy.types.Scene.animExportPath + # del bpy.types.Scene.animOverwriteDMAEntry + # del bpy.types.Scene.animInsertableBinaryPath + # del bpy.types.Scene.animIsSegPtr + # del bpy.types.Scene.animIsAnimList + # del bpy.types.Scene.animListIndexExport + self.actor_name = scene.get("animName", self.name) + self.group_name = scene.get("animGroupName", self.group_name) + header_type = scene.get("animExportHeaderType", None) + if header_type: + self.header_type = enumAnimExportTypes[header_type][0] + level_option = scene.get("animLevelOption", None) + if level_option: + self.level_option = enumLevelNames[level_option][0] + custom_export = self.get("animCustomExport", False) + if custom_export: + self.header_type = "Custom" + print(f"Upgraded global SM64 settings to version 1") + + @staticmethod + def upgrade_changed_props(): + for scene in bpy.data.scenes: + sm64_props: SM64_AnimProps = scene.fast64.sm64 + if sm64_props.version == 0: + sm64_props.update_version_0(scene) + sm64_props.version = SM64_AnimProps.cur_version + @property def actor_name(self): return self.actor_name_prop if self.header_type != "DMA" else None @@ -1276,11 +1344,11 @@ def draw_table_properties(self, layout: UILayout, is_dma: bool, export_type: str self.actor_name, ) - def draw_importing_properties(self, layout: UILayout, import_rom_path: str | None = None): + def draw_importing_properties(self, layout: UILayout, import_rom: os.PathLike | None = None): col = layout.column() col.prop(self, "importing_tab", icon="TRIA_DOWN" if self.importing_tab else "TRIA_RIGHT") if self.importing_tab: - self.importing.draw_props(col, import_rom_path) + self.importing.draw_props(col, import_rom) def draw_binary_settings(self, layout: UILayout, export_type: str): col = layout.column() @@ -1342,7 +1410,7 @@ def draw_props( layout: UILayout, export_type: str = "C", show_importing: bool = True, - import_rom_path: str = "", + import_rom: os.PathLike | None = None, ): col = layout.column() @@ -1358,7 +1426,7 @@ def draw_props( self.draw_action_properties(col.box(), is_dma, export_type) self.draw_table_properties(col.box(), is_dma, export_type) if show_importing: - self.draw_importing_properties(col.box(), import_rom_path) + self.draw_importing_properties(col.box(), import_rom) properties = ( diff --git a/fast64_internal/sm64/settings/properties.py b/fast64_internal/sm64/settings/properties.py index 8c6c0f696..d524a3b93 100644 --- a/fast64_internal/sm64/settings/properties.py +++ b/fast64_internal/sm64/settings/properties.py @@ -121,6 +121,7 @@ def upgrade_changed_props(): if sm64_props.version == 1: sm64_props.upgrade_version_1(scene) print("Upgraded global SM64 settings to version 2") + SM64_AnimProps.upgrade_changed_props() def draw_props(self, layout: UILayout, show_repo_settings: bool = True): col = layout.column()