76 lines
2.8 KiB
Python
76 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
# Bake examples/spacetaxi/assets/songs/song*.song into stSongData.h.
|
|
#
|
|
# python3 examples/spacetaxi/assets/genSongData.py
|
|
#
|
|
# The .song sources come from the game's own player run under a 6502
|
|
# emulator: assets/sidCapture.py logs every SID write per PAL frame and
|
|
# assets/sidToSong.py turns that into songbake text.
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
here = os.path.dirname(os.path.abspath(__file__))
|
|
repo = os.path.abspath(os.path.join(here, "..", "..", ".."))
|
|
songbake = os.path.join(repo, "tools", "songbake", "songbake.py")
|
|
out = os.path.join(here, "..", "stSongData.h")
|
|
count = 9
|
|
|
|
header = """// Space Taxi (C64) tunes as JoeyLib JYM1 streams. GENERATED by
|
|
// assets/genSongData.py -- do not hand-edit. The songs were extracted by
|
|
// running the game's own music player under a 6502 emulator
|
|
// (assets/sidCapture.py logs every SID write per PAL frame;
|
|
// assets/sidToSong.py turns that into songbake text in assets/songs/).
|
|
//
|
|
// Where the C64 plays them:
|
|
// BLOCKING via $44CF (the game spins until the tune ends; the port
|
|
// parks in ST_STATE_JINGLE with the sim frozen):
|
|
// 0..3 start of every screen, rotating on $5E9B ($6906)
|
|
// 4 level 25 start ($6935) and the bonus cab ($70B1)
|
|
// 5 game over ($5C1F), after the two-second GAME OVER! wait
|
|
// NON-BLOCKING via $CB02 (started and left to the IRQ player):
|
|
// 6 the high-score name entry screen ($4E35) -- no port screen yet
|
|
// 7 the high-score table ($4C1F, joystick UP on the title)
|
|
// 8 the level intro while the cab flies in ($459C); endless, so
|
|
// the source is trimmed to 30 s and looped
|
|
#ifndef ST_SONG_DATA_H
|
|
#define ST_SONG_DATA_H
|
|
|
|
#include <stdint.h>
|
|
|
|
"""
|
|
|
|
footer = """typedef struct {
|
|
const uint8_t *data;
|
|
uint16_t length;
|
|
} StSongT;
|
|
|
|
#define ST_SONG_COUNT %du
|
|
#define ST_SONG_BONUS 4u
|
|
#define ST_SONG_GAME_OVER 5u
|
|
#define ST_SONG_NAME_ENTRY 6u
|
|
#define ST_SONG_SCORES 7u
|
|
#define ST_SONG_INTRO 8u
|
|
|
|
static const StSongT kStSongs[ST_SONG_COUNT] = {
|
|
%s};
|
|
|
|
#endif // ST_SONG_DATA_H
|
|
"""
|
|
|
|
parts = []
|
|
for n in range(count):
|
|
src = os.path.join(here, "songs", "song%d.song" % n)
|
|
with tempfile.NamedTemporaryFile(suffix=".h", delete=False) as tmp:
|
|
path = tmp.name
|
|
subprocess.run([sys.executable, songbake, "-c", "gStSong%d" % n, src, path], check=True, stderr=subprocess.DEVNULL)
|
|
body = open(path).read()
|
|
os.unlink(path)
|
|
body = "\n".join(l for l in body.split("\n") if l.startswith("static") or l.startswith(" ") or l.startswith("}"))
|
|
parts.append(body.rstrip() + "\n\n")
|
|
|
|
table = "".join(" { gStSong%d, (uint16_t)sizeof(gStSong%d) },\n" % (n, n) for n in range(count))
|
|
with open(out, "w") as fp:
|
|
fp.write(header + "".join(parts) + footer % (count, table))
|
|
print("wrote", os.path.normpath(out))
|