Edit subtitles and menu text
This commit is contained in:
@@ -18,7 +18,7 @@ import re
|
||||
import struct
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
from . import banks, classify
|
||||
from . import banks, classify, subtitles
|
||||
from .game import wad_fingerprint
|
||||
from .inject import pack_bnk_path
|
||||
from .pack import Pack
|
||||
@@ -228,9 +228,13 @@ def bank_sounds(sc, characters=None):
|
||||
|
||||
|
||||
def head_owners(game, sc, archives=None):
|
||||
"""{prefetch media id: WAD sound key} -- the speech line (one language) each prefetch head belongs to,
|
||||
found through the per-language BKPK tables of the packages (docs/formats/banks.md)."""
|
||||
want = {m for m, e in sc.media.items() if banks.PREFETCH_HEAD in e["kinds"]}
|
||||
"""{prefetch media id: WAD sound key} -- the speech line (one language) each prefetch head belongs to."""
|
||||
return media_owners(game, sc, {m for m, e in sc.media.items() if banks.PREFETCH_HEAD in e["kinds"]}, archives)
|
||||
|
||||
|
||||
def media_owners(game, sc, want, archives=None):
|
||||
"""{media id: WAD sound key} for streamed speech media, found through the per-language BKPK tables of
|
||||
the packages (docs/formats/banks.md): every language has its own media IDs for the same WAD entry."""
|
||||
out = {}
|
||||
for a in archives or [x for x in game.archives if x != "SFX"]:
|
||||
wad = Wad(game.wad(a))
|
||||
@@ -250,14 +254,61 @@ def head_owners(game, sc, archives=None):
|
||||
return out
|
||||
|
||||
|
||||
def scan_banks(game, progress=None, characters=None):
|
||||
def scan_banks(game, progress=None, characters=None, visit=None):
|
||||
"""Full scan of the game's banks -> ([Sound], [Location] with WAD keys on prefetch heads, Scan)."""
|
||||
sc = banks.scan(game.cooked, progress)
|
||||
sc = banks.scan(game.cooked, progress, visit=visit)
|
||||
owners = head_owners(game, sc)
|
||||
locs = [l._replace(sound=owners.get(l.media, "")) if l.kind == banks.PREFETCH_HEAD else l for l in sc.locations]
|
||||
return bank_sounds(sc, characters), locs, sc
|
||||
|
||||
|
||||
def subtitle_links(game, sc, speech_names):
|
||||
"""{speech event name: {language: WAD sound key}}: event -> actions -> containers -> sounds -> the
|
||||
per-language media of the streamed speech line (exact, no name matching)."""
|
||||
ev = banks.event_media(sc)
|
||||
want = {m for n in speech_names for m in ev.get(n, ())}
|
||||
owners = media_owners(game, sc, want)
|
||||
out = {}
|
||||
for n in speech_names:
|
||||
keys = {}
|
||||
for m in ev.get(n, ()):
|
||||
k = owners.get(m)
|
||||
if k:
|
||||
keys.setdefault(k.split(":")[0], k)
|
||||
if keys:
|
||||
out[n] = keys
|
||||
return out
|
||||
|
||||
|
||||
def scan_text(game, progress=None, characters=None):
|
||||
"""One pass over every package: (bank sounds, bank locations, Scan, {lang: [SubLine]}, [SubLoc], issues)."""
|
||||
col = subtitles.Collector()
|
||||
snd, locs, sc = scan_banks(game, progress, characters, visit=col)
|
||||
links = subtitle_links(game, sc, list(col.dialogues))
|
||||
texts, sublocs = subtitles.rows(col, links)
|
||||
return snd, locs, sc, texts, sublocs, col.issues
|
||||
|
||||
|
||||
def load_subtitles(game, lang, progress=None):
|
||||
"""([SubLine], {SUB key: [SubLoc]}) of one language: shipped catalog when the game matches it, else a
|
||||
cached or fresh scan of the packages (several minutes)."""
|
||||
fp = banks.game_fingerprint(game.cooked)
|
||||
shipped = _shipped_index().get("SUB", {})
|
||||
t = os.path.join(catalog_dir(), "SUB_%s.csv" % lang)
|
||||
loc = os.path.join(catalog_dir(), subtitles.LOCATIONS)
|
||||
if shipped.get("fingerprint") == fp and os.path.exists(t) and os.path.exists(loc):
|
||||
return subtitles.read_texts(t, lang), subtitles.read_locations(loc, lang)
|
||||
cache = os.path.join(user_dir("cache"), "scan_SUB_%s_v%d" % (fp, SCAN_VERSION))
|
||||
if not os.path.exists(cache + ".locations.csv.gz"):
|
||||
_, _, _, texts, sublocs, _ = scan_text(game, progress)
|
||||
for lg, rows in texts.items():
|
||||
subtitles.write_texts(cache + "_%s.csv" % lg, rows)
|
||||
subtitles.write_locations(cache + ".locations.csv.gz", sublocs)
|
||||
t = cache + "_%s.csv" % lang
|
||||
return (subtitles.read_texts(t, lang) if os.path.exists(t) else []), \
|
||||
subtitles.read_locations(cache + ".locations.csv.gz", lang)
|
||||
|
||||
|
||||
def load_banks(game, progress=None):
|
||||
"""([Sound], {media: [Location]}) of the in-memory sounds: shipped catalog when the game's bank set
|
||||
matches it, else a cached or fresh scan (several minutes)."""
|
||||
|
||||
Reference in New Issue
Block a user