"""Orchestrate: converted image -> self-contained viewer -> Commodore disk image.""" from __future__ import annotations import os from . import basicgen, diskimage, imginfo from .convert.base import Conversion from .viewer.assemble import SOURCES, 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") -> 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 "c64view") # 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" viewer_prg = build_viewer_prg(vkey, conv.data, conv.data_addr) files: list[tuple[str, bytes]] = [(name, viewer_prg)] 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)