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:
parent
3dc74cde04
commit
6b857c6c71
108 changed files with 215 additions and 54 deletions
|
@ -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}")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue