re: caption pages are utterances, and the dialogue tool was truncating 356 names

Measured the <id>_<page>_<line> key structure: a page is one subtitle box of
3 or 4 wrapped lines, and successive pages are successive utterances by
possibly different speakers. 452 of 4091 ids span more than one page, up to 8.

That refutes the isl_dialogue.py committed two commits ago, which read only
page 000 -- 356 of the 1338 script message names are multi-page, so a quarter
of its output was truncated to the opening utterance. Tool now walks pages
until one is empty; Stage 02 sample regenerated (43 of 213 calls multi-page).

The 2683/2683 resolution figure is unaffected: it counted ids that have text,
and every id does have a page 000. What was wrong was the rendered text.
This commit is contained in:
Sylpheed RE agent
2026-08-26 03:11:38 +00:00
parent de132c5dec
commit a962daf518
3 changed files with 119 additions and 11 deletions

View File

@@ -6,7 +6,8 @@ with the caption text it plays.
Built-in 64 takes a symbol-table-1 (type 6) message name; the caption text lives
in the pack's IXUD blocks under `<name>_<page>_<line>`. All 2683 call sites
across the 28 stages resolve, so this is a total mapping rather than a sample.
across the 28 stages resolve, so this is a total mapping rather than a sample. 356 of the 1338 distinct
message names span more than one page; every page is printed.
"""
import collections
import struct
@@ -16,6 +17,12 @@ import isl
NO_NAME = 0xFFFFFFFF
# A caption id is keyed `<id>_<page>_<line>`. A page is one subtitle box of up
# to four wrapped lines; successive pages are successive utterances. Measured
# maxima on the English pack: 8 pages, 4 lines.
MAX_PAGES = 16
MAX_LINES = 8
def be32(b, o):
return struct.unpack_from('>I', b, o)[0]
@@ -114,9 +121,15 @@ def main():
if not isinstance(v, int) or v not in s1:
return
name = s1[v][1]
text = [cap[k] for k in
('%s_000_%02d' % (name, i) for i in range(4)) if k in cap]
lines.append((off, name, ' '.join(text)))
pages = []
for page in range(MAX_PAGES):
box = [cap[k] for k in
('%s_%03d_%02d' % (name, page, i) for i in range(MAX_LINES))
if k in cap]
if not box:
break
pages.append(' '.join(box))
lines.append((off, name, pages))
bases = isl.phase_bases(b) + [end]
for i in range(len(bases) - 1):
@@ -128,14 +141,22 @@ def main():
print('Generated by `tools/re-capture/isl_dialogue.py`. Each line is one')
print('`request_script_message` (built-in 64) and the caption it plays.')
print()
print('%d message calls, %d with text.' % (len(lines), sum(1 for _, _, t in lines if t)))
multi = sum(1 for _, _, p in lines if len(p) > 1)
print('%d message calls, %d with text, %d spanning more than one page.'
% (len(lines), sum(1 for _, _, p in lines if p), multi))
print()
print('A page is one subtitle box (measured maximum 4 wrapped lines).')
print('Successive pages are successive utterances and may be different')
print('speakers, so a multi-page id is a whole exchange, not one line.')
print()
seen = set()
for off, nm, text in lines:
for off, nm, pages in lines:
if off in seen:
continue
seen.add(off)
print('%06X %-22s %s' % (off, nm, text))
print('%06X %-22s %s' % (off, nm, pages[0] if pages else ''))
for extra in pages[1:]:
print('%6s %-22s %s' % ('', '', extra))
if __name__ == '__main__':