Skip to content

Commit

Permalink
assumed bone count
Browse files Browse the repository at this point in the history
  • Loading branch information
Lilaa3 committed Apr 22, 2024
1 parent dbedd48 commit b4cd67d
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 50 deletions.
13 changes: 10 additions & 3 deletions fast64_internal/sm64/animation/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,22 @@ def to_binary(
# 0x18
return data

def read_binary(self, header_reader: RomReading, is_dma: bool = False):
def read_binary(
self,
header_reader: RomReading,
is_dma: bool = False,
assumed_bone_count: int | None = None,
):
self.reference = header_reader.address
self.flags = header_reader.read_value(2, signed=False) # /*0x00*/ s16 flags;
self.trans_divisor = header_reader.read_value(2) # /*0x02*/ s16 animYTransDivisor;
self.start_frame = header_reader.read_value(2) # /*0x04*/ s16 startFrame;
self.loop_start = header_reader.read_value(2) # /*0x06*/ s16 loopStart;
self.loop_end = header_reader.read_value(2) # /*0x08*/ s16 loopEnd;
# Unused in engine but makes it easy to read animation data
self.bone_count = header_reader.read_value(2) # /*0x0A*/ s16 unusedBoneCount;
# /*0x0A*/ s16 unusedBoneCount;
bone_count = header_reader.read_value(2)
self.bone_count = bone_count if bone_count is not None else assumed_bone_count

# /*0x0C*/ const s16 *values;
# /*0x10*/ const u16 *index;
Expand Down Expand Up @@ -499,7 +506,7 @@ def to_binary(self, is_dma: bool = False, start_address: int = 0):
if anim_header.data:
ptrs.extend([start_address + len(data) + 12, start_address + len(data) + 16])
indice_offset = indice_tables_offset + sum(
len(indice_table.data) * 2 for indice_table in indice_tables[: data_set.index(anim_header.data)]
len(indice_table.data) * 2 for indice_table in indice_tables[: data_set.index(anim_header.data)]
)
data.extend(
anim_header.to_binary(
Expand Down
73 changes: 57 additions & 16 deletions fast64_internal/sm64/animation/importing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@
from ..sm64_constants import insertableBinaryTypes

from .utility import RomReading, get_anim_pose_bones, sm64_to_radian
from .classes import SM64_DMATable, DMATableEntrie, SM64_Anim, SM64_AnimData, SM64_AnimHeader, SM64_AnimPair, SM64_AnimTable
from .classes import (
SM64_DMATable,
DMATableEntrie,
SM64_Anim,
SM64_AnimData,
SM64_AnimHeader,
SM64_AnimPair,
SM64_AnimTable,
)
from .c_parser import CParser, EnumIndexedValue, Initialization


Expand Down Expand Up @@ -238,24 +246,25 @@ def import_binary_header(
header_reader: RomReading,
is_dma: bool,
animations: dict[str, SM64_Anim],
assumed_bone_count: int | None = None,
):
print(f"Reading binary header at address {hex(header_reader.address)}")
header = SM64_AnimHeader()
header.read_binary(header_reader, is_dma)
header.read_binary(header_reader=header_reader, is_dma=is_dma, assumed_bone_count=assumed_bone_count)

data_key = f"{header.indice_reference}-{header.values_reference}"
if data_key in animations:
anim = animations[data_key]
else:
anim = SM64_Anim()
# if header.indice_reference < len(data) and header.values_reference < len(data):
# TODO: if header.indice_reference < len(data) and header.values_reference < len(data):
if True:
anim.data = SM64_AnimData()
anim.data.read_binary(
header_reader.branch(header.indice_reference),
header_reader.branch(header.values_reference),
header.bone_count,
) # Add suport for using the bone ocunt in the selected armature
indices_reader=header_reader.branch(header.indice_reference),
values_reader=header_reader.branch(header.values_reference),
bone_count=header.bone_count,
)
animations[data_key] = anim

header.header_variant = len(anim.headers)
Expand All @@ -268,7 +277,8 @@ def import_binary_dma_animation(
dma_table_reader: RomReading,
animations: dict[str, SM64_Anim],
table: SM64_AnimTable,
table_index: int|None = None,
table_index: int | None = None,
assumed_bone_count: int | None = None,
) -> SM64_AnimHeader | None:
dma_table = SM64_DMATable()
dma_table.read_binary(dma_table_reader)
Expand All @@ -277,12 +287,22 @@ def import_binary_dma_animation(
raise PluginError(f"Index {table_index} outside of defined table ({len(dma_table.entries)} entries).")

entrie: DMATableEntrie = dma_table.entries[table_index]
header = import_binary_header(dma_table_reader.branch(entrie.address), True, animations)
header = import_binary_header(
header_reader=dma_table_reader.branch(entrie.address),
is_dma=True,
animations=animations,
assumed_bone_count=assumed_bone_count,
)
table.elements.append(header)
return header
else:
for entrie in dma_table.entries:
header = import_binary_header(dma_table_reader.branch(entrie.address), True, animations)
header = import_binary_header(
header_reader=dma_table_reader.branch(entrie.address),
is_dma=True,
animations=animations,
assumed_bone_count=assumed_bone_count,
)
table.elements.append(header)


Expand All @@ -291,7 +311,8 @@ def import_binary_table(
animations: dict[str, SM64_Anim],
table: SM64_AnimTable,
ignore_null: bool,
table_index: int|None = None,
table_index: int | None = None,
assumed_bone_count: int | None = None,
):
for i in range(255):
ptr = table_reader.read_ptr()
Expand All @@ -302,7 +323,12 @@ def import_binary_table(

is_correct_index = i == table_index
if table_index is None or is_correct_index:
header = import_binary_header(table_reader.branch(ptr), False, animations)
header = import_binary_header(
header_reader=table_reader.branch(ptr),
is_dma=False,
animations=animations,
assumed_bone_count=assumed_bone_count,
)
table.elements.append(header)

if table_index is not None and is_correct_index:
Expand All @@ -315,9 +341,10 @@ def import_binary_animations(
data_reader: RomReading,
import_type: str,
animations: dict[str, SM64_Anim],
table: SM64_AnimTable,
table_index: int|None = None,
table_index: int | None = None,
ignore_null: bool = False,
assumed_bone_count: int | None = None,
table: SM64_AnimTable = SM64_AnimTable(),
):
if import_type == "Table":
import_binary_table(
Expand All @@ -326,16 +353,23 @@ def import_binary_animations(
table=table,
table_index=table_index,
ignore_null=ignore_null,
assumed_bone_count=assumed_bone_count,
)
elif import_type == "DMA":
import_binary_dma_animation(
dma_table_reader=data_reader,
animations=animations,
table=table,
table_index=table_index,
assumed_bone_count=assumed_bone_count,
)
elif import_type == "Animation":
import_binary_header(data_reader, False, animations)
import_binary_header(
header_reader=data_reader,
is_dma=False,
animations=animations,
assumed_bone_count=assumed_bone_count,
)
else:
raise PluginError("Unimplemented binary import type.")

Expand All @@ -345,6 +379,7 @@ def import_insertable_binary_animations(
animations: dict[str, SM64_Anim],
table_index: int = 0,
ignore_null: bool = False,
assumed_bone_count: int | None = None,
table: SM64_AnimTable = SM64_AnimTable(),
):
data_type_num = insertable_data_reader.read_value(4, signed=False)
Expand All @@ -367,14 +402,20 @@ def import_insertable_binary_animations(

data_type = next(key for key, value in insertableBinaryTypes.items() if value == data_type_num)
if data_type == "Animation":
import_binary_header(data_reader, False, animations)
import_binary_header(
header_reader=data_reader,
is_dma=False,
animations=animations,
assumed_bone_count=assumed_bone_count,
)
elif data_type == "Animation Table":
import_binary_table(
table_reader=data_reader,
animations=animations,
table=table,
table_index=table_index,
ignore_null=ignore_null,
assumed_bone_count=assumed_bone_count,
)
else:
raise PluginError(f'Wrong animation data type "{data_type}".')
37 changes: 21 additions & 16 deletions fast64_internal/sm64/animation/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@
update_table_file,
write_anim_header,
)
from .utility import (
animation_operator_checks,
eval_num_from_str,
get_action,
)
from .utility import animation_operator_checks, eval_num_from_str, get_action, get_anim_pose_bones
from .constants import marioAnimationNames

from typing import TYPE_CHECKING
Expand Down Expand Up @@ -452,9 +448,9 @@ def execute_operator(self, context: Context):
table_props.update_table,
)
elif sm64_props.export_type == "Insertable Binary":
#data, ptrs = animation.to_binary(export_props.is_binary_dma, 0)
#path = abspath(export_props.insertable_path)
#writeInsertableFile(path, 2, ptrs, 0, data)
# data, ptrs = animation.to_binary(export_props.is_binary_dma, 0)
# path = abspath(export_props.insertable_path)
# writeInsertableFile(path, 2, ptrs, 0, data)
pass
else:
raise PluginError(f"Unimplemented export type ({sm64_props.export_type})")
Expand Down Expand Up @@ -546,6 +542,8 @@ def execute_operator(self, context):
import_props: SM64_AnimImportProps = sm64_props.anim_import
table_props: SM64_AnimTableProps = export_props.table

armature_obj: Object = context.selected_objects[0]

animations: dict[str, SM64_Anim] = {}
table = SM64_AnimTable()

Expand All @@ -560,36 +558,43 @@ def execute_operator(self, context):
else:
rom_data, segment_data = None, None

anim_bones = get_anim_pose_bones(armature_obj)
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
)
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(
data_reader=RomReading(data=rom_data, start_address=address, rom_data=rom_data, segment_data=segment_data),
data_reader=RomReading(
data=rom_data, start_address=address, rom_data=rom_data, segment_data=segment_data
),
import_type=import_props.binary_import_type,
animations=animations,
table_index=None if import_props.read_entire_table else import_props.mario_or_table_index,
ignore_null=import_props.ignore_null,
table=table,
assumed_bone_count=assumed_bone_count,
)
elif import_props.import_type == "Insertable Binary":
insertable_path = abspath(import_props.insertable_path)
filepath_checks(insertable_path)
path = abspath(import_props.path)
filepath_checks(path)

with open(insertable_path, "rb") as insertable_file:
with open(path, "rb") as insertable_file:
import_insertable_binary_animations(
insertable_data_reader=RomReading(insertable_file.read(), 0, None, rom_data, segment_data),
animations=animations,
table=table,
table_index=None if import_props.read_entire_table else import_props.mario_or_table_index,
ignore_null=import_props.ignore_null,
assumed_bone_count=assumed_bone_count,
)
elif import_props.import_type == "C":
c_path = abspath(import_props.c_path)
path_checks(c_path)
import_c_animations(c_path, animations, table)
path = abspath(import_props.path)
path_checks(path)
import_c_animations(path, animations, table)

for data in animations.values():
animation_import_to_blender(
Expand All @@ -600,7 +605,7 @@ def execute_operator(self, context):
import_props.remove_name_footer,
import_props.use_custom_name,
)
sm64_props.anim_export.table.from_anim_table_class(table)
table_props.from_anim_table_class(table)

self.report({"INFO"}, "Success!")
return {"FINISHED"}
Expand Down
Loading

0 comments on commit b4cd67d

Please sign in to comment.