From be1cb678c445cb8d9a4d707c698f0dc600a490ea Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 22 Sep 2011 22:38:12 +0300 Subject: [PATCH 1/1] spu: handle loop write vs loop flag race (bIgnoreLoop alternative) it feels this should be better, but shouldn't write much here without testing really (Heart of Darkness). --- plugins/dfsound/externals.h | 1 + plugins/dfsound/freeze.c | 2 ++ plugins/dfsound/registers.c | 5 +++++ plugins/dfsound/spu.c | 4 +++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h index 4ce39bb8..c9f20ca8 100644 --- a/plugins/dfsound/externals.h +++ b/plugins/dfsound/externals.h @@ -115,6 +115,7 @@ typedef struct unsigned int bRVBActive:1; // reverb active flag unsigned int bNoise:1; // noise active flag unsigned int bFMod:2; // freq mod (0=off, 1=sound channel, 2=freq channel) + unsigned int bJump:1; // last decoded block jumped int iLeftVolume; // left volume int iRightVolume; // right volume diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 6caa6bf8..1c037fe1 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -134,6 +134,7 @@ static void save_channel(SPUCHAN_orig *d, const SPUCHAN *s, int ch) d->bOn = !!(dwChannelOn & (1<bStop = s->bStop; d->bReverb = s->bReverb; + d->bIgnoreLoop = s->bJump; d->iActFreq = 1; d->iUsedFreq = 2; d->iLeftVolume = s->iLeftVolume; @@ -178,6 +179,7 @@ static void load_channel(SPUCHAN *d, const SPUCHAN_orig *s, int ch) d->bRVBActive = s->bRVBActive; d->bNoise = s->bNoise; d->bFMod = s->bFMod; + d->bJump = s->bIgnoreLoop; d->ADSRX.State = s->ADSRX.State; d->ADSRX.AttackModeExp = s->ADSRX.AttackModeExp; d->ADSRX.AttackRate = s->ADSRX.AttackRate; diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 2493a1e5..669c70f7 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -173,6 +173,10 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) //------------------------------------------------// case 14: // loop? s_chan[ch].pLoop=spuMemC+((val&~1)<<3); + if(s_chan[ch].bJump) + // real machine would be most likely still doing the last block and use new value for the jump; + // but we decode ahead a bit and already did the jump part, so compensate for that now. + s_chan[ch].pCurr=s_chan[ch].pLoop; break; //------------------------------------------------// } @@ -429,6 +433,7 @@ static void SoundOn(int start,int end,unsigned short val) s_chan[ch].bStop=0; s_chan[ch].pCurr=spuMemC+((regAreaGet(ch,6)&~1)<<3); // must be block aligned s_chan[ch].pLoop=spuMemC+((regAreaGet(ch,14)&~1)<<3); + s_chan[ch].bJump=0; dwNewChannel|=(1<