From d3c6d53819e9234e1929b230694d5fe814bafef7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 2 Mar 2023 01:11:02 -0500 Subject: [PATCH] SegaPCM: truly fix sample loop issue #1005 --- src/engine/platform/segapcm.cpp | 23 +++++++++++++---------- src/engine/platform/segapcm.h | 1 + 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index ee097abc6..b96e4452c 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -136,11 +136,12 @@ void DivPlatformSegaPCM::tick(bool sysTick) { rWrite(0x86+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); - rWrite(6+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-2)>>8)); + rWrite(6+(i<<3),sampleEndSegaPCM[chan[i].pcm.sample]); if (loopStart<0 || loopStart>=actualLength) { rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); } else { int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart; + logV("sampleOff: %x loopPos: %x",sampleOffSegaPCM[chan[i].pcm.sample],loopPos); rWrite(4+(i<<3),loopPos&0xff); rWrite(5+(i<<3),(loopPos>>8)&0xff); rWrite(0x86+(i<<3),((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); @@ -153,7 +154,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) { rWrite(0x86+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); - rWrite(6+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-2)>>8)); + rWrite(6+(i<<3),sampleEndSegaPCM[chan[i].pcm.sample]); if (loopStart<0 || loopStart>=actualLength) { rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); } else { @@ -450,16 +451,18 @@ void DivPlatformSegaPCM::reset() { memset(sampleMem,0,16777216); memset(sampleLoaded,0,256*sizeof(bool)); + memset(sampleOffSegaPCM,0,256*sizeof(unsigned int)); + memset(sampleEndSegaPCM,0,256); for (int i=0; isong.sampleLen; i++) { DivSample* sample=parent->getSample(i); - unsigned int alignedSize=(sample->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)+0xff)&(~0xff); - if (alignedSize>65536) alignedSize=65536; - if ((memPos&0xff0000)!=((memPos+alignedSize)&0xff0000)) { - memPos=(memPos+0xffff)&0xff0000; + unsigned int alignedSize=sample->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT); + if (alignedSize>=65279) alignedSize=65279; + if ((memPos&(~0xffff))!=((memPos+alignedSize)&(~0xffff))) { + memPos=(memPos+0xffff)&(~0xffff); } - if (alignedSize&(~0xff)) { - memPos+=256-(alignedSize&0xff); + if (alignedSize&0xff) { + memPos=((memPos+255)&(~0xff))+256-(alignedSize&0xff); } logV("- sample %d will be at %x with length %x",i,memPos,alignedSize); sampleLoaded[i]=true; @@ -467,11 +470,11 @@ void DivPlatformSegaPCM::reset() { sampleOffSegaPCM[i]=memPos; for (unsigned int j=0; jdata8[j]+0x80); + sampleEndSegaPCM[i]=((memPos+0xff)>>8)-1; if (memPos>=16777216) break; } + logV(" and it ends in %d",sampleEndSegaPCM[i]); if (memPos>=16777216) break; - - memPos&=~0xff; } sampleMemLen=memPos; } diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index 4dd541e76..f99a24df3 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -76,6 +76,7 @@ class DivPlatformSegaPCM: public DivDispatch { short pendingWrites[256]; unsigned int sampleOffSegaPCM[256]; + unsigned char sampleEndSegaPCM[256]; bool sampleLoaded[256]; friend void putDispatchChip(void*,int);