tools(LayoutDump): --props and --media, for questions the decomp cannot answer
Two dump modes, both added because a chat bug turned on authored data rather
than code.
--props prints each state's property ids WITH VALUES. It is what settled the
unseen-text indicator regression: element 0x1000048C authors dat property 0x3B
("Invisible") per state —
state 13 Ghosted 0x3B = True -> hidden
state 1 Normal 0x3B = False -> shown
— which is what actually puts that element on screen. No amount of reading the
decomp would have produced those two booleans.
--media prints the RAW media sequence per state off the LayoutDesc, because
ElementInfo keeps only the FIRST image of a state (LayoutImporter.cs, the
`!imageRead` guard) and an animation is therefore invisible above that level.
It reports what it CANNOT do rather than implying an element has no media: raw
descriptors only carry what an element overrides, and states usually come from
a base element — for the indicator, base 0x10000527, which lives in a different
layout entirely. Following that chain means reimplementing LayoutImporter's
Resolve, so the mode says so instead of printing a misleading empty list.
What the two modes established between them, for whoever picks up the blink:
the media vocabulary includes MediaDescImage, MediaDescPause and MediaDescJump,
so an authored animation is a SEQUENCE with waits and a loop — a small program,
not a frame array. Supporting it means keeping the sequence through import and
running a media player, not just widening StateMedia to a list.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
a330d50df9
commit
f44f7641b1
1 changed files with 49 additions and 0 deletions
|
|
@ -46,6 +46,55 @@ if (root is null)
|
|||
Console.WriteLine($"layout 0x{ids[0]:X8}");
|
||||
Print(root, 0);
|
||||
|
||||
int mediaAt = Array.IndexOf(args, "--media");
|
||||
if (mediaAt >= 0)
|
||||
{
|
||||
// The RAW media sequence per state, straight off the LayoutDesc. ElementInfo
|
||||
// keeps only the first image, so an animation is invisible above that level.
|
||||
uint wanted = mediaAt + 1 < args.Length
|
||||
? Convert.ToUInt32(args[mediaAt + 1], 16)
|
||||
: 0u;
|
||||
// Layouts are not necessarily in Portal — go through the adapter, the same
|
||||
// way LayoutImporter does.
|
||||
var ld = adapter.Get<DatReaderWriter.DBObjs.LayoutDesc>(ids[0]);
|
||||
if (ld is null)
|
||||
{
|
||||
Console.WriteLine($"layout 0x{ids[0]:X8} not found");
|
||||
return 2;
|
||||
}
|
||||
|
||||
foreach (var top in ld.Elements)
|
||||
Walk(top.Value);
|
||||
return 0;
|
||||
|
||||
void Walk(DatReaderWriter.Types.ElementDesc d)
|
||||
{
|
||||
if (wanted == 0 || d.ElementId == wanted)
|
||||
{
|
||||
Console.WriteLine($"element 0x{d.ElementId:X8}");
|
||||
if (d.States.Count == 0)
|
||||
{
|
||||
// Raw descriptors only carry what THIS element overrides; states
|
||||
// and their media usually come from the base element, and
|
||||
// LayoutDesc::InqFullDesc @0x0069A520 resolves that chain.
|
||||
// Following it here would mean reimplementing LayoutImporter's
|
||||
// Resolve, so say so rather than imply the element has none.
|
||||
Console.WriteLine(
|
||||
$" (no states of its own — inherited from base 0x{d.BaseElement:X8};"
|
||||
+ " raw media not resolved here)");
|
||||
}
|
||||
foreach (var st in d.States)
|
||||
{
|
||||
Console.WriteLine($" state {st.Key}: {st.Value.Media.Count} media");
|
||||
foreach (var m in st.Value.Media)
|
||||
Console.WriteLine($" {m.GetType().Name}");
|
||||
}
|
||||
}
|
||||
foreach (var child in d.Children)
|
||||
Walk(child.Value);
|
||||
}
|
||||
}
|
||||
|
||||
int resizeAt = Array.IndexOf(args, "--resize");
|
||||
if (resizeAt >= 0 && resizeAt + 2 < args.Length)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue