#!/usr/bin/env python3
# Embed the C64 attract-demo recorded input streams (the four
# "SPACETAXI 0x" disk files -- RLE [joystick mask][tick count] pairs;
# mask bit0=UP bit1=DOWN bit2=LEFT bit3=RIGHT, bit7 always set, no
# fire bit -- which is why every recorded ride ends in a crash: the
# demo cab can never lower its gear) as C arrays for stDemoStreams.h.
#
# Every stream file is odd-length: the $9936 saver's end=$3F+3
# off-by-one appends one dangling byte past the last complete pair,
# trimmed here on all four.
#
# Rotation order is H -> W -> T -> X ($6FE2/$50C1 trace) with file
# mapping H=01, T=02, W=03, X=04 and demo levels H=8, W=23, T=20,
# X=24 (1-based).

import os

HERE    = os.path.dirname(os.path.abspath(__file__))
EXTRACT = os.path.join(HERE, "..", "..", "..", "stuff", "spacetaxi", "extract")
OUT     = os.path.join(HERE, "..", "stDemoStreams.h")

# (file, symbol, 0-based level index, screen letter) in ROTATION order.
STREAMS = [
    ("SPACETAXI 01_N0S.prg", "kDemoStreamH", 7,  "H"),
    ("SPACETAXI 03_N0S.prg", "kDemoStreamW", 22, "W"),
    ("SPACETAXI 02_N0S.prg", "kDemoStreamT", 19, "T"),
    ("SPACETAXI 04_N0S.prg", "kDemoStreamX", 23, "X"),
]


def main():
    with open(OUT, "w", encoding="ascii") as f:
        f.write("// Generated by assets/genDemoStreams.py -- do not hand-edit.\n")
        f.write("// C64 attract-demo recorded input streams (see the generator\n")
        f.write("// for format notes). Rotation order H, W, T, X.\n\n")
        f.write("#ifndef ST_DEMO_STREAMS_H\n#define ST_DEMO_STREAMS_H\n\n")
        f.write("#include <stdint.h>\n\n")
        entries = []
        for fname, sym, level, letter in STREAMS:
            data = open(os.path.join(EXTRACT, fname), "rb").read()
            if len(data) % 2 == 1:
                data = data[:-1]          # trim the saver's dangling byte
            f.write(f"// {letter}: {fname} ({len(data)} bytes after trim)\n")
            f.write(f"static const uint8_t {sym}[{len(data)}] = {{\n")
            for i in range(0, len(data), 12):
                row = ", ".join(f"0x{b:02X}" for b in data[i:i + 12])
                f.write(f"    {row},\n")
            f.write("};\n\n")
            entries.append((sym, len(data), level))
        f.write("typedef struct {\n")
        f.write("    const uint8_t *stream;\n")
        f.write("    uint16_t       length;\n")
        f.write("    uint8_t        levelIndex;   // 0-based\n")
        f.write("} StDemoEntryT;\n\n")
        f.write(f"static const StDemoEntryT kDemoRotation[{len(entries)}] = {{\n")
        for sym, ln, level in entries:
            f.write(f"    {{ {sym}, {ln}u, {level}u }},\n")
        f.write("};\n\n#endif\n")
    print(f"wrote {OUT}")


if __name__ == "__main__":
    main()
