mirror of
https://github.com/valentderah/totk-pc-recomp.git
synced 2026-11-11 01:41:02 +00:00
The setup takes an optional --firmware directory (an unpacked firmware or an emulator's Contents/registered) and, for Chinese, Korean and Traditional Chinese, runs the vendored font extractor into <install>/shared-fonts. Without the folder it warns as before and the install still completes. The fonts step is keyed by the language and a cheap firmware fingerprint; the window gets a folder picker and help text, and the command line takes --firmware.
79 lines
3.2 KiB
Python
79 lines
3.2 KiB
Python
"""totk.ini: set the game language and keep everything else (keys and syntax as runtime/cfg.c reads them).
|
|
|
|
A new file starts from totk.ini.example, whose lines are all commented defaults. The language goes into `lang`
|
|
(a Switch language code, runtime/ov_system.c): an active `lang = ...` line is rewritten in place, else the commented
|
|
`# lang = ...` line of the example is activated, else the line is added to [language] (created at the end if
|
|
missing). Other lines, comments and line order stay as they are.
|
|
"""
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
# runtime/ov_system.c: the codes TOTK_LANG offers. Each language appears once, under the code the game accepts.
|
|
LANGUAGES = ('ja', 'en-US', 'en-GB', 'fr', 'fr-CA', 'de', 'it', 'es', 'es-419', 'nl', 'pt', 'pt-BR', 'ru', 'ko',
|
|
'zh-Hans', 'zh-Hant')
|
|
# Older installer builds wrote these two codes; they are read as the canonical ones and rewritten on the next install.
|
|
ALIASES = {'zh-CN': 'zh-Hans', 'zh-TW': 'zh-Hant'}
|
|
# Their text falls back to the Switch shared fonts (runtime/ov_system.c), which the fonts step extracts from the
|
|
# firmware folder when the player gives one.
|
|
NEED_SHARED_FONTS = ('ko', 'zh-Hans', 'zh-Hant')
|
|
|
|
ACTIVE = re.compile(r'^(\s*)(?:totk_)?lang(\s*=\s*)(.*?)(\s*)$', re.IGNORECASE)
|
|
COMMENTED = re.compile(r'^\s*[#;]\s*(?:totk_)?lang\s*=.*$', re.IGNORECASE)
|
|
SECTION = re.compile(r'^\s*\[(.*)\]\s*$')
|
|
|
|
|
|
def canonical_language(lang):
|
|
"""The code LANGUAGES lists for lang: an alias of an older installer build is mapped, anything else is kept."""
|
|
return ALIASES.get(lang, lang)
|
|
|
|
|
|
def set_language(text, lang):
|
|
"""text with `lang = <lang>` (an alias written as its canonical code); see the module docstring."""
|
|
lang = canonical_language(lang)
|
|
lines = text.splitlines()
|
|
for i, line in enumerate(lines):
|
|
m = ACTIVE.match(line)
|
|
if m:
|
|
lines[i] = f'{m.group(1)}lang{m.group(2)}{lang}'
|
|
return '\n'.join(lines) + '\n'
|
|
for i, line in enumerate(lines):
|
|
if COMMENTED.match(line):
|
|
lines[i] = f'lang = {lang}'
|
|
return '\n'.join(lines) + '\n'
|
|
for i, line in enumerate(lines):
|
|
m = SECTION.match(line)
|
|
if m and m.group(1).strip().lower() == 'language':
|
|
lines.insert(i + 1, f'lang = {lang}')
|
|
return '\n'.join(lines) + '\n'
|
|
if lines and lines[-1].strip():
|
|
lines.append('')
|
|
lines += ['[language]', f'lang = {lang}']
|
|
return '\n'.join(lines) + '\n'
|
|
|
|
|
|
def get_language(text):
|
|
for line in text.splitlines():
|
|
m = ACTIVE.match(line)
|
|
if m:
|
|
return m.group(3)
|
|
return None
|
|
|
|
|
|
def write(dest, lang, example=None):
|
|
"""Write dest/totk.ini with lang; an existing file keeps its other lines. Returns the path."""
|
|
path = Path(dest) / 'totk.ini'
|
|
if path.is_file():
|
|
text = path.read_text(encoding='utf-8-sig')
|
|
elif example and Path(example).is_file():
|
|
text = Path(example).read_text(encoding='utf-8')
|
|
else:
|
|
text = ''
|
|
new = set_language(text, lang)
|
|
if path.is_file() and new == text:
|
|
return path
|
|
tmp = path.with_name('totk.ini.tmp')
|
|
tmp.write_text(new, encoding='utf-8', newline='\n')
|
|
os.replace(tmp, path)
|
|
return path
|