feat: converter reads the Phone library's register statement, named stores and generators
`init phone register` becomes a default (the group chat) plus a function of library calls that runs with the other defaults of a new game (phone_register.py). `init/python [early|hide] in some.store` wraps its code in an in_store node and `default some.store.name` may name a store; yield works as an expression (generator functions are marked gen); `import x as y`, `transform -150 name(...)`, `init:` with if/else, `config.special_namespaces` lines, `at` lists and tuples, transforms made by Python functions, `choice` weights that are expressions, `__len__`/`__bool__`, and the whitelist for os, calendar, itertools, pygame_sdl2 and the new runtime. The converter also records the size of every picture it converts (`imageSizes`) so `renpy.image_size` answers without loading. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e94f9b0d9e
commit
83cc7fdd5c
11 files changed
+379
-26
No files matched your search
@@ -134,11 +134,16 @@ def convert_archive(archive: Path, filename: str, work: Path, progress: Progress
|
||||
failed: list[str] = []
|
||||
done = 0
|
||||
|
||||
image_sizes: dict[str, list[int]] = {}
|
||||
|
||||
def work_one(p: Path) -> tuple[str, str, str, int]:
|
||||
dimensions = _dimensions(p)
|
||||
out, ext = assets.convert(p, out_dir)
|
||||
blob_id, size = put_file(out, ext, move=True)
|
||||
rel = p.relative_to(game_dir).as_posix()
|
||||
logical = str(PurePosixPath(rel).with_suffix(ext))
|
||||
if dimensions:
|
||||
image_sizes[logical] = dimensions # the game asks for them (`renpy.image_size`) before anything is loaded
|
||||
return rel, logical, blob_id, size
|
||||
|
||||
with ThreadPoolExecutor(max_workers=get_settings().worker_threads) as pool:
|
||||
@@ -223,6 +228,7 @@ def convert_archive(archive: Path, filename: str, work: Path, progress: Progress
|
||||
"build": data.build,
|
||||
"files": aliases,
|
||||
"dataFiles": data_files,
|
||||
"imageSizes": image_sizes,
|
||||
"defaults": data.defaults,
|
||||
"init": data.init_code,
|
||||
"ui": _ui(gui, aliases),
|
||||
@@ -342,6 +348,19 @@ def _used_screens(data: ScriptData) -> set[str]:
|
||||
DATA_FILE_LIMIT = 4 * 1024 * 1024
|
||||
|
||||
|
||||
def _dimensions(path: Path) -> list[int] | None:
|
||||
"""Width and height of a picture, read from its header (None for other media)."""
|
||||
if assets.kind_of(path) != "image":
|
||||
return None
|
||||
try:
|
||||
from PIL import Image
|
||||
|
||||
with Image.open(path) as img:
|
||||
return [int(img.size[0]), int(img.size[1])]
|
||||
except Exception: # noqa: BLE001 - the conversion itself reports a broken picture
|
||||
return None
|
||||
|
||||
|
||||
def _is_engine_file(game_dir: Path, p: Path) -> bool:
|
||||
parts = [x.lower() for x in p.relative_to(game_dir).parts]
|
||||
return len(parts) > 1 and parts[0] in ENGINE_DIRS
|
||||
|
||||
Reference in new issue
Block a user