# SPDX-FileCopyrightText: © 2025 ZeldaRET # SPDX-License-Identifier: CC0-1.0 from typing import TYPE_CHECKING if TYPE_CHECKING: from ..extase import MemoryContext from ..extase.cdata_resources import ( CDataResource, CDataArrayResource, CDataExt_Struct, CDataExt_Value, CDataExtWriteContext, fmt_hex_s, ) class PlayerAnimationDataResource(CDataArrayResource): elem_cdata_ext = CDataExt_Value("h").set_write_str_v(lambda v: fmt_hex_s(v)) def __init__(self, file, range_start, name): super().__init__(file, range_start, name) self.frame_count_name = f"FRAMECOUNT_{self.symbol_name}" def set_frame_count(self, frame_count: int): self.set_length(frame_count * (22 * 3 + 1)) self.frame_count = frame_count def write_c_declaration(self, h): h.write(f"#define {self.frame_count_name} {self.frame_count}\n") super().write_c_declaration(h) def get_c_declaration_base(self): return f"s16 {self.symbol_name}[{self.frame_count_name} * (PLAYER_LIMB_MAX * 3 + 1)]" def get_h_includes(self): return ("ultra64.h", "player.h") class PlayerAnimationResource(CDataResource): def report(resource, memory_context: "MemoryContext", v): assert isinstance(v, dict) segment = v["segment"] assert isinstance(segment, int) player_animation_data_res = memory_context.report_resource_at_segmented( resource, segment, PlayerAnimationDataResource, lambda file, offset: PlayerAnimationDataResource( file, offset, f"{resource.name}_{segment:08X}_PlayerAnimData" ), ) player_animation_data_res.set_frame_count(v["common"]["frameCount"]) def write_frameCount( resource, memory_context: "MemoryContext", v, wctx: CDataExtWriteContext ): address = resource.cdata_unpacked["segment"] assert isinstance(address, int) wctx.f.write(wctx.line_prefix) wctx.f.write( memory_context.resolve_segmented(address) .get_resource(PlayerAnimationDataResource) .frame_count_name ) return True def write_segment( resource, memory_context: "MemoryContext", v, wctx: CDataExtWriteContext ): assert isinstance(v, int) address = v wctx.f.write(wctx.line_prefix) wctx.f.write(memory_context.get_c_reference_at_segmented(address)) return True cdata_ext = CDataExt_Struct( ( ( "common", CDataExt_Struct( (("frameCount", CDataExt_Value("h").set_write(write_frameCount)),) ), ), ("pad2", CDataExt_Value.pad16), ("segment", CDataExt_Value("I").set_write(write_segment)), ) ).set_report(report) def get_c_reference(self, resource_offset: int): if resource_offset == 0: return f"&{self.symbol_name}" else: raise ValueError() def get_c_declaration_base(self): return f"LinkAnimationHeader {self.symbol_name}" def get_h_includes(self): return ("animation.h",)