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>
71 lines
2.9 KiB
Python
Executable File
71 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Boot-splash boundaries from a UI draw log, counted the way that survives the cap.
|
|
|
|
🔴 Do NOT read element visibility off which quads the log prints. A draw batches
|
|
several quads (`indices=24` is six) and the log dumps only the first 8 vertices —
|
|
two quads — so which elements appear is the first two IN THE BATCH, and that set
|
|
moves as elements fade. On the developer splash the three glows hold that prefix
|
|
until t=45, which makes the three wordmarks look as though they start there.
|
|
|
|
`indices / 4` is how many quads the draw actually holds, and the cap cannot touch
|
|
it. Its transitions land exactly where the declared count of elements with
|
|
alpha > 0 changes:
|
|
|
|
publisher 1 -> 2 -> 1 (wordmark joins the glow at t=15; glow ends at t=45)
|
|
developer 3 -> 6 -> 3 (three wordmarks join three glows; glows end)
|
|
|
|
so each run yields calibration points at t = 15, 45 and the splash's end.
|
|
"""
|
|
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):
|
|
per = {}
|
|
for (f, ind, got, exp, x, y, w, h, a) in quads(path, lo, hi):
|
|
if exp >= 1:
|
|
per[f] = max(per.get(f, 0), exp if exp >= 2 else 1)
|
|
runs = []
|
|
cur = None
|
|
for f in sorted(per):
|
|
n = per[f]
|
|
if cur and cur[2] == n and f <= cur[1] + 2:
|
|
cur[1] = f
|
|
else:
|
|
if cur: runs.append(tuple(cur))
|
|
cur = [f, f, n]
|
|
if cur: runs.append(tuple(cur))
|
|
return [r for r in runs if r[1] - r[0] >= 1]
|
|
|
|
def main():
|
|
path = sys.argv[1]
|
|
runs = batch_runs(path)
|
|
print(f"# {path}")
|
|
for a, b, n in runs:
|
|
print(f" frames {a:>4}..{b:<4} ({b-a+1:>3}) {n} quads")
|
|
# publisher = the 2-quad run; developer = the 6-quad run
|
|
pub = [r for r in runs if r[2] == 2]
|
|
dev6 = [r for r in runs if r[2] == 6]
|
|
dev3 = [r for r in runs if r[2] == 3]
|
|
if pub and dev6 and dev3:
|
|
p = pub[0]
|
|
d6 = dev6[0]
|
|
d3after = [r for r in dev3 if r[0] > d6[1]]
|
|
d3before = [r for r in dev3 if r[1] < d6[0]]
|
|
if d3after and d3before:
|
|
pub_start, pub_end = d3before[0][0], None
|
|
# publisher span: its own 2-quad run brackets t=15..45; the screen ends
|
|
# at the last frame before the developer's first 3-quad run
|
|
pub_last = d3before[0][0] - 1
|
|
pub_first = 1
|
|
dev_first = d3before[0][0]
|
|
dev_last = d3after[-1][1]
|
|
print(f"\n publisher frames {pub_first}..{pub_last} = {pub_last-pub_first+1}")
|
|
print(f" developer frames {dev_first}..{dev_last} = {dev_last-dev_first+1}")
|
|
r = (pub_last-pub_first+1)/(dev_last-dev_first+1)
|
|
print(f" ratio = {r:.4f} (declared 255/210 = {255/210:.4f}, "
|
|
f"excess {(r-255/210)/(255/210)*100:+.2f}%)")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|