From ab79222574b4cfccbb0054ff80aba9fd2376226e Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Sun, 12 Apr 2026 23:18:18 +0200 Subject: [PATCH] `tools/assets` cleanup pass (mostly typing) (#2705) * address easy todos * add type asserts * format * add type hints * more typing fixes * more asserts for typing * break long f string --- tools/assets/descriptor/n64resources.py | 30 ++++------- tools/assets/extract/extase/__init__.py | 40 ++++++++++---- .../assets/extract/extase/cdata_resources.py | 15 ++++++ tools/assets/extract/extase/repr_c_struct.py | 52 ++++++++++++------- .../extase_oot64/animation_resources.py | 4 +- .../extase_oot64/collision_resources.py | 17 +++++- .../extract/extase_oot64/dlist_resources.py | 22 +++++--- .../extract/extase_oot64/misc_resources.py | 1 + .../extase_oot64/room_shape_resources.py | 3 ++ .../extase_oot64/scene_commands_resource.py | 15 +++--- .../extase_oot64/scene_rooms_resources.py | 4 +- .../extase_oot64/skelcurve_resources.py | 6 +-- .../extase_oot64/skeleton_resources.py | 2 +- tools/assets/extract/oot64_data/__init__.py | 1 + tools/assets/extract/z64_resource_handlers.py | 2 +- 15 files changed, 143 insertions(+), 71 deletions(-) diff --git a/tools/assets/descriptor/n64resources.py b/tools/assets/descriptor/n64resources.py index fe7c7172da..b88c69f4b3 100644 --- a/tools/assets/descriptor/n64resources.py +++ b/tools/assets/descriptor/n64resources.py @@ -16,9 +16,6 @@ from .base import ( ) from . import xml_errors -# TODO remove -STATIC_ATTRIB = {"Static"} - class GfxMicroCode(enum.Enum): F3DEX = enum.auto() @@ -33,9 +30,7 @@ class DListResourceDesc(ResourceDesc): def handler_DList(symbol_name, offset, collection, reselem: Element): - xml_errors.check_attrib( - reselem, {"Name", "Offset"}, {"Ucode", "RawPointers"} | STATIC_ATTRIB - ) + xml_errors.check_attrib(reselem, {"Name", "Offset"}, {"Ucode", "RawPointers"}) if "Ucode" in reselem.attrib: ucode = GfxMicroCode[reselem.attrib["Ucode"].upper()] else: @@ -54,7 +49,7 @@ class BlobResourceDesc(ResourceDesc): def handler_Blob(symbol_name, offset, collection, reselem: Element): - xml_errors.check_attrib(reselem, {"Name", "Offset", "Size"}, STATIC_ATTRIB) + xml_errors.check_attrib(reselem, {"Name", "Offset", "Size"}) size = int(reselem.attrib["Size"], 16) return BlobResourceDesc(symbol_name, offset, collection, reselem, size) @@ -65,7 +60,7 @@ class MtxResourceDesc(ResourceDesc): def handler_Mtx(symbol_name, offset, collection, reselem: Element): - xml_errors.check_attrib(reselem, {"Name", "Offset"}, STATIC_ATTRIB) + xml_errors.check_attrib(reselem, {"Name", "Offset"}) return MtxResourceDesc(symbol_name, offset, collection, reselem) @@ -85,7 +80,7 @@ class VtxArrayResourceDesc(ResourceDesc): def handler_Array(symbol_name, offset, collection, reselem: Element): - xml_errors.check_attrib(reselem, {"Name", "Offset", "Count"}, STATIC_ATTRIB) + xml_errors.check_attrib(reselem, {"Name", "Offset", "Count"}) count = int(reselem.attrib["Count"]) assert len(reselem) == 1, "Expected exactly one child of Array node" array_elem = reselem[0] @@ -138,16 +133,14 @@ def handler_Texture( xml_errors.check_attrib( reselem, {"Name", "Offset", "Format", "Width", "Height"}, - # TODO remove OutName, SplitTlut + # TODO remove SplitTlut { - "OutName", "SplitTlut", "TlutOffset", "ExternalTlut", "ExternalTlutOffset", "HackMode", - } - | STATIC_ATTRIB, + }, ) format = TextureFormat[reselem.attrib["Format"].upper()] width = int(reselem.attrib["Width"]) @@ -170,8 +163,8 @@ def handler_Texture( xml_errors.check_attrib( reselem, {"Name", "Offset", "Format", "Width", "Height", "TlutOffset"}, - # TODO remove OutName, SplitTlut - {"OutName", "SplitTlut", "HackMode"} | STATIC_ATTRIB, + # TODO remove SplitTlut + {"SplitTlut", "HackMode"}, ) tlut_offset = int(reselem.attrib["TlutOffset"], 16) @@ -200,8 +193,8 @@ def handler_Texture( "ExternalTlut", "ExternalTlutOffset", }, - # TODO remove OutName, SplitTlut - {"OutName", "SplitTlut", "HackMode"} | STATIC_ATTRIB, + # TODO remove SplitTlut + {"SplitTlut", "HackMode"}, ) external_tlut_file = reselem.attrib["ExternalTlut"] external_tlut_offset = int(reselem.attrib["ExternalTlutOffset"], 16) @@ -230,8 +223,7 @@ def handler_Texture( xml_errors.check_attrib( reselem, {"Name", "Offset", "Format", "Width", "Height"}, - # TODO remove OutName - {"OutName", "HackMode"} | STATIC_ATTRIB, + {"HackMode"}, ) res = TextureResourceDesc( symbol_name, offset, collection, reselem, format, width, height diff --git a/tools/assets/extract/extase/__init__.py b/tools/assets/extract/extase/__init__.py index 066fdf7b0b..c6fb107548 100644 --- a/tools/assets/extract/extase/__init__.py +++ b/tools/assets/extract/extase/__init__.py @@ -8,7 +8,7 @@ import enum import reprlib import io -from typing import TYPE_CHECKING, Sequence, Optional, Union, Any, Iterable +from typing import TYPE_CHECKING, Sequence, Optional, Union, Any, Iterable, Generator from pprint import pprint @@ -398,6 +398,8 @@ class File: # Ignore markers falling within existing resources result, resource = self.get_resource_at(file_start) if result == GetResourceAtResult.DEFINITIVE: + assert resource is not None + assert resource.range_end is not None if resource.range_start <= file_start < file_end <= resource.range_end: assert isinstance(resource, resource_type) resource.reporters.add(reporter) @@ -491,6 +493,8 @@ class File: self.add_resource(resource) else: assert result == GetResourceAtResult.DEFINITIVE + assert resource is not None + assert resource.range_end is not None assert ( resource.range_start <= rbm.file_start @@ -515,6 +519,7 @@ class File: unaccounted_resources: list[Resource] = [] def add_unaccounted(range_start, range_end): + assert self.data is not None if I_D_OMEGALUL: # IDO aligns every declaration to 4, so declaring zeros # that is actually padding for that purpose throws off matching. @@ -577,6 +582,10 @@ class File: # Add unaccounted if needed at the end of the file resource_last = self._resources[-1] + assert resource_last.range_end is not None, ( + "add_unaccounted_resources should be called once all" + " resources are parsed and have a definitive range" + ) if resource_last.range_end < len(self.data): add_unaccounted( resource_last.range_end, @@ -589,6 +598,10 @@ class File: for i in range(1, len(self._resources)): resource_a = self._resources[i - 1] resource_b = self._resources[i] + assert resource_a.range_end is not None, ( + "add_unaccounted_resources should be called once all" + " resources are parsed and have a definitive range" + ) assert resource_a.range_end <= resource_b.range_start # Add unaccounted if needed between two successive resources @@ -641,11 +654,12 @@ class File: self.source_h_path = source_path / f"{file_name}.h" def write_source(self): - def strip_extracted_prefix(path : Path) -> Path: + def strip_extracted_prefix(path: Path) -> Path: parts = path.parts if parts[0] == "extracted": return Path(*parts[2:]) # Skip first two parts return path # Return original path if condition not met + assert hasattr( self, "source_c_path" ), "set_source_path must be called before write_source" @@ -665,7 +679,9 @@ class File: referenced_file, ) assert hasattr(referenced_file, "source_h_path") - file_include_paths_complete.append(strip_extracted_prefix(referenced_file.source_h_path)) + file_include_paths_complete.append( + strip_extracted_prefix(referenced_file.source_h_path) + ) # Same as file_include_paths_complete, # but paths that can be are made relative to the source C. @@ -838,7 +854,7 @@ class Resource(abc.ABC): TODO figure out what to do with this, for now thinking debugging""" @abc.abstractmethod - def try_parse_data(self, memory_context: "MemoryContext"): + def try_parse_data(self, memory_context: "MemoryContext") -> object: """Parse this resource's data bytes This can typically result in finding more resources, @@ -879,7 +895,7 @@ class Resource(abc.ABC): """ ... - def get_c_expression_length(self, resource_offset: int): + def get_c_expression_length(self, resource_offset: int) -> str: """Get a C expression for referencing the length of data in this resource The offset `resource_offset` is relative to the resource, as in get_c_reference. @@ -1049,7 +1065,7 @@ class Resource(abc.ABC): + ")" ) - def __rich_repr__(self): + def __rich_repr__(self) -> Generator[str | tuple[str, Any], None, None]: yield self.name yield ( f"0x{self.range_start:08X}-" @@ -1070,13 +1086,15 @@ class ZeroPaddingResource(Resource): *, include_in_source=True, ): - # TODO move to try_parse_data ? - assert set(file.data[range_start:range_end]) == {0} super().__init__(file, range_start, range_end, name) self.include_in_source = include_in_source def try_parse_data(self, memory_context): - # Nothing specific to do + # Check the data is 0s + assert self.file.data is not None + if set(self.file.data[self.range_start : self.range_end]) != {0}: + raise ResourceParseImpossible("Not zero padding") + return RESOURCE_PARSE_SUCCESS def get_c_reference(self, resource_offset): @@ -1090,6 +1108,7 @@ class ZeroPaddingResource(Resource): pass def get_c_declaration_base(self): + assert self.range_end is not None length_bytes = self.range_end - self.range_start assert length_bytes > 0 return f"u8 {self.symbol_name}[{length_bytes}]" @@ -1116,6 +1135,7 @@ class BinaryBlobResource(Resource): return RESOURCE_PARSE_SUCCESS def get_as_xml(self): + assert self.range_end is not None return f"""\ """ @@ -1129,6 +1149,8 @@ class BinaryBlobResource(Resource): return ("ultra64.h",) def write_extracted(self, memory_context): + assert self.file.data is not None + assert self.range_end is not None data = self.file.data[self.range_start : self.range_end] assert len(data) == self.range_end - self.range_start self.extract_to_path.write_bytes(data) diff --git a/tools/assets/extract/extase/cdata_resources.py b/tools/assets/extract/extase/cdata_resources.py index d959a0c1f5..1f5d93e32e 100644 --- a/tools/assets/extract/extase/cdata_resources.py +++ b/tools/assets/extract/extase/cdata_resources.py @@ -168,6 +168,20 @@ class CDataExt_Value(CData_Value, CDataExt): else: return False + s8: "CDataExt_Value" + u8: "CDataExt_Value" + s16: "CDataExt_Value" + u16: "CDataExt_Value" + s32: "CDataExt_Value" + u32: "CDataExt_Value" + f32: "CDataExt_Value" + f64: "CDataExt_Value" + pointer: "CDataExt_Value" + + pad8: "CDataExt_Value" + pad16: "CDataExt_Value" + pad32: "CDataExt_Value" + CDataExt_Value.s8 = CDataExt_Value("b").freeze() CDataExt_Value.u8 = CDataExt_Value("B").freeze() @@ -277,6 +291,7 @@ class CDataResource(Resource): self._is_cdata_processed = False def try_parse_data(self, memory_context: "MemoryContext"): + assert self.file.data is not None if self.can_size_be_unknown: assert hasattr(self, "cdata_ext") and self.cdata_ext is not None, ( "Subclasses with can_size_be_unknown=True should redefine try_parse_data" diff --git a/tools/assets/extract/extase/repr_c_struct.py b/tools/assets/extract/extase/repr_c_struct.py index 3548ede370..c20ab31d15 100644 --- a/tools/assets/extract/extase/repr_c_struct.py +++ b/tools/assets/extract/extase/repr_c_struct.py @@ -38,6 +38,16 @@ class CData_Value(CData): def unpack_from(self, data: memoryview, offset: int = 0): return self.unpack_struct.unpack_from(data, offset)[0] + s8: "CData_Value" + u8: "CData_Value" + s16: "CData_Value" + u16: "CData_Value" + s32: "CData_Value" + u32: "CData_Value" + f32: "CData_Value" + f64: "CData_Value" + pointer: "CData_Value" + CData_Value.s8 = CData_Value("b") CData_Value.u8 = CData_Value("B") @@ -142,26 +152,30 @@ def try_stuff(): } data = { varLenArray, 3, { 421, 0x01020304 } }; """ - array_bytes = bytes( - [ - 1, - 0, - *(0, 2), - 3, - 0, - *(0, 4), - ] + array_bytes = memoryview( + bytes( + [ + 1, + 0, + *(0, 2), + 3, + 0, + *(0, 4), + ] + ) ) - varLenArray_bytes = bytes([1, 2, 3]) - data_bytes = bytes( - [ - *(0x12, 0x34, 0x56, 0x78), - *(0, 3), - 0, - 0, - *(0, 0, 421 >> 8, 421 & 0xFF), - *(1, 2, 3, 4), - ] + varLenArray_bytes = memoryview(bytes([1, 2, 3])) + data_bytes = memoryview( + bytes( + [ + *(0x12, 0x34, 0x56, 0x78), + *(0, 3), + 0, + 0, + *(0, 0, 421 >> 8, 421 & 0xFF), + *(1, 2, 3, 4), + ] + ) ) arrayElem_CData_Struct = CData_Struct( diff --git a/tools/assets/extract/extase_oot64/animation_resources.py b/tools/assets/extract/extase_oot64/animation_resources.py index 7a54f00c85..a9436f3925 100644 --- a/tools/assets/extract/extase_oot64/animation_resources.py +++ b/tools/assets/extract/extase_oot64/animation_resources.py @@ -30,7 +30,7 @@ class AnimationFrameDataResource(CDataResource, can_size_be_unknown=True): def __init__(self, file: File, range_start: int, name: str): super().__init__(file, range_start, name) - self.length = None + self.length: int | None = None def try_parse_data(self, memory_context): if self.length is not None: @@ -64,7 +64,7 @@ class AnimationJointIndicesResource(CDataResource, can_size_be_unknown=True): def __init__(self, file: File, range_start: int, name: str): super().__init__(file, range_start, name) - self.length = None + self.length: int | None = None def try_parse_data(self, memory_context): if self.length is not None: diff --git a/tools/assets/extract/extase_oot64/collision_resources.py b/tools/assets/extract/extase_oot64/collision_resources.py index d8005ba446..f2c1e6a22f 100644 --- a/tools/assets/extract/extase_oot64/collision_resources.py +++ b/tools/assets/extract/extase_oot64/collision_resources.py @@ -42,6 +42,7 @@ class CollisionVtxListResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"Vec3s {self.symbol_name}[{self.cdata_ext.length}]" return f"Vec3s {self.symbol_name}[]" @@ -161,6 +162,7 @@ class CollisionPolyListResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"CollisionPoly {self.symbol_name}[{self.cdata_ext.length}]" return f"CollisionPoly {self.symbol_name}[]" @@ -292,6 +294,7 @@ class CollisionSurfaceTypeListResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"SurfaceType {self.symbol_name}[{self.cdata_ext.length}]" return f"SurfaceType {self.symbol_name}[]" @@ -318,6 +321,7 @@ class BgCamFuncDataResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"Vec3s {self.symbol_name}[{self.cdata_ext.length}]" return f"Vec3s {self.symbol_name}[]" @@ -337,7 +341,7 @@ class BgCamFuncDataResource(CDataResource): class CollisionBgCamListResource(CDataResource): def write_bgCamFuncData( - resource: "CollisionSurfaceTypeListResource", + resource: "CollisionBgCamListResource", memory_context: "MemoryContext", v, wctx: CDataExtWriteContext, @@ -419,6 +423,7 @@ class CollisionBgCamListResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"BgCamInfo {self.symbol_name}[{self.cdata_ext.length}]" return f"BgCamInfo {self.symbol_name}[]" @@ -438,11 +443,19 @@ class CollisionBgCamListResource(CDataResource): class CollisionWaterBoxesResource(CDataResource): def write_properties(v): + assert isinstance(v, int) bgCamIndex = (v >> 0) & 0xFF lightIndex = (v >> 8) & 0x1F room = (v >> 13) & 0x3F setFlag19 = (v >> 19) & 1 - return f"WATERBOX_PROPERTIES(/* bgCamIndex */ {bgCamIndex}, /* lightIndex */ {lightIndex}, /* room */ {room}, /* setFlag19 */ {'true' if setFlag19 else 'false'})" + return ( + "WATERBOX_PROPERTIES(" + f"/* bgCamIndex */ {bgCamIndex}, " + f"/* lightIndex */ {lightIndex}, " + f"/* room */ {room}, " + f"/* setFlag19 */ {'true' if setFlag19 else 'false'}" + ")" + ) elem_cdata_ext = CDataExt_Struct( ( diff --git a/tools/assets/extract/extase_oot64/dlist_resources.py b/tools/assets/extract/extase_oot64/dlist_resources.py index f80a2f9954..9efa3b2230 100644 --- a/tools/assets/extract/extase_oot64/dlist_resources.py +++ b/tools/assets/extract/extase_oot64/dlist_resources.py @@ -147,6 +147,7 @@ class VtxArrayResource(CDataResource): super().__init__(file, range_start, name) def get_as_xml(self): + assert self.range_end is not None return f"""\ @@ -154,6 +155,7 @@ class VtxArrayResource(CDataResource): def get_c_declaration_base(self): if hasattr(self, "HACK_IS_STATIC_ON"): + assert isinstance(self.cdata_ext, CDataExt_Array) return f"Vtx {self.symbol_name}[{self.cdata_ext.length}]" return f"Vtx {self.symbol_name}[]" @@ -343,10 +345,11 @@ class TextureResource(Resource): if resource_ci.siz == G_IM_SIZ._4b: v_max = max(max((b >> 4) & 0xF, b & 0xF) for b in resource_ci_data) assert v_max < 16 - - if resource_ci.siz == G_IM_SIZ._8b: + elif resource_ci.siz == G_IM_SIZ._8b: v_max = max(resource_ci_data) assert v_max < 256 + else: + assert False, resource_ci.siz new_min_count = v_max + 1 @@ -446,6 +449,9 @@ class TextureResource(Resource): return f"{self.name}.{format_name}{elem_type_suffix}" def write_extracted(self, memory_context): + assert self.file.data is not None + assert self.range_end is not None + if self.is_tlut(): # TLUTs are extracted as part of the color-indexed textures using them @@ -605,10 +611,11 @@ class TLUTResource(TextureResource, can_size_be_unknown=True): if resource_ci.siz == G_IM_SIZ._4b: v_max = max(max((b >> 4) & 0xF, b & 0xF) for b in resource_ci_data) assert v_max < 16 - - if resource_ci.siz == G_IM_SIZ._8b: + elif resource_ci.siz == G_IM_SIZ._8b: v_max = max(resource_ci_data) assert v_max < 256 + else: + assert False, resource_ci.siz new_min_count = v_max + 1 @@ -645,6 +652,7 @@ class TextureSplitTlutResource(TextureResource): return f"{self.name}.ci8.split_{'lo' if self.lo_half else 'hi'}.tlut_{self.resource_tlut.name}" def write_extracted(self, memory_context): + assert self.file.data is not None data = self.file.data[self.range_start : self.range_end] assert len(data) == self.range_end - self.range_start @@ -652,7 +660,7 @@ class TextureSplitTlutResource(TextureResource): assert all(_b < 128 for _b in data) else: assert all(_b >= 128 for _b in data) - data = bytes(_b - 128 for _b in data) + data = memoryview(bytes(_b - 128 for _b in data)) tlut_data = self.resource_tlut.file.data[ self.resource_tlut.range_start : self.resource_tlut.range_end @@ -1024,9 +1032,9 @@ class ColorIndexedTexturesManager: texs: list["ColorIndexedTexturesManager.Tex"] def __init__(self, *, HACK_late_SetTextureLUT=False): - self.cur_tlut_mode: G_TT = None + self.cur_tlut_mode: G_TT | None = None - self.cur_tluts_count: int = None + self.cur_tluts_count: int | None = None self.cur_tluts: dict[int, ColorIndexedTexturesManager.Tlut] = dict() self.cur_texs: list[ColorIndexedTexturesManager.Tex] = [] diff --git a/tools/assets/extract/extase_oot64/misc_resources.py b/tools/assets/extract/extase_oot64/misc_resources.py index b4c02c82c5..3bb576a104 100644 --- a/tools/assets/extract/extase_oot64/misc_resources.py +++ b/tools/assets/extract/extase_oot64/misc_resources.py @@ -18,6 +18,7 @@ class CutsceneResource(Resource, can_size_be_unknown=True): super().__init__(file, range_start, None, name) def try_parse_data(self, memory_context): + assert self.file.data is not None assert self.range_start % 4 == 0 data = self.file.data[self.range_start :] num_bytes = len(data) diff --git a/tools/assets/extract/extase_oot64/room_shape_resources.py b/tools/assets/extract/extase_oot64/room_shape_resources.py index 935c5045b0..29153f3fcc 100644 --- a/tools/assets/extract/extase_oot64/room_shape_resources.py +++ b/tools/assets/extract/extase_oot64/room_shape_resources.py @@ -56,6 +56,8 @@ def report_room_shape_at_segmented( def get_room_shape_resource_type(file: File, offset: int): + assert file.data is not None + room_shape_type_int = file.data[offset] room_shape_type = RoomShapeType(room_shape_type_int) @@ -269,6 +271,7 @@ class JFIFResource(Resource): return f"{self.name}.jpg" def write_extracted(self, memory_context): + assert self.file.data is not None # TODO trim zeros at the end of the data self.extract_to_path.write_bytes( self.file.data[self.range_start : self.range_end] diff --git a/tools/assets/extract/extase_oot64/scene_commands_resource.py b/tools/assets/extract/extase_oot64/scene_commands_resource.py index aa6da2bc45..7ed7b87706 100644 --- a/tools/assets/extract/extase_oot64/scene_commands_resource.py +++ b/tools/assets/extract/extase_oot64/scene_commands_resource.py @@ -111,6 +111,7 @@ class SceneCommandsResource(Resource, can_size_be_unknown=True): self.exit_list_length = None def try_parse_data(self, memory_context: "MemoryContext"): + assert self.file.data is not None data = self.file.data[self.range_start :] new_progress_done = [] @@ -265,7 +266,6 @@ class SceneCommandsResource(Resource, can_size_be_unknown=True): new_progress_done.append(("reported ActorEntryListResource", cmd_id)) if cmd_id == SceneCmdId.SCENE_CMD_ID_EXIT_LIST: - # TODO length from collision assert data1 == 0 resource = memory_context.report_resource_at_segmented( self, @@ -423,6 +423,7 @@ class SceneCommandsResource(Resource, can_size_be_unknown=True): return f"SceneCmd {self.symbol_name}[]" def write_extracted(self, memory_context): + assert self.file.data is not None data = self.file.data[self.range_start : self.range_end] with self.extract_to_path.open("w") as f: if not self.braces_in_source: @@ -431,10 +432,12 @@ class SceneCommandsResource(Resource, can_size_be_unknown=True): (cmd_id_int, data1, pad2, data2_I) = struct.unpack_from( ">BBHI", data, offset ) - (_, data2_H0, data2_H1) = struct.unpack_from(">IHH", data, offset) (_, data2_B0, data2_B1, data2_B2, data2_B3) = struct.unpack_from( ">IBBBB", data, offset ) + (_, data2_b0, data2_b1, data2_b2, data2_b3) = struct.unpack_from( + ">Ibbbb", data, offset + ) cmd_id = SceneCmdId(cmd_id_int) f.write(" " * 4) f.write(scene_cmd_macro_name_by_cmd_id[cmd_id]) @@ -468,10 +471,9 @@ class SceneCommandsResource(Resource, can_size_be_unknown=True): f.write(memory_context.get_c_reference_at_segmented(address)) if cmd_id == SceneCmdId.SCENE_CMD_ID_WIND_SETTINGS: assert data1 == 0 - # TODO cast x,y,z to s8 - xDir = data2_B0 - yDir = data2_B1 - zDir = data2_B2 + xDir = data2_b0 + yDir = data2_b1 + zDir = data2_b2 strength = data2_B3 f.write(f"{xDir}, {yDir}, {zDir}, {strength}") if cmd_id == SceneCmdId.SCENE_CMD_ID_SPAWN_LIST: @@ -676,6 +678,7 @@ class AltHeadersResource(CDataArrayResource): ) # SceneCmd* def try_parse_data(self, memory_context): + assert self.file.data is not None length = 0 for i, (v,) in enumerate( struct.iter_unpack(">I", self.file.data[self.range_start :]) diff --git a/tools/assets/extract/extase_oot64/scene_rooms_resources.py b/tools/assets/extract/extase_oot64/scene_rooms_resources.py index 4c65ad8af4..c3bd510259 100644 --- a/tools/assets/extract/extase_oot64/scene_rooms_resources.py +++ b/tools/assets/extract/extase_oot64/scene_rooms_resources.py @@ -158,8 +158,8 @@ class SpawnListResource(CDataArrayResource): ) # (eventually) set by SceneCommandsResource - player_entry_list_length = None - room_list_length = None + player_entry_list_length: int | None = None + room_list_length: int | None = None def try_parse_data(self, memory_context): if self.player_entry_list_length is None or self.room_list_length is None: diff --git a/tools/assets/extract/extase_oot64/skelcurve_resources.py b/tools/assets/extract/extase_oot64/skelcurve_resources.py index ea872b8bc1..1eed98884b 100644 --- a/tools/assets/extract/extase_oot64/skelcurve_resources.py +++ b/tools/assets/extract/extase_oot64/skelcurve_resources.py @@ -27,7 +27,7 @@ class KnotCountsArrayResource(CDataResource, can_size_be_unknown=True): def __init__(self, file: File, range_start: int, name: str): super().__init__(file, range_start, name) - self.length = None + self.length: int | None = None def try_parse_data(self, memory_context: "MemoryContext"): if self.length is not None: @@ -63,7 +63,7 @@ class CurveInterpKnotArrayResource(CDataResource, can_size_be_unknown=True): def __init__(self, file: File, range_start: int, name: str): super().__init__(file, range_start, name) - self.length = None + self.length: int | None = None def try_parse_data(self, memory_context: "MemoryContext"): if self.length is not None: @@ -91,7 +91,7 @@ class ConstantDataArrayResource(CDataResource, can_size_be_unknown=True): def __init__(self, file: File, range_start: int, name: str): super().__init__(file, range_start, name) - self.length = None + self.length: int | None = None def try_parse_data(self, memory_context: "MemoryContext"): if self.length is not None: diff --git a/tools/assets/extract/extase_oot64/skeleton_resources.py b/tools/assets/extract/extase_oot64/skeleton_resources.py index 12fe050a61..afa69223cc 100644 --- a/tools/assets/extract/extase_oot64/skeleton_resources.py +++ b/tools/assets/extract/extase_oot64/skeleton_resources.py @@ -216,6 +216,7 @@ class SkeletonResourceBaseABC(CDataResource): return RESOURCE_PARSE_SUCCESS def write_c_declaration(self, h): + assert self.limbs_array_resource is not None h.write(f"typedef enum {self.enum_name} {{\n") limb_enum_members = ( self.enum_member_name_none, @@ -231,7 +232,6 @@ class SkeletonResourceBaseABC(CDataResource): ) h.write(f"}} {self.enum_name};\n") super().write_c_declaration(h) - return True @abc.abstractmethod def get_skeleton_header_cdata_unpacked(self) -> dict: ... diff --git a/tools/assets/extract/oot64_data/__init__.py b/tools/assets/extract/oot64_data/__init__.py index 8fac94032f..5d43371776 100644 --- a/tools/assets/extract/oot64_data/__init__.py +++ b/tools/assets/extract/oot64_data/__init__.py @@ -127,5 +127,6 @@ def get_skybox_id(skybox_id: int) -> str: def get_light_mode(light_mode: int) -> str: return misc_ids.LIGHT_MODES[light_mode] + def get_navi_quest_hint_file_id_name(navi_quest_hint_file_id: int) -> str: return misc_ids.NAVI_QUEST_HINT_FILE_IDS[navi_quest_hint_file_id] diff --git a/tools/assets/extract/z64_resource_handlers.py b/tools/assets/extract/z64_resource_handlers.py index d0b6c2067a..b2ac4a2fee 100644 --- a/tools/assets/extract/z64_resource_handlers.py +++ b/tools/assets/extract/z64_resource_handlers.py @@ -449,7 +449,7 @@ def register_resource_handlers(): ) -RESOURCE_HANDLERS: dict[str, ResourceHandler] = {} +RESOURCE_HANDLERS: dict[type[ResourceDesc], ResourceHandler] = {} def get_resource_from_desc(