1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-12 19:04:38 +00:00

some cleanup, use gNameTex_WIDTH/HEIGHT macros in dlists

This commit is contained in:
Dragorn421 2025-02-16 13:14:49 +01:00
parent 7cb604387b
commit b952b2db1e
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
7 changed files with 87 additions and 92 deletions

View file

@ -12,3 +12,7 @@ To run the extraction outside of `make setup`, use `./tools/extract_assets.sh VE
- Pass `-j` to use multiprocessing, making extraction quicker. Note that this makes for less readable errors if any error happens. - Pass `-j` to use multiprocessing, making extraction quicker. Note that this makes for less readable errors if any error happens.
- Pass `-s name` to extract assets using baserom file `name`. - Pass `-s name` to extract assets using baserom file `name`.
- Pass `-r -s 'name.*'` to extract assets using baserom files whose name match regular expression `name.*`. - Pass `-r -s 'name.*'` to extract assets using baserom files whose name match regular expression `name.*`.
There currently are various hacks in place in the extraction tool source code to make extraction of some corner cases possible, or to silence extraction warnings.
Some of these hacks check for the name of resources, so renaming a few specific resources may need updating the extraction tool's source too.
The plan is to eventually remove those hardcoded checks from the source and use a `HackMode` attribute in the xmls to trigger the hacks code paths.

View file

@ -768,7 +768,9 @@ class Resource(abc.ABC):
if range_end is None: if range_end is None:
assert self.can_size_be_unknown assert self.can_size_be_unknown
else: else:
assert range_start < range_end <= file.size assert (
range_start < range_end <= file.size
), f"{range_end=:#08X} out of range [{range_start=:#08X},{file.size=:#08X})"
self.file = file self.file = file

View file

@ -33,8 +33,6 @@ class CDataExt(CData, abc.ABC):
report_f = None report_f = None
write_f = None write_f = None
# TODO not sure what to name this, it doesn't have to be used for pointer reporting,
# more generic "callback" may be better idk yet
def set_report( def set_report(
self, report_f: Callable[["CDataResource", "MemoryContext", Any], None] self, report_f: Callable[["CDataResource", "MemoryContext", Any], None]
): ):
@ -395,7 +393,6 @@ cdata_ext_Vec3s = CDataExt_Struct(
) )
# TODO move to z64 ?
class Vec3sArrayResource(CDataResource): class Vec3sArrayResource(CDataResource):
elem_cdata_ext = cdata_ext_Vec3s elem_cdata_ext = cdata_ext_Vec3s

View file

@ -276,8 +276,6 @@ class MemoryContext:
direct_file_offset_start = self._direct_address_to_offset(address) direct_file_offset_start = self._direct_address_to_offset(address)
direct_file_offset_end = direct_file_offset_start + target_file.size direct_file_offset_end = direct_file_offset_start + target_file.size
# TODO should memory_map members be directly accessed,
# or should MemoryMap have functions (applies elsewhere in MemoryContext)
self.memory_map.direct.set( self.memory_map.direct.set(
direct_file_offset_start, direct_file_offset_start,
direct_file_offset_end, direct_file_offset_end,

View file

@ -268,7 +268,6 @@ class BgCamFuncDataResource(CDataResource):
element_cdata_ext = cdata_ext_Vec3s element_cdata_ext = cdata_ext_Vec3s
def __init__(self, file: File, range_start: int, range_end: int, name: str): def __init__(self, file: File, range_start: int, range_end: int, name: str):
# TODO see VtxArrayResource
count = (range_end - range_start) // self.element_cdata_ext.size count = (range_end - range_start) // self.element_cdata_ext.size
self.cdata_ext = CDataExt_Array(self.element_cdata_ext, count) self.cdata_ext = CDataExt_Array(self.element_cdata_ext, count)
super().__init__(file, range_start, name) super().__init__(file, range_start, name)

View file

@ -10,11 +10,11 @@ try:
except ModuleNotFoundError: except ModuleNotFoundError:
rich_pprint = print rich_pprint = print
# pip install pygfxd@git+https://github.com/Dragorn421/pygfxd.git@9d418bc5d1cebedfeec3455250bef29473055940
import pygfxd import pygfxd
if TYPE_CHECKING: if TYPE_CHECKING:
from ..extase.memorymap import MemoryContext from ..extase.memorymap import MemoryContext
from ..extase.memorymap import UnmappedAddressError, UnexpectedResourceTypeError
from ..extase import ( from ..extase import (
RESOURCE_PARSE_SUCCESS, RESOURCE_PARSE_SUCCESS,
@ -131,7 +131,6 @@ class VtxArrayResource(CDataResource):
).set_write(write_elem) ).set_write(write_elem)
def __init__(self, file: File, range_start: int, range_end: int, name: str): def __init__(self, file: File, range_start: int, range_end: int, name: str):
# TODO this is stupid (range_end -> num -> size -> range_end)
num = (range_end - range_start) // self.element_cdata_ext.size num = (range_end - range_start) // self.element_cdata_ext.size
self.cdata_ext = CDataExt_Array(self.element_cdata_ext, num) self.cdata_ext = CDataExt_Array(self.element_cdata_ext, num)
super().__init__(file, range_start, name) super().__init__(file, range_start, name)
@ -1266,89 +1265,86 @@ class DListResource(Resource, can_size_be_unknown=True):
def arg_fn_handle_Dim(arg_num: int): def arg_fn_handle_Dim(arg_num: int):
timg = pygfxd.gfxd_value_by_type(pygfxd.GfxdArgType.Timg, 0) timg = pygfxd.gfxd_value_by_type(pygfxd.GfxdArgType.Timg, 0)
""" # TODO port to memctx changes if timg is None:
if timg is not None: return False
_, timg_segmented, _ = timg _, timg_segmented, _ = timg
dim_args_i = [] dim_args_i = []
for arg_i in range(pygfxd.gfxd_arg_count()): for arg_i in range(pygfxd.gfxd_arg_count()):
if pygfxd.gfxd_arg_type(arg_i) == pygfxd.GfxdArgType.Dim: if pygfxd.gfxd_arg_type(arg_i) == pygfxd.GfxdArgType.Dim:
dim_args_i.append(arg_i) dim_args_i.append(arg_i)
assert arg_num in dim_args_i assert arg_num in dim_args_i
assert len(dim_args_i) <= 2 assert len(dim_args_i) <= 2
if len(dim_args_i) == 2: if len(dim_args_i) != 2:
width_arg_i, height_arg_i = dim_args_i return False
# TODO this width/height stuff is jank code width_arg_i, height_arg_i = dim_args_i
# probably introduce an attribute system instead for resources, generalizing the length system try:
try: timg_resolved = memory_context.resolve_segmented(timg_segmented)
( except UnmappedAddressError:
resolution, # TODO store failed resolutions somewhere, for later printing
resolution_info, # (in general, it would be nice to fail less and *firmly* warn more instead,
) = self.file.memory_context.resolve_segmented(timg_segmented) # even if it means having compilation fail on purpose (#error))
except NoSegmentBaseError: return False
# TODO store failed resolutions somewhere, for later printing try:
# (in general, it would be nice to fail less and *firmly* warn more instead, resolved_resource = timg_resolved.get_resource(TextureResource)
# even if it means having compilation fail on purpose (#error)) except UnexpectedResourceTypeError:
resolution = None # TODO investigate. eg spot18 uses 0x0800_0000 as both a DL and Tex ?
if resolution == SegmentedAddressResolution.FILE: return False
resolved_file, resolved_offset = resolution_info
result, resolved_resource = resolved_file.get_resource_at(
resolved_offset
)
assert result == GetResourceAtResult.DEFINITIVE
assert resolved_resource is not None
# TODO investigate. eg spot18 uses 0x0800_0000 as both a DL and Tex ? assert isinstance(resolved_resource, TextureResource), (
if isinstance(resolved_resource, DListResource): hex(timg_segmented),
return False resolved_resource,
resolved_resource.__class__,
assert isinstance(resolved_resource, TextureResource), ( )
hex(timg_segmented), width_arg_value = pygfxd.gfxd_arg_value(width_arg_i)[1]
resolved_resource, height_arg_value = pygfxd.gfxd_arg_value(height_arg_i)[1]
resolved_resource.__class__, if (resolved_resource.width, resolved_resource.height) == (
) width_arg_value,
width_arg_value = pygfxd.gfxd_arg_value(width_arg_i)[1] height_arg_value,
height_arg_value = pygfxd.gfxd_arg_value(height_arg_i)[1] ):
if (resolved_resource.width, resolved_resource.height) == ( if arg_num == width_arg_i:
width_arg_value, if resolved_resource.width_name:
height_arg_value, pygfxd.gfxd_puts(resolved_resource.width_name)
): return True
if arg_num == width_arg_i: else:
if resolved_resource.width_name: assert arg_num == height_arg_i
pygfxd.gfxd_puts(resolved_resource.width_name) if resolved_resource.height_name:
return True pygfxd.gfxd_puts(resolved_resource.height_name)
else: return True
assert arg_num == height_arg_i else:
if resolved_resource.height_name: HACK_no_warn_bad_dims_DLs = {
pygfxd.gfxd_puts(resolved_resource.height_name) "sPresentedByNintendoDL", # uses gsDPLoadTextureTile, in which height is unused, so disassembled as 0 by gfxdis
return True "gMantUnusedMaterialDL", # DList bug
else: "gSunDL", # DList loads bigger chunks than the individual texture pieces (overlaps)
if arg_num == width_arg_i: }
print( HACK_no_warn_bad_dims_Texs = {
"Unexpected texture dimensions used: in dlist =", "gPoeComposerFlatHeadDL_000060E0_Tex", # used as both rgba16 16x16 and rgba16 8x8
self, "gDekuStickTex", # used as both i8 8x8 and i8 16x16
"texture =", "gHilite1Tex", # used as both rgba16 16x16 and rgba16 32x32
resolved_resource, "gHilite2Tex", # used as both rgba16 16x16 and rgba16 32x32
"texture resource has WxH =", "gUnknownCircle4Tex", # used as both i8 16x16 and rgba16 32x32
(resolved_resource.width, resolved_resource.height), "gLinkChildLowerBootTex", # used as both ci8 32x32 and ci8 16x16
"but dlist uses WxH =", "gDecorativeFlameMaskTex", # used as both i4 32x128 and i4 32x64
(width_arg_value, height_arg_value), }
) if (
pygfxd.gfxd_puts( arg_num == width_arg_i
" /* ! Unexpected texture dimensions !" and self.name not in HACK_no_warn_bad_dims_DLs
+ " DL={0[0]}x{0[1]} vs Tex={1[0]}x{1[1]} */ ".format( and resolved_resource.name not in HACK_no_warn_bad_dims_Texs
(width_arg_value, height_arg_value), ):
( print(
resolved_resource.width, "Unexpected texture dimensions used: in dlist =",
resolved_resource.height, self,
), "texture =",
) resolved_resource,
) "texture resource has WxH =",
# end if arg_num == width_arg_i (resolved_resource.width, resolved_resource.height),
# end width, height check "but dlist uses WxH =",
# end resolved to file (width_arg_value, height_arg_value),
# end 2 dim args )
# end timg check pygfxd.gfxd_puts(
""" " /* ! Unexpected texture dimensions !"
f" DL={width_arg_value}x{height_arg_value}"
f" vs Tex={resolved_resource.width}x{resolved_resource.height} */ "
)
return False return False
arg_fn_handlers = { arg_fn_handlers = {

View file

@ -389,7 +389,6 @@ def main():
z64_resource_handlers.register_resource_handlers() z64_resource_handlers.register_resource_handlers()
# TODO extract only when a pool xml was modified since last extract
try: try:
if args.single is not None: if args.single is not None:
any_match = False any_match = False