#!/usr/bin/env python3
"""Reproduce the selected PCM asset from jdc's supplied Twin Cobra USA ZIP.
No ROM is fetched or published. Normal NHL builds use the checked-in 4497-byte
PCM asset offline and never require this source ROM.
"""
from pathlib import Path
import argparse,hashlib,zipfile

ROM_SHA='23c1dd768c455067ad614c6c054db59176b0bda0f6531fff56da023e224cd512'
PCM_SHA='ce014d721f2022444e19bcc8617f34fd79e2f16b6938745f8e3fdcaa4d456240'


def extract(rom):
    assert hashlib.sha256(rom).hexdigest()==ROM_SHA,'unexpected Twin Cobra ROM'
    z=rom[0x9e000:];entry=0x120+13*8
    start=int.from_bytes(z[entry:entry+2],'little')
    count=int.from_bytes(z[entry+2:entry+4],'little')
    assert (start,count,z[entry+4])==(0x1298,4496,48)
    # Original driver outputs high nibble then low nibble to YM2612 DAC.
    # NHL uses zero as its sample terminator: change DAC0 to DAC1 only.
    pcm=bytes(max(1,((z[start+i//2]>>(4 if i%2==0 else 0))&15)*16)
              for i in range(count))+b'\0'
    assert hashlib.sha256(pcm).hexdigest()==PCM_SHA
    return pcm


def main():
    ap=argparse.ArgumentParser(description=__doc__);ap.add_argument('source_zip',type=Path)
    ap.add_argument('output_pcm',type=Path);args=ap.parse_args()
    with zipfile.ZipFile(args.source_zip) as archive:
        names=[n for n in archive.namelist() if n.lower().endswith(('.md','.bin','.gen'))]
        assert len(names)==1
        pcm=extract(archive.read(names[0]))
    args.output_pcm.parent.mkdir(parents=True,exist_ok=True);args.output_pcm.write_bytes(pcm)
    print(PCM_SHA)


if __name__=='__main__':main()
