some bugfixes

This commit is contained in:
minjaesong
2026-06-20 04:37:21 +09:00
parent ddc4a22809
commit 76e297a412
2 changed files with 22 additions and 7 deletions

View File

@@ -10,3 +10,7 @@ for f in *.xm; python3 xm2taud.py $f assets/disk0/home/music/(basename $f .xm).t
for f in *.XM; python3 xm2taud.py $f assets/disk0/home/music/(basename $f .XM).taud; end for f in *.XM; python3 xm2taud.py $f assets/disk0/home/music/(basename $f .XM).taud; end
for f in *.mon; python3 mon2taud.py $f assets/disk0/home/music/(basename $f .mon).taud; end for f in *.mon; python3 mon2taud.py $f assets/disk0/home/music/(basename $f .mon).taud; end
for f in *.MON; python3 mon2taud.py $f assets/disk0/home/music/(basename $f .MON).taud; end for f in *.MON; python3 mon2taud.py $f assets/disk0/home/music/(basename $f .MON).taud; end
for f in *.mid; python3 midi2taud.py $f GeneralUser-GS.sf2 assets/disk0/home/music/(basename $f .mid).taud --force-synth-loop; end
for f in *.MID; python3 midi2taud.py $f GeneralUser-GS.sf2 assets/disk0/home/music/(basename $f .MID).taud --force-synth-loop; end
for f in *.midi; python3 midi2taud.py $f GeneralUser-GS.sf2 assets/disk0/home/music/(basename $f .midi).taud --force-synth-loop; end

View File

@@ -86,17 +86,28 @@ def parse_mon(data: bytes):
if data[:9] != MON_MAGIC_PREFIX: if data[:9] != MON_MAGIC_PREFIX:
sys.exit(f"error: bad magic; expected '\\x08MONOTONE', got {data[:9]!r}") sys.exit(f"error: bad magic; expected '\\x08MONOTONE', got {data[:9]!r}")
song_len = data[0x5C] # NOTE: data[0x5C] is totalPatterns (the count of stored pattern blocks),
# NOT the order-list length — see TMTSongFileHeader in MT_SONG.PAS. It must
# not be used to bound the order list.
total_patterns = data[0x5C]
num_voices = data[0x5D] num_voices = data[0x5D]
if num_voices < 1 or num_voices > 12: if num_voices < 1 or num_voices > 12:
sys.exit(f"error: invalid voice count {num_voices} (expected 1..12)") sys.exit(f"error: invalid voice count {num_voices} (expected 1..12)")
order_raw = data[0x5F:0x15F] order_raw = data[0x5F:0x15F]
# Effective order list: take first song_len entries and drop 0xFF skip-slots # The order list is contiguous from index 0 and terminated by the first
# (matches mtreader.lua and MT_PLAY.PAS' "ignore 0xFF" semantics). # 0xFF ("FF = end of song", MT_SONG.PAS line 156 / MT_PLAY.PAS lines 677-683:
order_list = [b for b in order_raw[:song_len] if b != 0xFF] # the player advances the order pointer and stops the moment the next order
# byte is 0xFF). The old code sliced order_raw[:totalPatterns], which dropped
# the tail whenever the song was longer than its pattern count — e.g. a
# repeated outro pattern — the "last order ignored" bug.
order_list = []
for b in order_raw:
if b == 0xFF:
break
order_list.append(b)
if not order_list: if not order_list:
sys.exit("error: order list is empty after filtering 0xFF skip slots") sys.exit("error: order list is empty (first order is the 0xFF EOS marker)")
n_patterns = max(order_list) + 1 n_patterns = max(order_list) + 1
pattern_size = MON_PATTERN_ROWS * num_voices * MON_CELL_BYTES pattern_size = MON_PATTERN_ROWS * num_voices * MON_CELL_BYTES
@@ -123,7 +134,7 @@ def parse_mon(data: bytes):
patterns.append(grid) patterns.append(grid)
return { return {
'song_len': song_len, 'total_patterns': total_patterns,
'num_voices': num_voices, 'num_voices': num_voices,
'order_list': order_list, 'order_list': order_list,
'n_patterns': n_patterns, 'n_patterns': n_patterns,
@@ -541,7 +552,7 @@ def main():
vprint(f"parsing '{args.input}' ({len(data)} bytes)…") vprint(f"parsing '{args.input}' ({len(data)} bytes)…")
mon = parse_mon(data) mon = parse_mon(data)
vprint(f" songLen={mon['song_len']}, voices={mon['num_voices']}, " vprint(f" totalPatterns={mon['total_patterns']}, voices={mon['num_voices']}, "
f"patterns={mon['n_patterns']}, orders={len(mon['order_list'])}") f"patterns={mon['n_patterns']}, orders={len(mon['order_list'])}")
taud = assemble_taud(mon, with_project_data=not args.no_project_data) taud = assemble_taud(mon, with_project_data=not args.no_project_data)