re: an embedded .prt part is a top-level RATC bundle, addressed by its element prefix
Read first: ui-rat-layout.md OWNS the RATC stack and already documents the 60-byte element declaration table and 'one bundle = one (context x language) build of that screen'. What it does not say is how a part is addressed when it is NOT a pak entry. The elements of one bundle share a common name prefix, and that prefix is the part name. GP_MAIN_GAME_E2D.pak has 130 bundles with 114 distinct element prefixes -- pgmenu_btn00, pghud_wing, pgface, pghud_range, pgmanuva_eff0 -- exactly the in-game part names. The 100 in-game-only .prt names match a 2D bundle prefix 68 times; the control, the 241 shipped parts, matches ZERO. The two families are disjoint on the test. 13 shipped parts match a bundle prefix in their own screen pak, which is the expected shape. Four of the five mission banners land here: pgmsg_start.prt is E2D bundle 0x89fac252, a one-element bundle declaring pgmsg_start_sub.rat; likewise _end_, _failed_, _restart_. pgmsg_update has no bundle at all, consistent with having no _sub.rat. 32 in-game names still have no 2D bundle. They cluster into families whose base name is a bundle, reading as a variant declared inside a parent bundle -- a reading, not adopted. Artefact +38 lines / 0 deletions; the other six regenerate byte-identical.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
Regenerates docs/re/data/prt-parts.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
import sys, os, glob, re, struct, collections
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -15,10 +15,21 @@ FIVE = ['pgmsg_start.prt', 'pgmsg_end.prt', 'pgmsg_update.prt',
|
||||
PRE = ['', 'Stage\\', 'stage\\', 'message\\', 'language\\', '2d\\', 'ui\\', 'prt\\',
|
||||
'view\\'] + [l + '\\' for l in ('eng', 'jpn', 'fra', 'deu', 'ita', 'esp')]
|
||||
|
||||
def _elements(b):
|
||||
n = struct.unpack_from('>I', b, 0x14)[0]
|
||||
if not (0 < n < 4000) or 0x20 + n * 60 > len(b):
|
||||
return []
|
||||
return [b[0x20 + i * 60:0x20 + i * 60 + 28].split(b'\x00')[0].decode('latin-1', 'replace')
|
||||
for i in range(n)]
|
||||
|
||||
def _stem(e):
|
||||
return re.sub(r'\.(t32|rat|prm)$', '', e)
|
||||
|
||||
def main():
|
||||
H = collections.defaultdict(set)
|
||||
names = set()
|
||||
ref = collections.defaultdict(set)
|
||||
pref2d, prefall = set(), set()
|
||||
rat = collections.defaultdict(set)
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
base = os.path.basename(pk)
|
||||
@@ -29,6 +40,13 @@ def main():
|
||||
if b[:4] == b'RATC':
|
||||
for m in re.finditer(rb'[A-Za-z0-9_]{3,40}_sub\.rat', b):
|
||||
rat[m.group(0).decode()].add(base)
|
||||
e = _elements(b)
|
||||
if e:
|
||||
pfx = os.path.commonprefix([_stem(x) for x in e]).rstrip('_')
|
||||
if pfx:
|
||||
prefall.add(pfx)
|
||||
if '2D.pak' in base:
|
||||
pref2d.add(pfx)
|
||||
|
||||
print("# Where `.prt` screen parts live")
|
||||
print("# Regenerate: python3 tools/re-capture/prt_parts.py")
|
||||
@@ -68,6 +86,20 @@ def main():
|
||||
print(" pg* parts: %d, of which %d resolve: %s"
|
||||
% (len(pg), sum(1 for n in pg if res[n]), sorted(n for n in pg if res[n])))
|
||||
|
||||
ing = [n for n in names if not res[n] and 'tables.pak' not in ref[n]]
|
||||
sh = [n for n in names if res[n]]
|
||||
match = lambda ns, S: sum(1 for n in ns if n[:-4] in S or n[:-4] + '_sub' in S)
|
||||
print("\n## AN EMBEDDED PART IS A TOP-LEVEL RATC BUNDLE, named by its element prefix")
|
||||
print(" RATC bundle element-prefixes: %d distinct (2D paks: %d)" % (len(prefall), len(pref2d)))
|
||||
print(" in-game-only .prt (%d): match a 2D bundle prefix %d ; any bundle prefix %d"
|
||||
% (len(ing), match(ing, pref2d), match(ing, prefall)))
|
||||
print(" CONTROL shipped .prt (%d): match a 2D bundle prefix %d ; any bundle prefix %d"
|
||||
% (len(sh), match(sh, pref2d), match(sh, prefall)))
|
||||
resid = sorted(n for n in ing if n[:-4] not in pref2d and n[:-4] + '_sub' not in pref2d)
|
||||
print(" in-game .prt with NO 2D bundle (%d):" % len(resid))
|
||||
for n in resid:
|
||||
print(" %s" % n)
|
||||
|
||||
print("\n## `<stem>_sub.rat` sub-bundles inside RATC")
|
||||
print(" distinct _sub.rat names: %d" % len(rat))
|
||||
for k in sorted(rat):
|
||||
|
||||
Reference in New Issue
Block a user