aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfsound
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/dfsound')
-rw-r--r--plugins/dfsound/externals.h1
-rw-r--r--plugins/dfsound/freeze.c2
-rw-r--r--plugins/dfsound/registers.c2
-rw-r--r--plugins/dfsound/spu.c36
4 files changed, 26 insertions, 15 deletions
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h
index c69af81..5d72002 100644
--- a/plugins/dfsound/externals.h
+++ b/plugins/dfsound/externals.h
@@ -227,6 +227,7 @@ extern int bSpuInit;
extern unsigned int dwNewChannel;
extern unsigned int dwChannelOn;
extern unsigned int dwPendingChanOff;
+extern unsigned int dwChannelDead;
extern int SSumR[];
extern int SSumL[];
diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c
index 41c6f16..d09a9b0 100644
--- a/plugins/dfsound/freeze.c
+++ b/plugins/dfsound/freeze.c
@@ -315,6 +315,7 @@ void LoadStateV5(SPUFreeze_t * pF)
dwNewChannel=0;
dwChannelOn=0;
+ dwChannelDead=0;
for(i=0;i<MAXCHAN;i++)
{
load_channel(&s_chan[i],&pFO->s_chan[i],i);
@@ -341,6 +342,7 @@ void LoadStateUnknown(SPUFreeze_t * pF)
dwNewChannel=0;
dwChannelOn=0;
+ dwChannelDead=0;
pSpuIrq=0;
for(i=0;i<0xc0;i++)
diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c
index 83b9e43..f6c3058 100644
--- a/plugins/dfsound/registers.c
+++ b/plugins/dfsound/registers.c
@@ -169,6 +169,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val)
s_chan[ch].pLoop=spuMemC+((unsigned long)((val<<3)&~0xf));
//s_chan[ch].bIgnoreLoop=1;
//ReleaseMutex(s_chan[ch].hMutex); // -> oki, on with the thread
+ dwChannelDead&=~(1<<ch);
break;
//------------------------------------------------//
}
@@ -429,6 +430,7 @@ void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND
dwNewChannel|=(1<<ch); // bitfield for faster testing
dwChannelOn|=1<<ch;
+ dwChannelDead&=~(1<<ch);
}
}
}
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c
index bea8414..b866cff 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -108,9 +108,10 @@ int bSPUIsOpen=0;
static pthread_t thread = (pthread_t)-1; // thread id (linux)
-unsigned long dwNewChannel=0; // flags for faster testing, if new channel starts
-unsigned long dwChannelOn=0;
-unsigned long dwPendingChanOff=0;
+unsigned int dwNewChannel=0; // flags for faster testing, if new channel starts
+unsigned int dwChannelOn=0; // not silent channels
+unsigned int dwPendingChanOff=0;
+unsigned int dwChannelDead=0; // silent+not useful channels
void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq
void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0;
@@ -453,14 +454,12 @@ static int decode_block(int ch)
int ret = 0;
start=s_chan[ch].pCurr; // set up the current pos
- if(start == (unsigned char*)-1 || // special "stop" sign
- (dwPendingChanOff&(1<<ch)))
+ if(dwPendingChanOff&(1<<ch))
{
dwChannelOn&=~(1<<ch); // -> turn everything off
dwPendingChanOff&=~(1<<ch);
s_chan[ch].bStop=1;
s_chan[ch].ADSRX.EnvelopeVol=0;
- return 0; // -> and done for this channel
}
//////////////////////////////////////////// irq check
@@ -495,8 +494,11 @@ static int decode_block(int ch)
start = s_chan[ch].pLoop;
}
- if (start - spuMemC >= 0x80000)
- start = (unsigned char*)-1;
+ if (start - spuMemC >= 0x80000) {
+ // most likely wrong
+ start = spuMemC;
+ printf("ch%d oflow\n", ch);
+ }
s_chan[ch].pCurr = start; // store values for next cycle
@@ -697,7 +699,7 @@ static void *MAINThread(void *arg)
{
int volmult = iVolume;
int ns,ns_from,ns_to;
- int ch,d;
+ int ch,d,silentch;
int bIRQReturn=0;
while(!bEndThread) // until we are shutting down
@@ -737,6 +739,8 @@ static void *MAINThread(void *arg)
ch=lastch; ns_from=lastns; lastch=-1; // -> setup all kind of vars to continue
}
+ silentch=~(dwChannelOn|dwNewChannel);
+
//--------------------------------------------------//
//- main channel loop -//
//--------------------------------------------------//
@@ -782,9 +786,8 @@ static void *MAINThread(void *arg)
if(!bIRQReturn && (spuCtrl&CTRL_IRQ))
for(ch=0;ch<MAXCHAN;ch++)
{
- if(dwChannelOn&(1<<ch)) continue; // already handled
- if(s_chan[ch].pCurr == (unsigned char *)-1)
- continue;
+ if(!(silentch&(1<<ch))) continue; // already handled
+ if(dwChannelDead&(1<<ch)) continue;
if(s_chan[ch].pCurr > pSpuIrq && s_chan[ch].pLoop > pSpuIrq)
continue;
@@ -801,7 +804,7 @@ static void *MAINThread(void *arg)
if(start == s_chan[ch].pCurr)
{
// looping on self
- s_chan[ch].pCurr=(unsigned char *)-1;
+ dwChannelDead|=1<<ch;
break;
}
@@ -1187,9 +1190,9 @@ char * SPUgetLibInfos(void)
*/
// debug
-void spu_get_debug_info(int *chans_out, int *fmod_chans_out, int *noise_chans_out)
+void spu_get_debug_info(int *chans_out, int *run_chans, int *fmod_chans_out, int *noise_chans_out)
{
- int ch = 0, fmod_chans = 0, noise_chans = 0;
+ int ch = 0, fmod_chans = 0, noise_chans = 0, irq_chans = 0;
for(;ch<MAXCHAN;ch++)
{
@@ -1199,9 +1202,12 @@ void spu_get_debug_info(int *chans_out, int *fmod_chans_out, int *noise_chans_ou
fmod_chans |= 1 << ch;
if (s_chan[ch].bNoise)
noise_chans |= 1 << ch;
+ if((spuCtrl&CTRL_IRQ) && s_chan[ch].pCurr <= pSpuIrq && s_chan[ch].pLoop <= pSpuIrq)
+ irq_chans |= 1 << ch;
}
*chans_out = dwChannelOn;
+ *run_chans = ~dwChannelOn & ~dwChannelDead & irq_chans;
*fmod_chans_out = fmod_chans;
*noise_chans_out = noise_chans;
}