#!/usr/bin/env python3 """Everything tools/bench/packed.lua needs to know about a DLXP container. python3 tools/bench/prep_packed.py -> tmp/packed_meta.lua THERE IS NO BLOB TO PREPARE, and that is the whole difference from `prep_stream.py`. The codec's rig has to hand the machine expanded codebooks, a packed palette and a record index, because a DLX record cannot be found or drawn without them; `prep_dlx.py` and `prep_stream.py` exist for that and FINDINGS 49.7.5 records what it cost to have two copies of one of those transforms. A packed container carries no such thing: record `i` is at sector 1 + i*97 by geometry and its bytes are already in the order GVRAM wants them (dlxp.py). So this file emits METADATA ONLY -- six numbers the rig would otherwise have to hard-code, every one of them read out of the container's own header. The volume is the container itself; tools/bench/mkvol.sh copies it. """ import os, sys sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "encoder")) from dlxp import DLXP, SECTOR if len(sys.argv) != 2: sys.exit(__doc__) d = DLXP(sys.argv[1]) # The record's sector count, and the array chain's entry count, DERIVED here and # asserted by the 68000 (PG_ARRN). Two independent statements of one geometry # is the only way a container and a player can be caught disagreeing about it -- # a chain one entry short delivers a picture with its last row missing, which # looks like a decode bug and is a layout bug. recs = d.rec_bytes // SECTOR rows = d.H entries = rows + (1 if d.has_palette else 0) out = "tmp/packed_meta.lua" with open(out, "w") as fh: fh.write("-- generated by tools/bench/prep_packed.py; do not edit\n") fh.write("return {\n") for k, v in [("W", d.W), ("H", d.H), ("fps", d.fps), ("nframes", d.nframes), ("rec_bytes", d.rec_bytes), ("rec_sectors", recs), ("pal_bytes", d.pal_bytes), ("pic_bytes", d.pic_bytes), ("lba0", d.off_frm // SECTOR), ("palette_last", int(d.palette_last)), ("has_palette", int(d.has_palette)), # DLXP2. Zero in a silent container, and the player branches on # the zero rather than being built two ways. ("cad_f", d.cad_f), ("cad_a", d.cad_a), ("has_audio", int(d.has_audio)), ("aud_bytes", d.aud_bytes), ("aud_hz", d.aud_hz), ("n_lumps", d.n_lumps), ("entries", entries)]: fh.write(f" {k} = {v},\n") fh.write("}\n") print(f"{sys.argv[1]}: DLXP{d.version} {d.W}x{d.H} {d.fps}fps {d.nframes} frames" + (f", AUDIO F={d.cad_f} A={d.cad_a}" if d.has_audio else ", silent")) print(f" record {d.rec_bytes:,} B = {recs} sectors, palette " f"{'LAST' if d.palette_last else 'FIRST'}, {d.pal_bytes} B") cad = (f" + (i//{d.cad_f})*{d.cad_a}" if d.has_audio else "") print(f" record i is at LBA {d.off_frm // SECTOR} + i*{recs}{cad} -- ARITHMETIC. " f"There is no index in this container and none can be needed.") print(f" the chain the 68000 must build: {entries} entries " f"({rows} rows{' + 1 palette' if d.has_palette else ''})") print(f" wire {d.video_kbps():.1f}" + (f" + {d.audio_kbps():.2f} = {d.kbps():.1f}" if d.has_audio else "") + f" KB/s, FIXED by geometry -> {out}")