mirror of
https://github.com/SK8-ENGINE/skate-3-rust-engine.git
synced 2026-10-26 19:47:44 +00:00
Resolve original HUD fonts through native VLT font-manager mappings
This commit is contained in:
1 parent
1c768a3e6c
commit
3c2860e376
2 files changed
+51
-12
No files matched your search
+41
-6
@@ -8,16 +8,50 @@ import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
import struct
|
||||
|
||||
from vendor.skate3_ui.project import extract_project
|
||||
from vendor.skate3_ui.scene_graph import AssetCache, SceneFlattener
|
||||
from vendor.skate3_ui.actions import Actions
|
||||
from asset_pipeline.vlt import hash64
|
||||
|
||||
|
||||
def prepare(game: Path, output: Path):
|
||||
def font_mapping(collections: Path, cache: AssetCache) -> dict:
|
||||
"""FontManager82808AE8 table; APT-name lookup82809208, load82809308.
|
||||
|
||||
Resolve the authored FileName, never infer family aliases from metrics.
|
||||
"""
|
||||
data = json.loads(collections.read_text(encoding='utf-8'))
|
||||
result = {}
|
||||
for row in data['collections']:
|
||||
if row['class'] != 'Hash_FECFBCAF356518C4':
|
||||
continue
|
||||
def field(name):
|
||||
return row['fields'].get(name, row['fields'].get(f'Hash_{hash64(name):016X}'))
|
||||
apt_name = row['fields']['Hash_340832CCFD9FDEB4']['data']
|
||||
filename = field('FileName')['data']
|
||||
matches = [r for r in cache.manifest['bundles']
|
||||
if 'font' in r and Path(r['name']).name == filename]
|
||||
if not matches:
|
||||
continue # The debug font is not a packaged front-end bitmap bank.
|
||||
if len(matches) != 1 or apt_name in result:
|
||||
raise ValueError(f'Ambiguous native font record: {apt_name}')
|
||||
scale = {name: struct.unpack('>f',bytes.fromhex(field(name)['data']))[0]
|
||||
for name in ('ScaleX','ScaleY','OffsetX','OffsetY')}
|
||||
target = matches[0]['font']['family']
|
||||
provenance = {'class': row['class'], 'key': row['key'],
|
||||
'source_sha256': row['sha256'], 'file_name':filename,
|
||||
'native_layout':scale}
|
||||
cache.add_font_alias(apt_name,target,provenance)
|
||||
result[apt_name] = provenance
|
||||
return result
|
||||
|
||||
|
||||
def prepare(game: Path, output: Path, collections: Path):
|
||||
extract_project(game, output, prefixes=("data/fe/source/screens/hud2/",
|
||||
"data/fe/source/controls/"), update=True)
|
||||
cache = AssetCache(output)
|
||||
mappings = font_mapping(collections,cache)
|
||||
name = "data/fe/source/screens/hud2/trickdisplay2"
|
||||
bundle = cache.load_bundle(name)
|
||||
apt_path = output / "raw" / (name + ".apt")
|
||||
@@ -42,17 +76,16 @@ def prepare(game: Path, output: Path):
|
||||
elif c['type_name'] == 'font':
|
||||
family = c['font']['name']
|
||||
asset = cache.font_asset(family)
|
||||
# Preserve this explicit source limitation. Preview.18 inferred a
|
||||
# metric alias in HighlightText; that is not proof of retail HUD
|
||||
# glyph/raster substitution. Never silently substitute a font.
|
||||
fonts[family] = asset
|
||||
result = {
|
||||
'format': 'skate3-scoring-hud', 'version': 1,
|
||||
'source': {'bundle': name,
|
||||
'apt_sha256': hashlib.sha256(apt_path.read_bytes()).hexdigest(),
|
||||
'const_sha256': hashlib.sha256(const_path.read_bytes()).hexdigest()},
|
||||
'const_sha256': hashlib.sha256(const_path.read_bytes()).hexdigest(),
|
||||
'collections_sha256': hashlib.sha256(collections.read_bytes()).hexdigest()},
|
||||
'characters': list(bundle['characters'].values()),
|
||||
'shapes': shapes, 'fonts': fonts, 'actions': blocks,
|
||||
'font_mappings':mappings,
|
||||
'unresolved_fonts': [family for family, asset in fonts.items() if asset is None],
|
||||
}
|
||||
target = output / 'runtime' / 'trickdisplay.json'
|
||||
@@ -68,5 +101,7 @@ if __name__ == '__main__':
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('--game', type=Path, required=True)
|
||||
p.add_argument('--output', type=Path, required=True)
|
||||
p.add_argument('--collections', type=Path, required=True,
|
||||
help='Owned private/stock/skater-collections.json')
|
||||
args = p.parse_args()
|
||||
prepare(args.game.resolve(), args.output.resolve())
|
||||
prepare(args.game.resolve(), args.output.resolve(), args.collections.resolve())
|
||||
Reference in new issue
Block a user