aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authornotaz2011-09-22 22:38:12 +0300
committernotaz2011-09-22 22:38:12 +0300
commitbe1cb678c445cb8d9a4d707c698f0dc600a490ea (patch)
tree87866cb07ab328ff5dac41f83300f916834fc662 /plugins
parent7e44d49d2a65d6e45d6f99f72a8cccdb02654aae (diff)
downloadpcsx_rearmed-be1cb678c445cb8d9a4d707c698f0dc600a490ea.tar.gz
pcsx_rearmed-be1cb678c445cb8d9a4d707c698f0dc600a490ea.tar.bz2
pcsx_rearmed-be1cb678c445cb8d9a4d707c698f0dc600a490ea.zip
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).
Diffstat (limited to 'plugins')
-rw-r--r--plugins/dfsound/externals.h1
-rw-r--r--plugins/dfsound/freeze.c2
-rw-r--r--plugins/dfsound/registers.c5
-rw-r--r--plugins/dfsound/spu.c4
4 files changed, 11 insertions, 1 deletions
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h
index 4ce39bb..c9f20ca 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 6caa6bf..1c037fe 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<<ch));
d->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 2493a1e..669c70f 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<<ch); // bitfield for faster testing
dwChannelOn|=1<<ch;
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c
index 8c6f7d2..06cc476 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -485,6 +485,7 @@ static int decode_block(int ch)
}
s_chan[ch].pCurr = start; // store values for next cycle
+ s_chan[ch].bJump = flags & 1;
return ret;
}
@@ -503,13 +504,14 @@ static int skip_block(int ch)
}
if(flags & 4)
- s_chan[ch].pLoop=start;
+ s_chan[ch].pLoop = start;
s_chan[ch].pCurr += 16;
if(flags & 1)
s_chan[ch].pCurr = s_chan[ch].pLoop;
+ s_chan[ch].bJump = flags & 1;
return ret;
}