From 4bf4be1ea26c3da3cc914e29f667a99fc35bdadd Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 22 Jun 2022 21:55:31 +0700 Subject: [PATCH] Fix 16-bit samples in YMZ280B VGM export --- src/engine/sample.h | 1 + src/engine/vgmOps.cpp | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/engine/sample.h b/src/engine/sample.h index d9ad633c9..70f8418cf 100644 --- a/src/engine/sample.h +++ b/src/engine/sample.h @@ -248,6 +248,7 @@ struct DivSample { offQSound(0), offX1_010(0), offSU(0), + offYMZ280B(0), offRF5C68(0), samples(0) {} ~DivSample(); diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 6e2bc82cf..0d1ad4f52 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -1653,13 +1653,34 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) { w->write(writeX1010[i]->getSampleMem(),writeX1010[i]->getSampleMemUsage()); } if (writeZ280[i]!=NULL && writeZ280[i]->getSampleMemUsage()>0) { + // In VGM, YMZ280B's 16-bit PCM has an endianness swapped + // which have been fixed in the upstream MAME since 2013 + // in order to get Konami FireBeat working + // The reason given for VGM not applying this change was + // "It matches OPL4 and MAME probably did an endianness optimization" + size_t sampleMemLen=writeZ280[i]->getSampleMemUsage(); + unsigned char* sampleMem=new unsigned char[sampleMemLen]; + memcpy(sampleMem,writeZ280[i]->getSampleMem(),sampleMemLen); + for (int i=0; idepth==16) { + unsigned int pos=s->offYMZ280B; + for (unsigned int j=0; jsamples; j++) { + unsigned char lo=sampleMem[pos+j*2]; + unsigned char hi=sampleMem[pos+j*2+1]; + sampleMem[pos+j*2]=hi; + sampleMem[pos+j*2+1]=lo; + } + } + } w->writeC(0x67); w->writeC(0x66); w->writeC(0x86); w->writeI((writeZ280[i]->getSampleMemUsage()+8)|(i*0x80000000)); w->writeI(writeZ280[i]->getSampleMemCapacity()); w->writeI(0); - w->write(writeZ280[i]->getSampleMem(),writeZ280[i]->getSampleMemUsage()); + w->write(sampleMem,sampleMemLen); + delete[] sampleMem; } }