74 lines
3.3 KiB
Python
74 lines
3.3 KiB
Python
#!/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 bit4=FIRE, bit7 always
|
|
# set) as C arrays for stDemoStreams.h.
|
|
#
|
|
# Every stream file is odd-length: the $9936 saver appends one
|
|
# dangling byte past the last complete pair. It is kept: the C64 reads
|
|
# it (and whatever follows in the buffer) when a ride outlasts its
|
|
# recording.
|
|
#
|
|
# 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()
|
|
# The whole file, dangling byte included: the C64 plays past
|
|
# the last pair into whatever the buffer held before.
|
|
f.write(f"// {letter}: {fname} ({len(data)} bytes)\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))
|
|
# The playback buffer at $0902 as the boot leaves it (demo H
|
|
# loaded over older RAM): recordings shorter than the previous one
|
|
# leave its tail in place, and the game reads on into it.
|
|
raw = open(os.path.join(HERE, "..", "..", "..", "stuff", "spacetaxi", "raw.bin"), "rb").read()[2:]
|
|
buf = raw[0x0902:0x0902 + 640]
|
|
f.write("#define ST_DEMO_BUFFER_BYTES 640u\n")
|
|
f.write("static const uint8_t kDemoBufferInit[ST_DEMO_BUFFER_BYTES] = {\n")
|
|
for i in range(0, len(buf), 12):
|
|
row = ", ".join(f"0x{b:02X}" for b in buf[i:i + 12])
|
|
f.write(f" {row},\n")
|
|
f.write("};\n\n")
|
|
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()
|