Version 3.2.0: fast lists with loading spinners, names from the game files, INT docs and screenshots, cleanup
This commit is contained in:
@@ -5,7 +5,8 @@ Sources, in order:
|
||||
1. data/catalog/<ARCHIVE>.csv -- shipped catalog (instant) when the WAD fingerprint matches;
|
||||
2. otherwise a header scan of the WAD (a few seconds, cached in the user cache), classified with
|
||||
`classify` and labelled with data/catalog/characters.csv (speaker per sound name).
|
||||
Names follow the community hash list (ackit/data/hashlist.txt): an entry with one WEM is NAME
|
||||
Names come from the game: a WAD entry ID is the Wwise ID (FNV-1) of a soundbank listed in the game's
|
||||
CookedPCConsole/CookedBanks.txt (`bank_names`); an entry with one WEM is NAME
|
||||
(alias NAME_1), entries with n variations are NAME_1..NAME_n (alias NAME#i); stream-pack media are
|
||||
named by their ID or <Pack>_<ID>.
|
||||
"""
|
||||
@@ -21,10 +22,11 @@ from dataclasses import dataclass, asdict
|
||||
from . import banks, classify, subtitles
|
||||
from . import lines as lines_mod
|
||||
from .game import wad_fingerprint
|
||||
from .bnk import fnv1
|
||||
from .lines import bank_langs
|
||||
from .inject import pack_bnk_path
|
||||
from .pack import Pack
|
||||
from .paths import catalog_dir, package_data, user_dir
|
||||
from .paths import catalog_dir, user_dir
|
||||
from .wad import Wad
|
||||
|
||||
FIELDS = ["archive", "target", "name", "aliases", "group", "category", "bank", "language", "line", "character",
|
||||
@@ -78,21 +80,28 @@ class Sound:
|
||||
|
||||
|
||||
# --- static data ---------------------------------------------------------------------------
|
||||
_names = None
|
||||
_names = {} # cooked folder -> {Wwise ID: bank name}
|
||||
|
||||
|
||||
def hash_names():
|
||||
global _names
|
||||
if _names is None:
|
||||
_names = {}
|
||||
for ln in open(package_data("hashlist.txt"), encoding="latin-1"):
|
||||
p = ln.rstrip("\r\n").split("\t")
|
||||
if len(p) >= 2 and p[1]:
|
||||
try:
|
||||
_names[int(p[0], 16)] = p[1]
|
||||
except ValueError:
|
||||
pass
|
||||
return _names
|
||||
def bank_names(cooked):
|
||||
"""{Wwise ID: name} of the game's soundbanks, from its own CookedBanks.txt (ID = FNV-1 of the name). They
|
||||
name the WAD entries (each entry holds the streamed media of one bank) and the stream packs."""
|
||||
key = os.path.normcase(os.path.abspath(cooked))
|
||||
if key not in _names:
|
||||
out = {}
|
||||
p = os.path.join(cooked, "CookedBanks.txt")
|
||||
if os.path.exists(p):
|
||||
for ln in open(p, encoding="latin-1"):
|
||||
n = ln.strip()
|
||||
if n:
|
||||
out.setdefault(fnv1(n), n)
|
||||
_names[key] = out
|
||||
return _names[key]
|
||||
|
||||
|
||||
def cooked_of(wad_path):
|
||||
"""CookedPCConsole folder of a WAD (WADs are in CookedPCConsole/<language or SFX>/)."""
|
||||
return os.path.dirname(os.path.dirname(os.path.abspath(wad_path)))
|
||||
|
||||
|
||||
def load_characters(path=None, lang=None):
|
||||
@@ -180,7 +189,7 @@ def _walk_entry(f, offset, size):
|
||||
|
||||
def scan_archive(archive, wad_path, characters=None, progress=None):
|
||||
"""Header scan of one WAD -> [Sound]."""
|
||||
names = hash_names()
|
||||
names = bank_names(cooked_of(wad_path))
|
||||
characters = characters if characters is not None else load_characters(lang=archive)
|
||||
wad = Wad(wad_path)
|
||||
out = []
|
||||
|
||||
Reference in New Issue
Block a user