docs(issues): #37 — Investigation 2 narrows bug to SubPalette coverage gaps
Five parallel agents + dat probes ruled out: - byte-level decode primitive (matches ACViewer) - polygon emission (no ST_DOUBLE / Surface.Type & 6 issues) - per-PART texture-override scoping (correctly per-MeshRef'd) - SubPalette indexing convention (full-size 2048 palettes, *8 wire un-pack is single-applied) Smoking gun: for +Acdream the server sends 10 SubPaletteSwap ranges that overlay palette indices [0..320), [576..1024), [1392..1488), [1728..1920). The complement — [320..576), [1024..1392), [1488..1728), [1920..2048) — is NOT overlaid. Base palette 0x0400007E at those indices has red/skin tones. Coat texture UVs sampling those non-overlaid indices render as visible "skin stub at top of coat". Either ACE sends incomplete SubPaletteSwap data, or retail does extra client-side ClothingTable computation we (and ACE) don't. Diagnostic harness now lives at tools/InspectCoatTex/Program.cs; GameWindow's DUMP_CLOTHING also probes runtime SubPalette dat sizes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a3f53c2644
commit
5937ebe1c5
3 changed files with 368 additions and 16 deletions
|
|
@ -2008,7 +2008,33 @@ public sealed class GameWindow : IDisposable
|
|||
if (spawn.SubPalettes is { } subPaletteList)
|
||||
{
|
||||
foreach (var subPal in subPaletteList)
|
||||
Console.WriteLine($" SP id=0x{subPal.SubPaletteId:X8} offset={subPal.Offset} length={subPal.Length}");
|
||||
{
|
||||
int rawOffset = subPal.Offset * 8;
|
||||
int rawLen = subPal.Length == 0 ? 2048 : subPal.Length * 8;
|
||||
var pal = _dats.Get<DatReaderWriter.DBObjs.Palette>(subPal.SubPaletteId);
|
||||
string palInfo = pal is null ? "Palette dat NOT FOUND (might be PaletteSet 0x0F?)" : $"Colors.Count={pal.Colors.Count}";
|
||||
Console.WriteLine($" SP id=0x{subPal.SubPaletteId:X8} wireOffset={subPal.Offset} wireLength={subPal.Length} -> rawIdx[{rawOffset}..{rawOffset + rawLen}) {palInfo}");
|
||||
// If pal is non-null and small, show first 4 colors
|
||||
if (pal is not null && pal.Colors.Count > 0)
|
||||
{
|
||||
int sample = Math.Min(4, pal.Colors.Count);
|
||||
for (int s = 0; s < sample; s++)
|
||||
{
|
||||
var c = pal.Colors[s];
|
||||
Console.WriteLine($" pal[{s:D3}] R={c.Red:X2} G={c.Green:X2} B={c.Blue:X2}");
|
||||
}
|
||||
// Also probe at the rawOffset (if in range) — that's where overlay copies FROM in our code
|
||||
if (rawOffset < pal.Colors.Count)
|
||||
{
|
||||
var c = pal.Colors[rawOffset];
|
||||
Console.WriteLine($" pal[{rawOffset:D4}] R={c.Red:X2} G={c.Green:X2} B={c.Blue:X2} <-- our code reads here");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($" pal[{rawOffset:D4}] OUT OF RANGE (Colors.Count={pal.Colors.Count}) -- our code's read SKIPS the overlay !!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var change in animPartChanges)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue