74 lines
3.3 KiB
Python
74 lines
3.3 KiB
Python
"""Orchestrate: converted image -> self-contained viewer -> Commodore disk image."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from . import basicgen, crt, diskimage, imginfo
|
|
from .convert.base import Conversion
|
|
from .viewer.assemble import (SOURCES, build_cart_rom, build_data_prg,
|
|
build_viewer_prg)
|
|
|
|
|
|
def export_disk(conv: Conversion, output_path: str,
|
|
disk_format: str | None = None,
|
|
disk_name: str | None = None,
|
|
include_graphic_file: bool = True,
|
|
source_path: str | None = None,
|
|
video: str = "pal",
|
|
display: str = "key", seconds: int = 0,
|
|
layout: str = "unified") -> str:
|
|
"""Write ``conv`` to a disk image at ``output_path``.
|
|
|
|
The disk's first (bootable) file is a self-contained viewer that already
|
|
embeds the picture, so ``LOAD"*",8,1`` then ``RUN`` displays it. When
|
|
``include_graphic_file`` is set, the picture is also written in a standard
|
|
interchange format (e.g. Koala) for use in other C64 art tools. When
|
|
``source_path`` is given and there is room, a colourful BASIC "info" program
|
|
describing the original image is added too. Returns the absolute path written.
|
|
"""
|
|
fmt = diskimage.fmt_from_path(output_path, disk_format)
|
|
stem = os.path.splitext(os.path.basename(output_path))[0]
|
|
name = diskimage.petscii_name(disk_name or stem or "8bitlenser")
|
|
|
|
# Timing-sensitive viewers (FLI) have an NTSC variant; others run on both.
|
|
vkey = conv.viewer
|
|
if video == "ntsc" and f"{conv.viewer}_ntsc" in SOURCES:
|
|
vkey = f"{conv.viewer}_ntsc"
|
|
|
|
# Separate layout (viewer code + a standalone "data" file the viewer loads) is
|
|
# supported by the simple viewers; FLI/interlace fall back to unified.
|
|
separate = layout == "separate" and vkey in ("hires", "multicolor")
|
|
viewer_prg = build_viewer_prg(vkey, conv.data, conv.data_addr, display=display,
|
|
seconds=seconds, video=video, separate=separate)
|
|
files: list[tuple[str, bytes]] = [(name, viewer_prg)]
|
|
if separate:
|
|
files.append(("data", build_data_prg(conv.data, conv.data_addr)))
|
|
if include_graphic_file:
|
|
files.extend(conv.extra_files)
|
|
|
|
if source_path:
|
|
# Best effort: never let the info file break a successful export.
|
|
try:
|
|
info = basicgen.build_info_prg(imginfo.gather(source_path))
|
|
budget = diskimage.BLOCKS_FREE[fmt] * 254
|
|
info_name = "info" if name != "info" else "picinfo"
|
|
if sum(len(b) for _, b in files) + len(info) <= budget:
|
|
files.append((info_name, info))
|
|
except Exception:
|
|
pass
|
|
|
|
return diskimage.build_disk(output_path, fmt, name, "01", files)
|
|
|
|
|
|
def export_cart(conv: Conversion, output_path: str, source_path: str | None = None,
|
|
video: str = "pal", display: str = "forever", seconds: int = 0) -> str:
|
|
"""Write ``conv`` as an autostarting 16K C64 .crt cartridge.
|
|
|
|
Only hires/multicolor/mono fit a 16K cart; FLI/interlace must use a disk."""
|
|
if not output_path.lower().endswith(".crt"):
|
|
output_path += ".crt"
|
|
name = os.path.splitext(os.path.basename(output_path))[0]
|
|
rom = build_cart_rom(conv.viewer, conv.data, display=display,
|
|
seconds=seconds, video=video)
|
|
return crt.write_crt(rom, output_path, name)
|