tools(re): report club-item slot indices in the residency probe
The squad parser writes actives element i to club-item slot r15d+i, and r15d is shared scratch that other atom handlers clobber. Which slots are filled therefore reveals the index the parse actually started from, which is the open question behind the regression in vault section 18. probe_resident_fields.py now prints the slot index of every populated entry plus the empty ones, and verify_kits.sh runs it next to the map census so one command reports both residency and whether the squad survived.
This commit is contained in:
@@ -77,7 +77,7 @@ for label, vbeg, vend in (("players (cardtype 1)", mgr + 0xd8, mgr + 0xe0),
|
||||
if span % stride:
|
||||
continue
|
||||
n = span // stride
|
||||
recs, nulls = [], 0
|
||||
recs, nulls = [], []
|
||||
ok = True
|
||||
for k in range(n):
|
||||
try:
|
||||
@@ -85,23 +85,29 @@ for label, vbeg, vend in (("players (cardtype 1)", mgr + 0xd8, mgr + 0xe0),
|
||||
except OSError:
|
||||
ok = False; break
|
||||
if not rec:
|
||||
nulls += 1; continue
|
||||
nulls.append(k); continue
|
||||
d = decode(rec)
|
||||
if d is None:
|
||||
ok = False; break
|
||||
recs.append((rec, d))
|
||||
recs.append((k, rec, d))
|
||||
if not ok:
|
||||
continue
|
||||
print(f" stride {stride} (ptr at +{ptr_off:#x}): {n} slots, {len(recs)} populated, {nulls} null")
|
||||
if not recs and nulls != n:
|
||||
print(f" stride {stride} (ptr at +{ptr_off:#x}): {n} slots, {len(recs)} populated, {len(nulls)} null")
|
||||
if not recs and len(nulls) != n:
|
||||
continue
|
||||
hist = collections.Counter(d[0:2] for _, d in recs)
|
||||
hist = collections.Counter(d[0:2] for _, _, d in recs)
|
||||
for key, c in sorted(hist.items(), key=lambda x: -x[1]):
|
||||
print(f" (cardtype,subtype)={key} x{c}")
|
||||
print(f" {'ptr':>14} " + " ".join(f"{f:>8}" for f in FIELDS))
|
||||
for rec, d in recs[:8]:
|
||||
print(f" {rec:#14x} " + " ".join(f"{v:>8}" for v in d))
|
||||
cats = collections.Counter(d[3] for _, d in recs)
|
||||
# The SLOT INDEX is load-bearing evidence: the squad parser's `actives`
|
||||
# arm writes element i to slot `r15d + i`, and r15d is shared scratch
|
||||
# that other atom handlers clobber. Which slots are filled therefore
|
||||
# reveals the index the parse actually started from.
|
||||
print(f" {'slot':>4} {'ptr':>14} " + " ".join(f"{f:>8}" for f in FIELDS))
|
||||
for k, rec, d in recs[:8]:
|
||||
print(f" {k:>4} {rec:#14x} " + " ".join(f"{v:>8}" for v in d))
|
||||
if nulls:
|
||||
print(f" empty slots: {nulls[:16]}")
|
||||
cats = collections.Counter(d[3] for _, _, d in recs)
|
||||
if cats:
|
||||
print(f" CATEGORY (+0x60) distribution: {dict(cats)}")
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user