1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-24 16:01:26 +00:00

handle dependencies between xmls

This commit is contained in:
Dragorn421 2025-02-09 11:39:24 +01:00
parent 3dc74cde04
commit 6b857c6c71
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
108 changed files with 215 additions and 54 deletions

View file

@ -16,7 +16,16 @@ from . import Resource, File, GetResourceAtResult
# or defaulting to poor choices (e.g. raw addresses)
BEST_EFFORT = True
if BEST_EFFORT:
VERBOSE_BEST_EFFORT = False
VERBOSE_BEST_EFFORT = 1
VERBOSE_BEST_EFFORT_LVL1_IGNORED_SEGS = {
1, # billboard matrix segment
8, # often used for eye/mouth textures, or various dlist callbacks. same for 9-0xC
9,
0xA,
0xB,
0xC,
0xD, # matrix buffer for skeletons dlists
}
# RangeMap
@ -291,7 +300,7 @@ class MemoryContext:
address_resolver = self.memory_map.direct.get(offset)
except IndexError as e:
raise UnmappedAddressError(
"direct address is not mapped", hex(address)
"direct address is not mapped", f"0x{address:08X}"
) from e
return address_resolver.resolve(address, offset)
@ -306,7 +315,7 @@ class MemoryContext:
address_resolver = self.memory_map.segments[segment_num].get(offset)
except IndexError as e:
raise UnmappedAddressError(
"segment address is not mapped", hex(address)
"segment address is not mapped", f"0x{address:08X}"
) from e
return address_resolver.resolve(address, offset)
@ -325,7 +334,10 @@ class MemoryContext:
fake_resource = new_resource_pointed_to(fake_file, 0)
fake_resource.reporters.add(reporter)
fake_file.add_resource(fake_resource)
if VERBOSE_BEST_EFFORT:
if VERBOSE_BEST_EFFORT >= 2 or (
VERBOSE_BEST_EFFORT >= 1
and (address >> 24) not in VERBOSE_BEST_EFFORT_LVL1_IGNORED_SEGS
):
print("BEST_EFFORT: ignored error e=")
rich_pprint(e)
print(" on resource report by reporter=")
@ -371,12 +383,18 @@ class MemoryContext:
resolve_result = self.resolve_segmented(address_start)
except UnmappedAddressError as e:
if BEST_EFFORT:
if VERBOSE_BEST_EFFORT:
if VERBOSE_BEST_EFFORT >= 2 or (
VERBOSE_BEST_EFFORT >= 1
and (address_start >> 24)
not in VERBOSE_BEST_EFFORT_LVL1_IGNORED_SEGS
):
print("BEST_EFFORT: ignored error e=")
rich_pprint(e)
print(" and skipping marking resource buffer for reporter=")
rich_pprint(reporter)
print(f" {resource_type=} {address_start=:#08X} {address_end=:#08X}")
print(
f" {resource_type=} {address_start=:#08X} {address_end=:#08X}"
)
return
raise
file_start = resolve_result.file_offset
@ -395,7 +413,10 @@ class MemoryContext:
return self.get_attribute_at_segmented(address, Attributes.c_reference)
except UnmappedAddressError as e:
if BEST_EFFORT:
if VERBOSE_BEST_EFFORT:
if VERBOSE_BEST_EFFORT >= 2 or (
VERBOSE_BEST_EFFORT >= 1
and (address >> 24) not in VERBOSE_BEST_EFFORT_LVL1_IGNORED_SEGS
):
print("BEST_EFFORT: ignored error e="),
rich_pprint(e)
print(f" and returning raw address=0x{address:08X}")

View file

@ -392,7 +392,9 @@ class TextureResource(Resource):
if is_all_resources_fake():
assert self.fmt == G_IM_FMT.RGBA
if VERBOSE_BEST_EFFORT_TLUT_NO_REAL_USER:
if VERBOSE_BEST_EFFORT_TLUT_NO_REAL_USER and not getattr(
self, "HACK_ignore_orphaned_tlut", False
):
print(
"BEST_EFFORT",
"no real (non-fake for best effort) ci resource uses this tlut",
@ -1044,7 +1046,7 @@ class ColorIndexedTexturesManager:
assert ci_state.tluts.keys() == {0}, ci_state.tluts
resource = memory_context.report_resource_at_segmented(
self,
reporter,
tex.timg,
TextureResource,
lambda file, offset: TextureResource(
@ -1063,7 +1065,7 @@ class ColorIndexedTexturesManager:
assert tlut.count == ci_state.tluts_count
resource_tlut = memory_context.report_resource_at_segmented(
self,
reporter,
tlut.tlut,
# TLUTs declared in xmls use <Texture> so are TextureResource,
# so we can only expects a TextureResource

View file

@ -23,6 +23,7 @@ from . import z64_resource_handlers
VERBOSE1 = False
VERBOSE2 = False
VERBOSE3 = False
# "options"
RM_SOURCE = True
@ -94,10 +95,15 @@ def create_file_resources(rescoll: ResourcesDescCollection, file: File):
def process_pool(
extraction_ctx: ExtractionContext, pool_desc: ResourcesDescCollectionsPool
):
if VERBOSE2:
if VERBOSE1:
print("> process_pool")
if len(pool_desc.collections) == 1:
print(", ".join(map(str, (_c.out_path for _c in pool_desc.collections))))
colls_str = " + ".join(set(map(str, (_c.out_path for _c in pool_desc.collections))))
try:
import rich
rich.print(f"[b]{colls_str}[/b]")
except:
print(colls_str)
file_by_rescoll: dict[ResourcesDescCollection, File] = dict()
@ -134,34 +140,45 @@ def process_pool(
# 2) Build a MemoryContext for each File
memctx_base = extraction_ctx.version_memctx_base.copy()
files_by_segment: dict[int, list[File]] = dict()
for rescoll, file in file_by_rescoll.items():
if rescoll.start_address is None:
pass
elif isinstance(rescoll.start_address, SegmentStartAddress):
files_by_segment.setdefault(rescoll.start_address.segment, []).append(file)
elif isinstance(rescoll.start_address, VRAMStartAddress):
memctx_base.set_direct_file(rescoll.start_address.vram, file)
else:
raise NotImplementedError(rescoll.start_address)
disputed_segments = []
for segment, files in files_by_segment.items():
if len(files) == 1:
memctx_base.set_segment_file(segment, files[0])
else:
disputed_segments.append(segment)
if VERBOSE2:
print(f"{disputed_segments=}")
memctx_by_file: dict[File, MemoryContext] = dict()
for rescoll, file in file_by_rescoll.items():
if VERBOSE2:
print("Building MemoryContext for", file.name)
files_by_segment: dict[int, list[File]] = dict()
file_memctx = memctx_base.copy()
for rescoll_dep in (rescoll, *rescoll.depends):
file_dep = file_by_rescoll[rescoll_dep]
if rescoll_dep.start_address is None:
pass
elif isinstance(rescoll_dep.start_address, SegmentStartAddress):
files_by_segment.setdefault(
rescoll_dep.start_address.segment, []
).append(file_dep)
elif isinstance(rescoll_dep.start_address, VRAMStartAddress):
file_memctx.set_direct_file(rescoll_dep.start_address.vram, file_dep)
if file_dep != file :
file.referenced_files.add(file_dep)
else:
raise NotImplementedError(rescoll_dep.start_address)
disputed_segments = []
for segment, files in files_by_segment.items():
if len(files) == 1:
file_memctx.set_segment_file(segment, files[0])
if files[0] != file:
file.referenced_files.add(files[0])
if VERBOSE2:
print("segment", segment, "set to", files[0].name)
else:
disputed_segments.append(segment)
if VERBOSE2:
print(f"{disputed_segments=}")
if (
isinstance(rescoll.start_address, SegmentStartAddress)
and rescoll.start_address.segment in disputed_segments
@ -183,7 +200,7 @@ def process_pool(
while True:
any_progress = False
for file, file_memctx in memctx_by_file.items():
if VERBOSE2:
if VERBOSE3:
print(file.name, ".try_parse_resources_data()")
if file.try_parse_resources_data(file_memctx):
any_progress = True
@ -193,14 +210,14 @@ def process_pool(
for file in memctx_by_file.keys():
file.check_non_parsed_resources()
if VERBOSE2:
if VERBOSE3:
print("parse_all_files() ...")
parse_all_files()
for file in memctx_by_file.keys():
file.commit_resource_buffers()
if VERBOSE2:
if VERBOSE3:
print("parse new resources (resource buffers) ...")
parse_all_files() # parse new resources (resource buffers)
@ -210,7 +227,7 @@ def process_pool(
# 4) add dummy (binary) resources for the unaccounted gaps
if VERBOSE2:
if VERBOSE3:
print("unaccounted...")
for file in memctx_by_file.keys():
@ -244,8 +261,6 @@ def process_pool(
# "source" refers to the main .c and .h `#include`ing all the extracted resources
if WRITE_SOURCE:
# TODO fill referenced_files properly or something
file.referenced_files = set(memctx_by_file.keys()) - {file}
file.write_source()

View file

@ -247,7 +247,7 @@ def register_resource_handlers():
def texture_resource_handler(
file: File, resource_desc: n64resources.TextureResourceDesc
):
return dlist_resources.TextureResource(
res = dlist_resources.TextureResource(
file,
resource_desc.offset,
resource_desc.symbol_name,
@ -256,6 +256,9 @@ def register_resource_handlers():
resource_desc.width,
resource_desc.height,
)
if "hackmode_ignore_orphaned_tlut" in resource_desc.hack_modes:
res.HACK_ignore_orphaned_tlut = True
return res
def ci_texture_resource_handler(
file: File, resource_desc: n64resources.CITextureResourceDesc