chore: retire the last dead paths and names from the consolidation
Nothing here changes what a tool computes; it changes where tools look. - tools/re-capture: 33 censuses globbed /work/sylph_extract, a path that has existed nowhere since /work became a clone, so they matched nothing and printed empty results. They now resolve the disc through a new disc.py from $SYLPHEED_DISC and exit loudly without it (the #44 fix, generalised). Nine scripts that imported siblings from the retired Reborn checkout or an old session scratchpad now import from their own directory. unitgroup.py only needs the variable when --pak is not given. - sylpheed-xex: the loader only ever uses the XEX2 retail key. The dead devkit key and a doc comment claiming a devkit fallback that does not exist are gone; Project Sylpheed is a retail XEX2, so no XEX1 key either. - sylpheed-viewer: real_font_rasterizes looked for /tmp/sylph_extract and so always skipped. It reads $SYLPHEED_DISC now, and passes against the disc. - Comments and docs that named xenia-rs, the Reborn repository or /work/*.pe as places to look now name sylpheed.db, Canary's ppc_context.h and the flat .pe; docs/re/README.md no longer says the native Canary build does not run. Historical records keep their original paths: findings that were measured against /work/xenia-rs/sylpheed.db still say so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ def nh(name):
|
||||
a=(a-(q*MOD))&0xFFFFFFFF
|
||||
return (((bb<<24)&0xFF000000)|(a&0xFFFFFF))&0xFFFFFFFF
|
||||
|
||||
EX="/home/fabi/RE Project Sylpheed/sylph_extract"
|
||||
EX = os.environ.get("SYLPHEED_DISC") or exit("set SYLPHEED_DISC to the extracted disc (the directory holding dat/)")
|
||||
def load_pak(base):
|
||||
"""base like dat/movie/eng ; returns list of (hash,off,size), data bytes"""
|
||||
pak=open(f"{EX}/{base}.pak","rb").read()
|
||||
|
||||
@@ -7,6 +7,7 @@ whether the 34-name roster is shared, and whether `Type` really predicts the
|
||||
field count. Regenerates docs/re/data/aiparams-census.txt.
|
||||
"""
|
||||
import sys, os, glob, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -32,7 +33,7 @@ def objects(pak):
|
||||
return out
|
||||
|
||||
def main():
|
||||
paks = sorted(p for p in glob.glob('/work/sylph_extract/**/*.pak', recursive=True)
|
||||
paks = sorted(p for p in glob.glob(disc_root() + '/**/*.pak', recursive=True)
|
||||
if os.path.basename(p).startswith('GP_MAIN_GAME_')
|
||||
and '2D' not in os.path.basename(p))
|
||||
print("# AIParams across the whole disc")
|
||||
|
||||
@@ -6,6 +6,7 @@ the known path prefixes, and reports per archive how many of its entries are
|
||||
explained. Regenerates docs/re/data/archive-naming.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -17,7 +18,7 @@ PRE = ['', '2d\\', 'ui\\', 'hud\\', 'Stage\\', 'stage\\', 'message\\', 'language
|
||||
'prt\\', 'view\\'] + [l + '\\' for l in ('eng', 'jpn', 'fra', 'deu', 'ita', 'esp')]
|
||||
|
||||
def main():
|
||||
paks = sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True))
|
||||
paks = sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True))
|
||||
names = set()
|
||||
decl = set()
|
||||
nenum = collections.Counter()
|
||||
|
||||
@@ -7,6 +7,7 @@ what points into the 131-record `Weapon` datasheet. Regenerates
|
||||
docs/re/data/arsenal-chain.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -17,8 +18,8 @@ ITEMF = {'Dependency', 'MissionObjective', 'Model', 'Package',
|
||||
'PlayerWeapon', 'Points', 'Power', 'Range'}
|
||||
|
||||
def main():
|
||||
ars = glob.glob('/work/sylph_extract/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
mg = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
ars = glob.glob(disc_root() + '/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
mg = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
|
||||
slots = collections.defaultdict(dict); wids = set()
|
||||
for h, b in pak_entries(mg):
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
"""Every BGM bank's sub-wave structure: count, bytes, PsuedoBytesPerSec, seconds.
|
||||
|
||||
Static, disc-only. See docs/re/structures/bgm-two-stems.md."""
|
||||
import sys, struct
|
||||
sys.path.insert(0,"/work/Syplheed-Reborn/tools/re-capture")
|
||||
exec(open("/work/Syplheed-Reborn/tools/re-capture/slb_segment_phase.py").read().split("def cmd_phases")[0])
|
||||
pak=Pak("/work/sylph_extract/dat/sound.pak")
|
||||
import os, sys, struct
|
||||
from disc import disc_root
|
||||
_SD = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, _SD)
|
||||
exec(open(os.path.join(_SD, "slb_segment_phase.py")).read().split("def cmd_phases")[0])
|
||||
pak=Pak(disc_root() + "/dat/sound.pak")
|
||||
def bps(b, riff_at):
|
||||
# PsuedoBytesPerSec at RIFF+0x20 (u32 LE), SampleRate at +0x24
|
||||
return struct.unpack_from("<I", b, riff_at+0x20)[0], struct.unpack_from("<I", b, riff_at+0x24)[0]
|
||||
|
||||
@@ -12,6 +12,7 @@ instead of a type name ('Yes' for a boolean, 'Vessel' for Generic.Type).
|
||||
Regenerates docs/re/data/datasheet-schema.txt.
|
||||
"""
|
||||
import glob, os, sys
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from unit_substructures import pak_entries
|
||||
import unitgroup as U
|
||||
@@ -27,7 +28,7 @@ TYPES = {
|
||||
}
|
||||
|
||||
def main():
|
||||
pak = sorted(glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_D.pak', recursive=True))
|
||||
pak = sorted(glob.glob(disc_root() + '/**/GP_MAIN_GAME_D.pak', recursive=True))
|
||||
if not pak:
|
||||
print('disc not mounted; nothing to do'); return
|
||||
out = {}
|
||||
|
||||
21
tools/re-capture/disc.py
Normal file
21
tools/re-capture/disc.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""Where the extracted disc is: `$SYLPHEED_DISC`, or a loud error.
|
||||
|
||||
The censuses in this directory used to glob `/work/sylph_extract`, a path that
|
||||
stopped existing when `/work` became a clone of this repository. A glob over a
|
||||
missing directory matches nothing, so those scripts printed empty results instead
|
||||
of failing (see `name_block_bases.py`). Resolve the disc here so that cannot
|
||||
happen quietly again.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def disc_root():
|
||||
"""The extracted disc's root — the directory holding `dat/` and `hidden/`."""
|
||||
root = os.environ.get("SYLPHEED_DISC")
|
||||
if not root or not os.path.isdir(os.path.join(root, "dat")):
|
||||
sys.exit(
|
||||
f"SYLPHEED_DISC={root!r} is not an extracted disc (no dat/ inside). "
|
||||
"Set it to the directory that holds dat/ and hidden/."
|
||||
)
|
||||
return root
|
||||
@@ -2,13 +2,16 @@
|
||||
"""Dump the guest's DECOMPRESSED executable image out of live Xenia memory.
|
||||
|
||||
Why this exists: the static PPC route the corpus is built on ran against a
|
||||
disassembly database at `/work/xenia-rs/sylpheed.db`, and that file is **not in
|
||||
this container** — the same migration that took the Xenia storage root. Without
|
||||
it, every finding that cites a `sub_82xxxxxx` is unre-checkable.
|
||||
disassembly database at `/work/xenia-rs/sylpheed.db`, and that file was **not in
|
||||
the container** — the same migration that took the Xenia storage root. Without
|
||||
it, every finding that cites a `sub_82xxxxxx` was unre-checkable. (The database
|
||||
now lives in this repository's root as `sylpheed.db`, rebuilt from the ISO by
|
||||
`sylph-xexdb`, which decrypts and decompresses the XEX itself; query it with
|
||||
`tools/zq.py`. This dump remains the way to get the image a *running* guest holds.)
|
||||
|
||||
`/disc/default.xex` cannot substitute: it is encrypted and LZX-compressed. Its
|
||||
header is intact (`XEX2`, original PE name `default.pe`) and everything after is
|
||||
noise — `strings` finds **zero** occurrences of `GamePart` in it.
|
||||
`/disc/default.xex` cannot substitute on its own: it is encrypted and
|
||||
LZX-compressed. Its header is intact (`XEX2`, original PE name `default.pe`) and
|
||||
everything after is noise — `strings` finds **zero** occurrences of `GamePart` in it.
|
||||
|
||||
Xenia decompresses, decrypts and relocates the image at load, so a running guest
|
||||
holds exactly the flat VA image the corpus calls the `.pe`. Dump it once and the
|
||||
|
||||
@@ -8,10 +8,11 @@ Bit comes from the T8aD header; the name from the string immediately preceding
|
||||
it (validated 17/18 on build 4 against the RATC child order).
|
||||
"""
|
||||
import struct, zlib, glob, re, os
|
||||
from disc import disc_root
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
NAME = re.compile(rb'[A-Za-z0-9_.]{2,31}\x00')
|
||||
base = "/work/sylph_extract/dat/GP_TITLE"
|
||||
base = disc_root() + "/dat/GP_TITLE"
|
||||
stub = open(base + ".pak", "rb").read()
|
||||
n = struct.unpack_from(">I", stub, 4)[0]
|
||||
blob = b"".join(open(s, "rb").read() for s in sorted(glob.glob(base + ".p[0-9][0-9]")))
|
||||
|
||||
@@ -7,6 +7,7 @@ preceding name is the ELEMENT's (opt) name and the child list is the SPRITE's.
|
||||
This test uses the element name and says so.
|
||||
"""
|
||||
import struct, zlib, glob, os, re, collections
|
||||
from disc import disc_root
|
||||
NAME = re.compile(rb'[A-Za-z0-9_.]{2,31}\x00')
|
||||
|
||||
def entries(base):
|
||||
@@ -25,7 +26,7 @@ def entries(base):
|
||||
|
||||
set_eff = set_noneff = clear_eff = clear_noneff = 0
|
||||
examples = []
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for d in entries(pak[:-4]):
|
||||
for m in re.finditer(b"T8aD", d):
|
||||
o = m.start()
|
||||
|
||||
@@ -12,11 +12,12 @@ prefix.
|
||||
Regenerates docs/re/data/effect-homes.txt.
|
||||
"""
|
||||
import glob, os, re, subprocess, sys, collections
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from unit_substructures import pak_entries
|
||||
import unitgroup as U
|
||||
|
||||
XPR = '/work/sylph_extract/hidden/resource3d'
|
||||
XPR = disc_root() + '/hidden/resource3d'
|
||||
FX = re.compile(r'(FxModel|EffectName|Effect_|ShellModel|CoverModel)')
|
||||
|
||||
def width(n):
|
||||
@@ -34,7 +35,7 @@ def main():
|
||||
home[name].add(os.path.basename(path))
|
||||
|
||||
bound = set()
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
for _h, b in pak_entries(pk):
|
||||
if b[:4] != b'IDXD':
|
||||
continue
|
||||
|
||||
@@ -35,7 +35,7 @@ import sys
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
CAP = "/work/docs/re/captures/title-builds"
|
||||
CAP = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "docs", "re", "captures", "title-builds"))
|
||||
REF_A = f"{CAP}/live-main-menu.png" # NEW GAME focused
|
||||
REF_B = f"{CAP}/live-main-menu-options-focused.png" # OPTIONS focused
|
||||
BUTTONS = ["NEW GAME", "LOAD GAME", "TUTORIAL", "OPTIONS", "EXTRAS"]
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import sys, glob, collections
|
||||
S="/tmp/claude-1000/-home-fabi-RE-Project-Sylpheed/b113cc12-4769-4ed8-ad66-c2b48f800773/scratchpad"
|
||||
sys.path.insert(0,S+"/wt-root/Syplheed-Reborn/tools/re-capture")
|
||||
exec(open(S+"/regn_decode.py").read().split("# ── the object")[0])
|
||||
import os, sys, glob, collections
|
||||
from disc import disc_root
|
||||
_SD = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, _SD)
|
||||
exec(open(os.path.join(_SD, "regn_decode.py")).read().split("# ── the object")[0])
|
||||
import unitgroup as U
|
||||
print("# `Generic` is the per-FILE header record, not a table")
|
||||
print("#")
|
||||
print("# One `Generic` per IDXD pak entry; its schema is set by the file's TYPE.")
|
||||
print("# Regenerate: see docs/re/structures/unit-datasheet-static.md")
|
||||
for pk in sorted(glob.glob("/work/sylph_extract/**/GP_MAIN_GAME_*.pak",recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + "/**/GP_MAIN_GAME_*.pak",recursive=True)):
|
||||
E=pak_entries(pk); items=E.items() if isinstance(E,dict) else E
|
||||
kinds=collections.Counter(); ids=set(); types=collections.Counter()
|
||||
nidxd=0; man=eff=0; ctl_ok=ctl_bad=0; one_per=True
|
||||
|
||||
@@ -6,6 +6,7 @@ per-slot ALLOW-LIST record whose positional (unnamed) fields are the ordered
|
||||
candidate item names. Regenerates docs/re/data/hangar-loadouts.txt.
|
||||
"""
|
||||
import sys, os, glob, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -17,10 +18,10 @@ ITEMF = {'Dependency', 'MissionObjective', 'Model', 'Package',
|
||||
SLOTS = ('Arm1', 'Arm2', 'Arm3', 'Nose')
|
||||
|
||||
def main():
|
||||
ars = glob.glob('/work/sylph_extract/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
ars = glob.glob(disc_root() + '/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
|
||||
unit_ids, char_ids = set(), set()
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
for h, b in pak_entries(pk):
|
||||
if b[:4] != b'IDXD': continue
|
||||
try: recs = U.parse(b)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Regenerates docs/re/data/hud-config.txt.
|
||||
"""
|
||||
import sys, os, glob, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -14,10 +15,10 @@ PRE = ['', '2d\\', 'ui\\', 'hud\\'] + [l + '\\' for l in ('eng', 'jpn', 'fra', '
|
||||
DEFAULT = ('HudResource.tbl', 'HudMarkerResource.tbl')
|
||||
|
||||
def main():
|
||||
p2 = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E2D.pak', recursive=True)[0]
|
||||
p2 = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E2D.pak', recursive=True)[0]
|
||||
E = dict(pak_entries(p2))
|
||||
H = set()
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
for h, b in pak_entries(pk):
|
||||
H.add(h)
|
||||
|
||||
@@ -75,7 +76,7 @@ def main():
|
||||
print(" %-30s %s" % (sq, " ".join("%s=%s" % (k, v) for k, v in sorted(n.items()))))
|
||||
|
||||
print("\n## ResourceTable -- 29 pairs, one per stage, with a single override")
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_*2D.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/GP_MAIN_GAME_*2D.pak', recursive=True)):
|
||||
for h, b in pak_entries(pk):
|
||||
if b[:4] != b'IDXD': continue
|
||||
for r in U.parse(b):
|
||||
|
||||
@@ -20,11 +20,12 @@ The headline measurement (see docs/re/structures/idxd-unnamed-keys.md):
|
||||
7 052 of them are < 0x10000 -- author-assigned ordinals / element ids
|
||||
42 of them are >= 0x01000000 -- genuine tag_hash values
|
||||
|
||||
`SYLPHEED_DISC` (default /work/sylph_extract) points at the extracted disc.
|
||||
`SYLPHEED_DISC` (required) points at the extracted disc.
|
||||
"""
|
||||
import argparse, collections, glob, os, re, struct, sys, zlib
|
||||
from disc import disc_root
|
||||
|
||||
DISC = os.environ.get('SYLPHEED_DISC', '/work/sylph_extract')
|
||||
DISC = disc_root()
|
||||
|
||||
# --------------------------------------------------------------------------- hashes
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ across the 28 stages resolve, so this is a total mapping rather than a sample. 3
|
||||
message names span more than one page; every page is printed.
|
||||
"""
|
||||
import collections
|
||||
from disc import disc_root
|
||||
import struct
|
||||
import sys
|
||||
|
||||
@@ -86,7 +87,7 @@ def walk(b, base, nxt, sink):
|
||||
def main():
|
||||
ssb = sys.argv[1]
|
||||
pak = sys.argv[2] if len(sys.argv) > 2 else \
|
||||
'/work/sylph_extract/dat/GP_MAIN_GAME_E.pak'
|
||||
disc_root() + '/dat/GP_MAIN_GAME_E.pak'
|
||||
sys.path.insert(0, sys.path[0])
|
||||
from unitgroup import read_entry # noqa: F401 (kept for parity)
|
||||
import zlib
|
||||
|
||||
@@ -17,6 +17,7 @@ The filter keys on SHAPE, not on a count: >=2 consecutive blocks whose fade is
|
||||
0x??ffffff, whose tint is 0xffffffff, and whose scale words are 1..4000.
|
||||
"""
|
||||
import struct, zlib, glob, os, sys, collections, re
|
||||
from disc import disc_root
|
||||
|
||||
def entries(base):
|
||||
stub=open(base+'.pak','rb').read()
|
||||
@@ -65,7 +66,7 @@ if not all(True for _ in [0]): sys.exit(1)
|
||||
|
||||
hist=collections.Counter(); nz=collections.Counter(); total=0
|
||||
examples=collections.defaultdict(list)
|
||||
for pak in sorted(glob.glob('/work/sylph_extract/dat/GP_*.pak')):
|
||||
for pak in sorted(glob.glob(disc_root() + '/dat/GP_*.pak')):
|
||||
base=pak[:-4]
|
||||
for h,d in entries(base):
|
||||
if b'RATC' not in d[:4] and d[:4]!=b'RATC': pass
|
||||
|
||||
@@ -8,6 +8,7 @@ the two objects that belong to no documented family.
|
||||
Regenerates docs/re/data/main-game-unnamed.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -64,7 +65,7 @@ def classify(shape):
|
||||
return None, None
|
||||
|
||||
def main():
|
||||
paks = sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True))
|
||||
paks = sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True))
|
||||
NAMES = name_map(paks)
|
||||
mains = sorted(p for p in paks
|
||||
if re.match(r'GP_MAIN_GAME_[A-Z]\.pak$', os.path.basename(p)))
|
||||
|
||||
@@ -8,11 +8,12 @@ language pack, each holding Score_Easy / Score_Normal / Score_Hard with one
|
||||
Run: python3 mission_scoring.py > ../../docs/re/data/mission-scoring.txt
|
||||
"""
|
||||
import sys, os, re, glob, collections
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from unit_substructures import pak_entries
|
||||
import unitgroup as U
|
||||
|
||||
DAT = '/work/sylph_extract/dat'
|
||||
DAT = disc_root() + '/dat'
|
||||
KEY = 'RankScore_S'
|
||||
DIFFS = ('Score_Easy', 'Score_Normal', 'Score_Hard')
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ Two traps this encodes, both paid for:
|
||||
once it tracks a transition it was not selected by.
|
||||
"""
|
||||
import os, struct, sys
|
||||
sys.path.insert(0, "/work/Syplheed-Reborn/tools/re-capture")
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import gmem
|
||||
|
||||
def scan(path, val):
|
||||
|
||||
@@ -22,11 +22,12 @@ number before it did:
|
||||
across six paks. They are collapsed into one family here.
|
||||
"""
|
||||
|
||||
import sys, glob, struct, re, collections
|
||||
import os, sys, glob, struct, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
S="/tmp/claude-1000/-home-fabi-RE-Project-Sylpheed/b113cc12-4769-4ed8-ad66-c2b48f800773/scratchpad"
|
||||
sys.path.insert(0,S+"/wt-root/Syplheed-Reborn/tools/re-capture")
|
||||
exec(open(S+"/regn_decode.py").read().split("# ── the object")[0])
|
||||
_SD = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, _SD)
|
||||
exec(open(os.path.join(_SD, "regn_decode.py")).read().split("# ── the object")[0])
|
||||
Hh=lambda b,o: struct.unpack_from(">H",b,o)[0]
|
||||
def fam(n): return re.sub(r'_[DEFIJS]2D\.pak$','_2D.pak',n)
|
||||
keys=collections.Counter(); kfam=collections.defaultdict(set)
|
||||
@@ -37,7 +38,7 @@ def take(b,o,base,lang):
|
||||
if Hh(b,o+8)==0: hi_zero+=1
|
||||
k=Hh(b,o+10); keys[k]+=1; kfam[k].add(base)
|
||||
if lang: langsets[lang].add(k)
|
||||
ROOT = sys.argv[1] if len(sys.argv) > 1 else "/work/sylph_extract"
|
||||
ROOT = sys.argv[1] if len(sys.argv) > 1 else disc_root()
|
||||
for f in sorted(glob.glob(ROOT + "/**/*.pak", recursive=True)):
|
||||
try: E=pak_entries(f)
|
||||
except Exception: continue
|
||||
|
||||
@@ -6,6 +6,7 @@ every texture). CONTROL: it must reproduce the three known fallback elements of
|
||||
GP_TITLE build 7 (indices 8, 13, 14) and find ptlogo_eff3 among them.
|
||||
"""
|
||||
import struct, zlib, glob, os, collections
|
||||
from disc import disc_root
|
||||
|
||||
DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40
|
||||
|
||||
@@ -56,7 +57,7 @@ def has_plateau(poses):
|
||||
|
||||
# ---- CONTROL -------------------------------------------------------------
|
||||
ctl = {i: (n, p) for i, n, p in elements(
|
||||
dict((i, d) for i, h, d in entries("/work/sylph_extract/dat/GP_TITLE"))[7])}
|
||||
dict((i, d) for i, h, d in entries(disc_root() + "/dat/GP_TITLE"))[7])}
|
||||
fb = sorted(i for i, (n, p) in ctl.items() if not has_plateau(p))
|
||||
print(f"CONTROL GP_TITLE build 7: fallback elements {fb} (want [8, 13, 14])")
|
||||
print(f" index 8 is {ctl[8][0]!r} (want ptlogo_eff3.t32)")
|
||||
@@ -66,7 +67,7 @@ assert fb == [8, 13, 14] and ctl[8][0].startswith("ptlogo_eff3"), "control faile
|
||||
tot = fb_n = 0
|
||||
by_name = collections.Counter()
|
||||
worst = []
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
base = pak[:-4]
|
||||
for i, h, d in entries(base):
|
||||
for idx, name, poses in elements(d):
|
||||
@@ -119,7 +120,7 @@ def elements_t(d):
|
||||
|
||||
alpha = lambda p: (p[0] >> 24) & 0xff
|
||||
stats = collections.Counter()
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for i, h, d in entries(pak[:-4]):
|
||||
for idx, name, times, poses in elements_t(d):
|
||||
if has_plateau(poses): continue
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Plateau-less elements whose LAST keyframe is visible -- do they contradict
|
||||
the entry->hold->exit model, or are they 'slides in and stops'?"""
|
||||
import struct, zlib, glob, os, collections
|
||||
from disc import disc_root
|
||||
DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40
|
||||
def entries(base):
|
||||
stub=open(base+".pak","rb").read()
|
||||
@@ -41,7 +42,7 @@ def elements(d):
|
||||
alpha=lambda q:(q[0]>>24)&0xff
|
||||
mono=stuck=other=0
|
||||
ex=[]
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for d in entries(pak[:-4]):
|
||||
for nm,p in elements(d):
|
||||
if len(p)==1: continue
|
||||
|
||||
@@ -9,11 +9,12 @@ in the layout cutscene-message-table.md already documents.
|
||||
Run: python3 preset_messages.py > ../../docs/re/data/preset-messages.txt
|
||||
"""
|
||||
import sys, os, re, glob, collections
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from unit_substructures import pak_entries
|
||||
import unitgroup as U
|
||||
|
||||
DAT = '/work/sylph_extract/dat'
|
||||
DAT = disc_root() + '/dat'
|
||||
PAK = os.path.join(DAT, 'GP_MAIN_GAME_E.pak')
|
||||
MARKER = 'ORDOR_SQUADRON_EXTENDED'
|
||||
STAGES = ['S%02d' % i for i in list(range(1, 17)) + list(range(18, 30))]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Regenerates docs/re/data/prt-parts.txt.
|
||||
"""
|
||||
import sys, os, glob, re, struct, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -33,7 +34,7 @@ def main():
|
||||
elem2d = collections.defaultdict(set)
|
||||
dirs = collections.Counter()
|
||||
rat = collections.defaultdict(set)
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
base = os.path.basename(pk)
|
||||
for h, b in pak_entries(pk):
|
||||
H[h].add(base)
|
||||
|
||||
@@ -14,11 +14,12 @@ not depend on the Rust parser it is checking. Takes a few minutes.
|
||||
"""
|
||||
|
||||
import struct, zlib, glob, os, collections, bisect
|
||||
from disc import disc_root
|
||||
MAG = (b"T8aD", b"RATC", b"ttcf", b"\x89PNG")
|
||||
ext = collections.Counter()
|
||||
tan_sites = []
|
||||
opt_total = 0
|
||||
DISC = os.environ.get("SYLPHEED_DISC", "/work/sylph_extract")
|
||||
DISC = disc_root()
|
||||
for pakpath in sorted(glob.glob(f"{DISC}/dat/*.pak")):
|
||||
base = pakpath[:-4]
|
||||
pak = open(pakpath, "rb").read()
|
||||
|
||||
@@ -5,6 +5,7 @@ scored disc-wide. What CAN be quantified is the blast radius: how often the
|
||||
rules disagree, and how often each returns a pose that draws nothing.
|
||||
"""
|
||||
import struct, zlib, glob, collections
|
||||
from disc import disc_root
|
||||
DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40
|
||||
def entries(base):
|
||||
stub=open(base+".pak","rb").read()
|
||||
@@ -48,7 +49,7 @@ def dwell(t,p):
|
||||
alpha=lambda q:(q[0]>>24)&0xff
|
||||
n=agree=0
|
||||
inv=collections.Counter(); deg=collections.Counter()
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for d in entries(pak[:-4]):
|
||||
for t,p in elements(d):
|
||||
if len(p)==1: continue
|
||||
|
||||
@@ -21,6 +21,7 @@ the first version of this control did exactly that and reported 0 rotations for
|
||||
screen that plainly has two. `screen list` prints the mapping.
|
||||
"""
|
||||
import struct, zlib, glob, os, sys, collections
|
||||
from disc import disc_root
|
||||
DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40
|
||||
|
||||
def entries(base):
|
||||
@@ -64,8 +65,8 @@ def rotated(d):
|
||||
return out, total
|
||||
|
||||
# ---- CONTROL -------------------------------------------------------------
|
||||
t = dict(entries("/work/sylph_extract/dat/GP_TITLE"))
|
||||
g = dict(entries("/work/sylph_extract/dat/GP_DIALOG"))
|
||||
t = dict(entries(disc_root() + "/dat/GP_TITLE"))
|
||||
g = dict(entries(disc_root() + "/dat/GP_DIALOG"))
|
||||
ct, _ = rotated(t[4]); cg, _ = rotated(g[2]) # build 0 == entry 2, see the note above
|
||||
print(f"CONTROL GP_TITLE build 4 (nested rotations only): {len(ct)} top-level rotated (want 0)")
|
||||
print(f"CONTROL GP_DIALOG build 0: {len(cg)} top-level rotated (want 2)")
|
||||
@@ -75,7 +76,7 @@ assert len(ct) == 0 and len(cg) == 2, "control failed"
|
||||
# ---- census --------------------------------------------------------------
|
||||
tot = rot = 0
|
||||
per_pak = collections.Counter(); names = collections.Counter()
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for i, d in entries(pak[:-4]):
|
||||
r = rotated(d)
|
||||
if not r: continue
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
set -u
|
||||
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98 XENIA_PAD_FILE=/tmp/xenia_pad.txt
|
||||
export PYTHONPATH=/sylph-home/.local/lib/python3.12/site-packages
|
||||
SD=/tmp/claude-1000/-home-fabi-RE-Project-Sylpheed/b113cc12-4769-4ed8-ad66-c2b48f800773/scratchpad/wt-root/Syplheed-Reborn/tools/re-capture
|
||||
SD="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
export PATH="$SD/bin:$PATH"
|
||||
OUT=/tmp/route; rm -rf $OUT; mkdir -p $OUT
|
||||
pad(){ python3 "$SD/pad.py" "$@"; }
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Regenerates docs/re/data/script-manifest.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -11,7 +12,7 @@ import unitgroup as U
|
||||
from unit_substructures import pak_entries
|
||||
|
||||
def main():
|
||||
mg = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
mg = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
E = dict(pak_entries(mg))
|
||||
recs = U.parse(E[U.name_hash('Stage\\script.tbl')])
|
||||
|
||||
@@ -34,7 +35,7 @@ def main():
|
||||
print(" %-22s %r" % (n, v))
|
||||
|
||||
idx = {}
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
idx[os.path.basename(pk)] = {h for h, b in pak_entries(pk)}
|
||||
targets = ['MissionDialogMessage.tbl', 'MissionDialog_local_string.tbl',
|
||||
'pgmsg_start.prt', 'pgmsg_end.prt', 'pgmsg_update.prt',
|
||||
|
||||
@@ -14,6 +14,7 @@ See docs/re/menu-audio-cues.md.
|
||||
Decode with: ffmpeg -i out.riff out.wav
|
||||
"""
|
||||
import os, struct, sys
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
exec(open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"slb_segment_phase.py")).read().split("def cmd_phases")[0])
|
||||
@@ -41,7 +42,7 @@ def main():
|
||||
ch = int(a[3]) if len(a) > 3 else 1
|
||||
rate = int(a[4]) if len(a) > 4 else 48000
|
||||
out = a[5] if len(a) > 5 else f"{name.split('.')[0]}_{off:#x}.riff"
|
||||
disc = os.environ.get("SYLPHEED_DISC", "/work/sylph_extract")
|
||||
disc = disc_root()
|
||||
pak = Pak(os.path.join(disc, "dat", "sound.pak"))
|
||||
i = pak.find(name)
|
||||
if i is None:
|
||||
|
||||
@@ -21,7 +21,7 @@ Subcommands
|
||||
chain <name> [n] the tiling arithmetic across n consecutive entries
|
||||
|
||||
Usage
|
||||
SYLPHEED_DISC=/work/sylph_extract python3 slb_segment_phase.py verify
|
||||
SYLPHEED_DISC=/path/to/extracted/disc python3 slb_segment_phase.py verify
|
||||
"""
|
||||
|
||||
import bisect
|
||||
|
||||
@@ -13,13 +13,14 @@ a script message `MSG_<X>` plays the cue `VOICE_<X>`, and the bank file is
|
||||
`jpn\\Voice\\VOICE_<X>.slb`. See docs/re/structures/sound-cue-table.md.
|
||||
"""
|
||||
import collections
|
||||
from disc import disc_root
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
TABLES = '/work/sylph_extract/dat/tables.pak'
|
||||
TABLES = disc_root() + '/dat/tables.pak'
|
||||
|
||||
|
||||
def be32(b, o):
|
||||
@@ -98,7 +99,7 @@ def wstr(b, pool, off):
|
||||
|
||||
def captions(lang='E'):
|
||||
"""`MSG_*_<page>_<line>` -> text, from the pack's IXUD field tables."""
|
||||
pak = '/work/sylph_extract/dat/GP_MAIN_GAME_%s.pak' % lang
|
||||
pak = disc_root() + '/dat/GP_MAIN_GAME_%s.pak' % lang
|
||||
out = {}
|
||||
for b in pak_entries(pak).values():
|
||||
if b[:4] != b'IXUD':
|
||||
@@ -124,7 +125,7 @@ def captions(lang='E'):
|
||||
|
||||
def demo_messages(lang='E'):
|
||||
"""The cutscene message table: id -> per-page (speaker, face, dur, cue)."""
|
||||
pak = '/work/sylph_extract/dat/GP_MAIN_GAME_%s.pak' % lang
|
||||
pak = disc_root() + '/dat/GP_MAIN_GAME_%s.pak' % lang
|
||||
out = {}
|
||||
for b in pak_entries(pak).values():
|
||||
if b[:4] != b'IDXD' or b'MSG_DEMO' not in b:
|
||||
|
||||
@@ -16,8 +16,8 @@ alpha > 0 changes:
|
||||
|
||||
so each run yields calibration points at t = 15, 45 and the splash's end.
|
||||
"""
|
||||
import sys, collections
|
||||
sys.path.insert(0, '/work/tools/re-capture')
|
||||
import os, sys, collections
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from quads_per_frame import quads
|
||||
|
||||
def batch_runs(path, lo=0, hi=400):
|
||||
|
||||
@@ -6,6 +6,7 @@ player-craft mesh; the Arsenal pak's 168 stage-scoped entries say the same thing
|
||||
from the other side. Regenerates docs/re/data/stage-numbering.txt.
|
||||
"""
|
||||
import sys, os, glob, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -13,8 +14,8 @@ import unitgroup as U
|
||||
from unit_substructures import pak_entries
|
||||
|
||||
def main():
|
||||
mg = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
ars = glob.glob('/work/sylph_extract/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
mg = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
ars = glob.glob(disc_root() + '/**/GP_HANGAR_ARSENAL.pak', recursive=True)[0]
|
||||
H = {h for h, b in pak_entries(mg)}
|
||||
E = {h: b for h, b in pak_entries(ars)}
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ docs/re/structures/unit-group-table.md and tools/re-capture/unitgroup.py.
|
||||
# tables it names
|
||||
"""
|
||||
import argparse, re, sys
|
||||
from disc import disc_root
|
||||
sys.path.insert(0, __file__.rsplit('/', 1)[0])
|
||||
from unitgroup import read_entry, name_hash, parse, named
|
||||
|
||||
PAK = '/work/sylph_extract/dat/GP_MAIN_GAME_E.pak'
|
||||
PAK = disc_root() + '/dat/GP_MAIN_GAME_E.pak'
|
||||
|
||||
def stage_record_hash(stage):
|
||||
"""The per-stage definition record is not name-addressed; find it by content."""
|
||||
@@ -63,7 +64,7 @@ def main():
|
||||
seen.add(v)
|
||||
src, n = PAK, 'stage\\' + v.split('+')[-1]
|
||||
if '+' in v and 'DefTables' in v:
|
||||
src, n = '/work/sylph_extract/hidden/DefTables.pak', v.split('+')[-1]
|
||||
src, n = disc_root() + '/hidden/DefTables.pak', v.split('+')[-1]
|
||||
print()
|
||||
try: dump('%s (via %s)' % (n, fn), parse(read_entry(src, name_hash(n))), a.limit)
|
||||
except Exception as e: print('=== %s -> unresolved: %s' % (n, e))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Regenerates docs/re/data/turret-coverarea.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -30,7 +31,7 @@ def wclass(w):
|
||||
return w or '<empty>'
|
||||
|
||||
def main():
|
||||
mg = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
mg = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
units = units_of(mg)
|
||||
rows = [(gn.get('ID'), gn.get('Type'), U.named(r))
|
||||
for recs, gn in units for r in recs if TUR.fullmatch(r['squadron'])]
|
||||
@@ -71,7 +72,7 @@ def main():
|
||||
% (m(n), n.get('Frame'), n.get('YawLimit'), n.get('WeaponID', '')))
|
||||
|
||||
wid, mounted, vers = set(), set(), collections.Counter()
|
||||
for pk in sorted(glob.glob('/work/sylph_extract/**/*.pak', recursive=True)):
|
||||
for pk in sorted(glob.glob(disc_root() + '/**/*.pak', recursive=True)):
|
||||
for h, b in pak_entries(pk):
|
||||
if b[:4] != b'IDXD': continue
|
||||
try: recs = U.parse(b)
|
||||
|
||||
@@ -16,7 +16,7 @@ import struct
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
sys.path.insert(0, "/home/fabi/RE - Project Sylpheed/sylpheed-reborn/tools/re-capture")
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import gmem # noqa: E402
|
||||
|
||||
DELTAS = [0x00, 0x10, 0x08, 0x04, 0x0C, 0x14, 0x18, 0x20]
|
||||
|
||||
@@ -23,7 +23,7 @@ import struct
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
sys.path.insert(0, "/home/fabi/RE - Project Sylpheed/sylpheed-reborn/tools/re-capture")
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import gmem # noqa: E402
|
||||
|
||||
DEF_VTABLE = 0x820AF844
|
||||
|
||||
@@ -7,6 +7,7 @@ records: `Turret_NNN`, `Bridge_NNN`, `Hatch_NNN`, `ShieldGenerator_NNN`,
|
||||
`Thruster_NNN`, `Versatile_NNN`. Regenerates docs/re/data/unit-substructures.txt.
|
||||
"""
|
||||
import sys, os, glob, re, collections
|
||||
from disc import disc_root
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
@@ -48,7 +49,7 @@ def units_of(pak):
|
||||
return out
|
||||
|
||||
def main():
|
||||
pak = glob.glob('/work/sylph_extract/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
pak = glob.glob(disc_root() + '/**/GP_MAIN_GAME_E.pak', recursive=True)[0]
|
||||
units = units_of(pak)
|
||||
print("# Sub-records inside the %d unit tables of %s" % (len(units), os.path.basename(pak)))
|
||||
print("# Regenerate: python3 tools/re-capture/unit_substructures.py")
|
||||
|
||||
@@ -30,6 +30,7 @@ which holds for 1160 of 1160 squadrons across the 28 stage tables present in
|
||||
GP_MAIN_GAME_E.pak.
|
||||
"""
|
||||
import argparse, glob, os, struct, sys, zlib
|
||||
from disc import disc_root
|
||||
|
||||
MODULUS, RECIP = 0x00FFF9D7, 0x80031493
|
||||
|
||||
@@ -155,10 +156,11 @@ def load_stage(pak, stage):
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('stage', nargs='?', default='S02')
|
||||
ap.add_argument('--pak', default='/work/sylph_extract/dat/GP_MAIN_GAME_E.pak')
|
||||
ap.add_argument('--pak', help='default: $SYLPHEED_DISC/dat/GP_MAIN_GAME_E.pak')
|
||||
ap.add_argument('--all', action='store_true', help='every stage S01..S29')
|
||||
ap.add_argument('--check', action='store_true', help='only report the Count*4+5 identity')
|
||||
a = ap.parse_args()
|
||||
a.pak = a.pak or disc_root() + '/dat/GP_MAIN_GAME_E.pak'
|
||||
stages = ['S%02d' % n for n in range(1, 30)] if a.all else [a.stage]
|
||||
held = total = 0
|
||||
for st in stages:
|
||||
|
||||
@@ -8,10 +8,11 @@ capture: constant, smoothly varying (a continuous quantity), or jumpy.
|
||||
Usage: whatchanges.py <probe.bin> [name-substring] [max-report]
|
||||
"""
|
||||
import math
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, "/home/fabi/RE - Project Sylpheed/sylpheed-reborn/tools/re-capture")
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from flight_analyze import load # noqa: E402
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ the change. It counts elements whose guessed rest pose is zero-scale and whose
|
||||
alpha is non-zero, i.e. the ones the old code actually painted.
|
||||
"""
|
||||
import struct, zlib, glob, os, collections
|
||||
from disc import disc_root
|
||||
DECL_AT, DECL_ENTRY, KEYFRAME = 0x20, 60, 40
|
||||
def entries(base):
|
||||
stub=open(base+".pak","rb").read()
|
||||
@@ -59,7 +60,7 @@ def dwell_pick(t,p):
|
||||
return best[0]
|
||||
alpha=lambda p:(p[0]>>24)&0xff
|
||||
n=paint=0; where=collections.Counter(); ex=[]
|
||||
for pak in sorted(glob.glob("/work/sylph_extract/dat/GP_*.pak")):
|
||||
for pak in sorted(glob.glob(disc_root() + "/dat/GP_*.pak")):
|
||||
for i,h,d in entries(pak[:-4]):
|
||||
for idx,name,t,p in elements_t(d):
|
||||
if has_plateau(p): continue
|
||||
|
||||
@@ -56,9 +56,8 @@ def _resolve_db():
|
||||
"""Locate the database: `$SYLPHEED_DB` / `$SYLPH_XEXDB`, else `<repo root>/sylpheed.db`.
|
||||
|
||||
🔴 This used to be one hardcoded absolute path, and it pointed *inside*
|
||||
`xenia-rs` -- a repository `docs/agents/CONSOLIDATION.md` archives in Phase 5
|
||||
and drops in Phase 7. It resolved on exactly one machine and would have
|
||||
started failing there too, with `duckdb` raising about a missing file rather
|
||||
`xenia-rs` -- a repository that has since been archived. It resolved on
|
||||
exactly one machine and would have started failing there too, with `duckdb` raising about a missing file rather
|
||||
than anything saying why.
|
||||
|
||||
The database is a build artefact of several hundred MB and is not in the
|
||||
|
||||
Reference in New Issue
Block a user