diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 50b44254..96319afc 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1973,9 +1973,18 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write break; case DIV_SYSTEM_ARCADE: case DIV_SYSTEM_YM2151: - w->writeC(0x54); - w->writeC(write.addr&0xff); - w->writeC(write.val); + switch (write.addr>>16) { + case 0: // YM2151 + w->writeC(0x54); + w->writeC(write.addr&0xff); + w->writeC(write.val); + break; + case 1: // SegaPCM + w->writeC(0xc0); + w->writeS(write.addr&0xffff); + w->writeC(write.val); + break; + } break; case DIV_SYSTEM_YM2610: switch (write.addr>>8) { @@ -2267,14 +2276,52 @@ SafeWriter* DivEngine::saveVGM() { } if (writeSegaPCM) { - // TODO + unsigned char* pcmMem=new unsigned char[16777216]; + + size_t memPos=0; + for (int i=0; irendOffP=memPos; + unsigned int alignedSize=(sample->rendLength+0xff)&(~0xff); + if (alignedSize>65536) alignedSize=65536; + if (sample->depth==8) { + for (unsigned int j=0; j=sample->rendLength) { + pcmMem[memPos++]=0; + } else { + pcmMem[memPos++]=((unsigned char)sample->rendData[j]); + } + if (memPos>=16777216) break; + } + } else { + for (unsigned int j=0; j=sample->rendLength) { + pcmMem[memPos++]=0; + } else { + pcmMem[memPos++]=(((unsigned short)sample->rendData[j])>>8); + } + if (memPos>=16777216) break; + } + } + if (memPos>=16777216) break; + } + + w->writeC(0x67); + w->writeC(0x66); + w->writeC(0x80); + w->writeI(memPos+8); + w->writeI(memPos); + w->writeI(0); + w->write(pcmMem,memPos); + + delete[] pcmMem; } if (writeADPCM && adpcmMemLen>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x82); - w->writeI(adpcmMemLen); + w->writeI(adpcmMemLen+8); w->writeI(adpcmMemLen); w->writeI(0); w->write(adpcmMem,adpcmMemLen); diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 33d777d3..d6cdb402 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -241,6 +241,11 @@ int DivPlatformArcade::dispatch(DivCommand c) { chan[c.chan].baseFreq=c.value<<6; chan[c.chan].freqChanged=true; chan[c.chan].furnacePCM=true; + if (dumpWrites) { // Sega PCM writes + DivSample* s=parent->song.sample[chan[c.chan].pcm.sample]; + // TODO: THIS!!! + addWrite(0x10084,s->rendOffP); + } } else { chan[c.chan].pcm.sample=12*sampleBank+c.value%12; if (chan[c.chan].pcm.sample>=parent->song.sampleLen) { diff --git a/src/engine/sample.h b/src/engine/sample.h index da337a49..03538557 100644 --- a/src/engine/sample.h +++ b/src/engine/sample.h @@ -6,7 +6,7 @@ struct DivSample { signed char vol, pitch; unsigned char depth; short* data; - unsigned int rendLength, adpcmRendLength, rendOff; + unsigned int rendLength, adpcmRendLength, rendOff, rendOffP; short* rendData; unsigned char* adpcmRendData; @@ -23,6 +23,7 @@ struct DivSample { rendLength(0), adpcmRendLength(0), rendOff(0), + rendOffP(0), rendData(NULL), adpcmRendData(NULL) {} ~DivSample();