Skip to content

Commit

Permalink
binary works again wtf wow amazing lila you are so amazing tm
Browse files Browse the repository at this point in the history
  • Loading branch information
Lilaa3 committed Apr 22, 2024
1 parent 7446efd commit 936d16f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 76 deletions.
47 changes: 19 additions & 28 deletions fast64_internal/sm64/animation/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ def clean_frames(self): # TODO: How the fuck do you write this
def get_frame(self, frame: int):
return self.values[frame] if frame < len(self.values) else self.values[-1]

# Importing
def read_binary(self, indices_reader: RomReading, data: bytes, valuesAddress: int):
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

value_reader = RomReading(data, valuesAddress + value_offset)
values_reader = values_reader.branch(values_reader.address + value_offset)
for _ in range(max_frame):
value = value_reader.read_value(2, signed=True)
value = values_reader.read_value(2, signed=True)
self.values.append(value)

def read_c(self, maxFrame, offset, values: list[int]):
Expand Down Expand Up @@ -105,13 +104,12 @@ def to_binary(self, start_address: int = 0) -> bytearray:

return data, values_address

def read_binary(self, data: bytes, indices_address, values_address, bone_count: int):
self.indice_reference = indices_address
self.values_reference = values_address
indices_reader = RomReading(data, indices_address)
def read_binary(self, indices_reader: RomReading, values_reader: RomReading, bone_count: int):
self.indice_reference = indices_reader.address
self.values_reference = values_reader.address
for _ in range((bone_count + 1) * 3):
pair = SM64_AnimPair()
pair.read_binary(indices_reader, data, values_address)
pair.read_binary(indices_reader, values_reader)
pair.clean_frames()
self.pairs.append(pair)

Expand Down Expand Up @@ -237,11 +235,8 @@ def to_binary(
# 0x18
return data

# Importing
def read_binary(
self, header_reader: RomReading, address: int, is_dma: bool = False
):
self.reference = address
def read_binary(self, header_reader: RomReading, is_dma: bool = False):
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;
Expand All @@ -250,15 +245,15 @@ def read_binary(
# Unused in engine but makes it easy to read animation data
self.bone_count = header_reader.read_value(2) # /*0x0A*/ s16 unusedBoneCount;

values_offfset = header_reader.read_ptr() # /*0x0C*/ const s16 *values;
indices_offset = header_reader.read_ptr() # /*0x10*/ const u16 *index;

# /*0x0C*/ const s16 *values;
# /*0x10*/ const u16 *index;
if is_dma:
self.values_reference = address + values_offfset
self.indice_reference = address + indices_offset
start_address = header_reader.start_address
self.values_reference = start_address + header_reader.read_value(4, signed=False)
self.indice_reference = start_address + header_reader.read_value(4, signed=False)
else:
self.values_reference = values_offfset
self.indice_reference = indices_offset
self.values_reference = header_reader.read_ptr()
self.indice_reference = header_reader.read_ptr()

def read_c(self, value: Initialization):
self.file_name = os.path.basename(value.origin_path)
Expand Down Expand Up @@ -432,27 +427,23 @@ class DMATableEntrie:


@dataclasses.dataclass
class DMATable:
class SM64_DMATable:
address_place_holder: int = 0
entries: list[DMATableEntrie] = dataclasses.field(default_factory=list)
data: bytes = dataclasses.field(default_factory=bytes)

def read_binary(self, rom_data: bytes, address: int):
dma_table_reader = RomReading(rom_data, address)
def read_binary(self, dma_table_reader: RomReading):
num_entries = dma_table_reader.read_value(4) # numEntries
self.address_place_holder = dma_table_reader.read_value(4) # addrPlaceholder

end_of_table = 0
for _ in range(num_entries):
offset = dma_table_reader.read_value(4)
size = dma_table_reader.read_value(4)
self.entries.append(DMATableEntrie(offset, size, address + offset))
self.entries.append(DMATableEntrie(offset, size, dma_table_reader.start_address + offset))
end_of_entry = offset + size
if end_of_entry > end_of_table:
end_of_table = end_of_entry

self.data = rom_data[address : address + end_of_table]


def num_to_padded_hex(num: int):
hex_str = hex(num)[2:].upper() # remove the '0x' prefix
Expand Down
59 changes: 30 additions & 29 deletions fast64_internal/sm64/animation/importing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..sm64_constants import insertableBinaryTypes

from .utility import RomReading, get_anim_pose_bones, sm64_to_radian
from .classes import 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 @@ -143,7 +143,7 @@ def animation_import_to_blender(
if armature_obj.animation_data is None:
armature_obj.animation_data_create()

if not anim_import.data:
if anim_import.data:
animation_data_to_blender(
armature_obj=armature_obj,
blender_to_sm64_scale=blender_to_sm64_scale,
Expand Down Expand Up @@ -239,7 +239,7 @@ def import_binary_header(
is_dma: bool,
animations: dict[str, SM64_Anim],
):
print(f"Reading binary header at address {header_reader.address}")
print(f"Reading binary header at address {hex(header_reader.address)}")
header = SM64_AnimHeader()
header.read_binary(header_reader, is_dma)

Expand All @@ -248,10 +248,13 @@ def import_binary_header(
anim = animations[data_key]
else:
anim = SM64_Anim()
if header.indice_reference < len(data) and header.values_reference < len(data):
# if header.indice_reference < len(data) and header.values_reference < len(data):
if True:
anim.data = SM64_AnimData()
anim.data.read_binary(
data, header.indice_reference, header.values_reference, header.bone_count
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
animations[data_key] = anim

Expand All @@ -262,49 +265,47 @@ def import_binary_header(


def import_binary_dma_animation(
rom_data: BufferedReader,
address: int,
dma_table_reader: RomReading,
animations: dict[str, SM64_Anim],
table: SM64_AnimTable,
table_index: Optional[int] = None,
table_index: int|None = None,
) -> SM64_AnimHeader | None:
dma_table = DMATable()
dma_table.read_binary(rom_data, address)
if not table_index is None:
dma_table = SM64_DMATable()
dma_table.read_binary(dma_table_reader)
if table_index is not None:
if table_index < 0 or table_index >= len(dma_table.entries):
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(rom_data, entrie.address, True, animations)
header = import_binary_header(dma_table_reader.branch(entrie.address), True, animations)
table.elements.append(header)
return header
else:
for entrie in dma_table.entries:
header = import_binary_header(rom_data, entrie.address, True, animations)
header = import_binary_header(dma_table_reader.branch(entrie.address), True, animations)
table.elements.append(header)


def import_binary_table(
table_reader: RomReading,
animations: dict[str, SM64_Anim],
read_entire_table: bool,
table_index: int,
ignore_null: bool,
table: SM64_AnimTable,
ignore_null: bool,
table_index: int|None = None,
):
for i in range(255):
ptr = table_reader.read_ptr()
if ptr is None and not ignore_null:
if not read_entire_table:
if table_index is not None:
raise PluginError("Table index not in table.")
break

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

if not read_entire_table and is_correct_index:
if table_index is not None and is_correct_index:
break
else:
raise PluginError("Table address is invalid, iterated through 255 indices and no NULL was found.")
Expand All @@ -314,33 +315,34 @@ def import_binary_animations(
data_reader: RomReading,
import_type: str,
animations: dict[str, SM64_Anim],
read_entire_table: bool = False,
table_index: int = 0,
table: SM64_AnimTable,
table_index: int|None = None,
ignore_null: bool = False,
table: SM64_AnimTable = SM64_AnimTable(),
):
if import_type == "Table":
import_binary_table(
table_reader=data_reader,
animations=animations,
table=table,
read_entire_table=read_entire_table,
table_index=table_index,
ignore_null=ignore_null,
)
elif import_type == "DMA":
import_binary_dma_animation(data_reader, data_reader.address, animations, table, table_index if read_entire_table else None)
import_binary_dma_animation(
dma_table_reader=data_reader,
animations=animations,
table=table,
table_index=table_index,
)
elif import_type == "Animation":
import_binary_header(data_reader, data_reader.address, False, animations)
import_binary_header(data_reader, False, animations)
else:
raise PluginError("Unimplemented binary import type.")


def import_insertable_binary_animations(
insertable_data_reader: RomReading,
animations: dict[str, SM64_Anim],
segment_data: Optional[dict[int, tuple[int, int]]] = None,
read_entire_table: bool = False,
table_index: int = 0,
ignore_null: bool = False,
table: SM64_AnimTable = SM64_AnimTable(),
Expand Down Expand Up @@ -370,10 +372,9 @@ def import_insertable_binary_animations(
import_binary_table(
table_reader=data_reader,
animations=animations,
read_entire_table=read_entire_table,
table=table,
table_index=table_index,
ignore_null=ignore_null,
table=table,
)
else:
raise PluginError(f'Wrong animation data type "{data_type}".')
22 changes: 10 additions & 12 deletions fast64_internal/sm64/animation/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from ..sm64_level_parser import parseLevelAtPointer
from ..sm64_constants import level_pointers, insertableBinaryTypes

from .classes import DMATable, DMATableEntrie, SM64_Anim, SM64_AnimTable, RomReading
from .classes import SM64_DMATable, DMATableEntrie, SM64_Anim, SM64_AnimTable, RomReading
from .importing import (
import_binary_animations,
import_binary_dma_animation,
Expand Down Expand Up @@ -561,18 +561,17 @@ def execute_operator(self, context):

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
)
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(
RomReading(data=rom_data, start_address=address, rom_data=rom_data, segment_data=segment_data),
import_props.binary_import_type,
animations,
import_props.read_entire_table,
import_props.mario_or_table_index,
import_props.ignore_null,
table,
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,
)
elif import_props.import_type == "Insertable Binary":
insertable_path = abspath(import_props.insertable_path)
Expand All @@ -584,8 +583,7 @@ def execute_operator(self, context):
animations=animations,
table=table,
segment_data=segment_data,
read_entire_table=import_props.read_entire_table,
table_index=import_props.mario_or_table_index,
table_index=import_props.mario_or_table_index if import_props.read_entire_table else None,
ignore_null=import_props.ignore_null,
)
elif import_props.import_type == "C":
Expand Down
16 changes: 9 additions & 7 deletions fast64_internal/sm64/animation/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,20 @@ def __init__(
self.segment_data = segment_data

def branch(self, start_address: int, data: bytes | None = None):
branch = copy.copy(self)
if data:
branch.data = data
branch.start_address = start_address
branch.address = start_address
return self
branch = RomReading(
data if data else self.data,
start_address,
self.insertable_ptrs,
self.rom_data,
self.segment_data,
)
return branch

def read_ptr(self):
in_bytes = self.data[self.address : self.address + 4]
self.address += 4
ptr = int.from_bytes(in_bytes, "big", signed=False)

if ptr == 0:
return None

Expand Down

0 comments on commit 936d16f

Please sign in to comment.