diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-06-27 21:33:12 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-06-27 21:33:12 +0200 |
commit | e8eba665eaa2befeab7edc54646dc5cd02b6e472 (patch) | |
tree | c5a5c139be147592a756eb324289ba56351f8b08 /plugins | |
parent | 775c6bc9a480a58abacef77018dda5391d4d363a (diff) |
ao psf2 spu reentrancy
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/ao/eng_psf/eng_psf2.c | 6 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/adsr2.c | 196 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/dma.h | 4 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/dma2.c | 67 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/externals.h | 674 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/registers2.c | 718 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/regs.h | 21 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/reverb2.c | 180 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/spu.h | 140 | ||||
-rw-r--r-- | plugins/ao/eng_psf/peops2/spu2.c | 559 |
10 files changed, 1265 insertions, 1300 deletions
diff --git a/plugins/ao/eng_psf/eng_psf2.c b/plugins/ao/eng_psf/eng_psf2.c index 2da270b9..7ed1ac3a 100644 --- a/plugins/ao/eng_psf/eng_psf2.c +++ b/plugins/ao/eng_psf/eng_psf2.c @@ -83,8 +83,6 @@ typedef struct { char *spu_pOutput; } psf2_synth_t; -extern void setlength2(int32 stop, int32 fade); - void ps2_update(unsigned char *pSound, long lBytes, void *data) { psf2_synth_t *s = data; @@ -556,7 +554,6 @@ void *psf2_start(uint8 *buffer, uint32 length) { lengthMS = ~0; } - setlength2(lengthMS, fadeMS); mipsinfo.i = s->initialPC; mips_set_info(s->mips_cpu, CPUINFO_INT_PC, &mipsinfo); @@ -588,6 +585,7 @@ void *psf2_start(uint8 *buffer, uint32 length) psx_hw_init(s->mips_cpu); SPU2init(s->mips_cpu, ps2_update, s); SPU2open(s->mips_cpu, NULL); + setlength2(s->mips_cpu->spu2, lengthMS, fadeMS); return s; } @@ -672,7 +670,7 @@ int32 psf2_command(void *handle, int32 command, int32 parameter) { lengthMS = ~0; } - setlength2(lengthMS, fadeMS); + setlength2(s->mips_cpu->spu2, lengthMS, fadeMS); return AO_SUCCESS; diff --git a/plugins/ao/eng_psf/peops2/adsr2.c b/plugins/ao/eng_psf/peops2/adsr2.c index 442cc38f..470069c6 100644 --- a/plugins/ao/eng_psf/peops2/adsr2.c +++ b/plugins/ao/eng_psf/peops2/adsr2.c @@ -66,148 +66,148 @@ void InitADSR(void) // INIT ADSR ////////////////////////////////////////////////////////////////////////
-INLINE void StartADSR(int ch) // MIX ADSR
+INLINE void StartADSR(spu2_state_t *spu, int ch) // MIX ADSR
{
- s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
- s_chan[ch].ADSRX.State=0;
- s_chan[ch].ADSRX.EnvelopeVol=0;
+ spu->s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars
+ spu->s_chan[ch].ADSRX.State=0;
+ spu->s_chan[ch].ADSRX.EnvelopeVol=0;
}
////////////////////////////////////////////////////////////////////////
-INLINE int MixADSR(int ch) // MIX ADSR
+INLINE int MixADSR(spu2_state_t *spu, int ch) // MIX ADSR
{
- if(s_chan[ch].bStop) // should be stopped:
+ if(spu->s_chan[ch].bStop) // should be stopped:
{ // do release
- if(s_chan[ch].ADSRX.ReleaseModeExp)
+ if(spu->s_chan[ch].ADSRX.ReleaseModeExp)
{
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ switch((spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
{
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;
+ case 0: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;
+ case 1: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;
+ case 2: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;
+ case 3: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;
+ case 4: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;
+ case 5: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;
+ case 6: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;
+ case 7: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;
}
}
else
{
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];
}
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0)
{
- s_chan[ch].ADSRX.EnvelopeVol=0;
- s_chan[ch].bOn=0;
- //s_chan[ch].bReverb=0;
- //s_chan[ch].bNoise=0;
+ spu->s_chan[ch].ADSRX.EnvelopeVol=0;
+ spu->s_chan[ch].bOn=0;
+ //spu->s_chan[ch].bReverb=0;
+ //spu->s_chan[ch].bNoise=0;
}
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
+ spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return spu->s_chan[ch].ADSRX.lVolume;
}
else // not stopped yet?
{
- if(s_chan[ch].ADSRX.State==0) // -> attack
+ if(spu->s_chan[ch].ADSRX.State==0) // -> attack
{
- if(s_chan[ch].ADSRX.AttackModeExp)
+ if(spu->s_chan[ch].ADSRX.AttackModeExp)
{
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];
}
else
{
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];
}
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0)
{
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
- s_chan[ch].ADSRX.State=1;
+ spu->s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ spu->s_chan[ch].ADSRX.State=1;
}
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
+ spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return spu->s_chan[ch].ADSRX.lVolume;
}
//--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==1) // -> decay
+ if(spu->s_chan[ch].ADSRX.State==1) // -> decay
{
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ switch((spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
{
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;
+ case 0: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;
+ case 1: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;
+ case 2: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;
+ case 3: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;
+ case 4: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;
+ case 5: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;
+ case 6: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;
+ case 7: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;
}
- if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;
- if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) spu->s_chan[ch].ADSRX.EnvelopeVol=0;
+ if(((spu->s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= spu->s_chan[ch].ADSRX.SustainLevel)
{
- s_chan[ch].ADSRX.State=2;
+ spu->s_chan[ch].ADSRX.State=2;
}
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
+ spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return spu->s_chan[ch].ADSRX.lVolume;
}
//--------------------------------------------------//
- if(s_chan[ch].ADSRX.State==2) // -> sustain
+ if(spu->s_chan[ch].ADSRX.State==2) // -> sustain
{
- if(s_chan[ch].ADSRX.SustainIncrease)
+ if(spu->s_chan[ch].ADSRX.SustainIncrease)
{
- if(s_chan[ch].ADSRX.SustainModeExp)
+ if(spu->s_chan[ch].ADSRX.SustainModeExp)
{
- if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0x60000000)
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
else
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];
}
else
{
- s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];
}
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0)
{
- s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
+ spu->s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;
}
}
else
{
- if(s_chan[ch].ADSRX.SustainModeExp)
+ if(spu->s_chan[ch].ADSRX.SustainModeExp)
{
- switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
+ switch((spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)
{
- case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;
- case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;
- case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;
- case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;
- case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;
- case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;
- case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;
- case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;
+ case 0: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;
+ case 1: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;
+ case 2: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;
+ case 3: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;
+ case 4: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;
+ case 5: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;
+ case 6: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;
+ case 7: spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;
}
}
else
{
- s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
+ spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];
}
- if(s_chan[ch].ADSRX.EnvelopeVol<0)
+ if(spu->s_chan[ch].ADSRX.EnvelopeVol<0)
{
- s_chan[ch].ADSRX.EnvelopeVol=0;
+ spu->s_chan[ch].ADSRX.EnvelopeVol=0;
}
}
- s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21;
- return s_chan[ch].ADSRX.lVolume;
+ spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21;
+ return spu->s_chan[ch].ADSRX.lVolume;
}
}
return 0;
@@ -435,45 +435,45 @@ every one millisecond long v,v2,lT,l1,l2,l3;
- if(s_chan[ch].bStop) // psx wants to stop? -> release phase
+ if(spu->s_chan[ch].bStop) // psx wants to stop? -> release phase
{
- if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
+ if(spu->s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now)
{
- if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
+ if(!spu->s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff
{
- s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime;
- s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume;
- s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
- (s_chan[ch].ADSR.ReleaseTime*
- s_chan[ch].ADSR.ReleaseVol)/1024;
+ spu->s_chan[ch].ADSR.ReleaseStartTime=spu->s_chan[ch].ADSR.lTime;
+ spu->s_chan[ch].ADSR.ReleaseVol=spu->s_chan[ch].ADSR.lVolume;
+ spu->s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level
+ (spu->s_chan[ch].ADSR.ReleaseTime*
+ spu->s_chan[ch].ADSR.ReleaseVol)/1024;
}
// -> NO release exp mode used (yet)
- v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume
- lT=s_chan[ch].ADSR.lTime- // -> how much time is past?
- s_chan[ch].ADSR.ReleaseStartTime;
- l1=s_chan[ch].ADSR.ReleaseTime;
+ v=spu->s_chan[ch].ADSR.ReleaseVol; // -> get last volume
+ lT=spu->s_chan[ch].ADSR.lTime- // -> how much time is past?
+ spu->s_chan[ch].ADSR.ReleaseStartTime;
+ l1=spu->s_chan[ch].ADSR.ReleaseTime;
if(lT<l1) // -> we still have to release
{
v=v-((v*lT)/l1); // --> calc new volume
}
else // -> release is over: now really stop that sample
- {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+ {v=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0;}
}
else // -> release IS 0: release at once
{
- v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;
+ v=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0;
}
}
else
{//--------------------------------------------------// not in release phase:
v=1024;
- lT=s_chan[ch].ADSR.lTime;
- l1=s_chan[ch].ADSR.AttackTime;
+ lT=spu->s_chan[ch].ADSR.lTime;
+ l1=spu->s_chan[ch].ADSR.AttackTime;
if(lT<l1) // attack
{ // no exp mode used (yet)
-// if(s_chan[ch].ADSR.AttackModeExp)
+// if(spu->s_chan[ch].ADSR.AttackModeExp)
// {
// v=(v*lT)/l1;
// }
@@ -485,8 +485,8 @@ every one millisecond }
else // decay
{ // should be exp, but who cares? ;)
- l2=s_chan[ch].ADSR.DecayTime;
- v2=s_chan[ch].ADSR.SustainLevel;
+ l2=spu->s_chan[ch].ADSR.DecayTime;
+ v2=spu->s_chan[ch].ADSR.SustainLevel;
lT-=l1;
if(lT<l2)
@@ -495,9 +495,9 @@ every one millisecond }
else // sustain
{ // no exp mode used (yet)
- l3=s_chan[ch].ADSR.SustainTime;
+ l3=spu->s_chan[ch].ADSR.SustainTime;
lT-=l2;
- if(s_chan[ch].ADSR.SustainModeDec>0)
+ if(spu->s_chan[ch].ADSR.SustainModeDec>0)
{
if(l3!=0) v2+=((v-v2)*lT)/l3;
else v2=v;
@@ -509,7 +509,7 @@ every one millisecond }
if(v2>v) v2=v;
- if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;}
+ if(v2<=0) {v2=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0;}
v=v2;
}
@@ -519,11 +519,11 @@ every one millisecond //----------------------------------------------------//
// ok, done for this channel, so increase time
- s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
+ spu->s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms;
if(v>1024) v=1024; // adjust volume
if(v<0) v=0;
- s_chan[ch].ADSR.lVolume=v; // store act volume
+ spu->s_chan[ch].ADSR.lVolume=v; // store act volume
return v; // return the volume factor
*/
diff --git a/plugins/ao/eng_psf/peops2/dma.h b/plugins/ao/eng_psf/peops2/dma.h index e11ece6d..8a68a24a 100644 --- a/plugins/ao/eng_psf/peops2/dma.h +++ b/plugins/ao/eng_psf/peops2/dma.h @@ -24,6 +24,6 @@ //
//*************************************************************************//
-void InterruptDMA4(void);
-void InterruptDMA7(void);
+void InterruptDMA4(mips_cpu_context *cpu);
+void InterruptDMA7(mips_cpu_context *cpu);
diff --git a/plugins/ao/eng_psf/peops2/dma2.c b/plugins/ao/eng_psf/peops2/dma2.c index 2d07c059..6c977429 100644 --- a/plugins/ao/eng_psf/peops2/dma2.c +++ b/plugins/ao/eng_psf/peops2/dma2.c @@ -35,6 +35,7 @@ #include "../peops2/registers.h" //#include "debug.h" #include "../psx.h" +#include "../peops2/spu.h" //extern uint32 psx_ram[(2*1024*1024)/4]; @@ -44,47 +45,49 @@ EXPORT_GCC void CALLBACK SPU2readDMA4Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) { + spu2_state_t *spu = cpu->spu2; int i; u16 *ram16 = (u16 *)&cpu->psx_ram[0]; for(i=0;i<iSize;i++) { - ram16[usPSXMem>>1]=spuMem[spuAddr2[0]]; // spu addr 0 got by writeregister + ram16[usPSXMem>>1]=spu->spuMem[spu->spuAddr2[0]]; // spu addr 0 got by writeregister usPSXMem+=2; - spuAddr2[0]++; // inc spu addr - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap + spu->spuAddr2[0]++; // inc spu addr + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; // wrap } - spuAddr2[0]+=0x20; //????? + spu->spuAddr2[0]+=0x20; //????? - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; // got from J.F. and Kanodin... is it needed? - regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete - spuStat2[0]=0x80; // DMA complete + spu->regArea[(PS2_C0_ADMAS)>>1]=0; // Auto DMA complete + spu->spuStat2[0]=0x80; // DMA complete } EXPORT_GCC void CALLBACK SPU2readDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) { + spu2_state_t *spu = cpu->spu2; int i; u16 *ram16 = (u16 *)&cpu->psx_ram[0]; for(i=0;i<iSize;i++) { - ram16[usPSXMem>>1]=spuMem[spuAddr2[1]]; // spu addr 1 got by writeregister + ram16[usPSXMem>>1]=spu->spuMem[spu->spuAddr2[1]]; // spu addr 1 got by writeregister usPSXMem+=2; - spuAddr2[1]++; // inc spu addr - if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap + spu->spuAddr2[1]++; // inc spu addr + if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; // wrap } - spuAddr2[1]+=0x20; //????? + spu->spuAddr2[1]+=0x20; //????? - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; // got from J.F. and Kanodin... is it needed? - regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete - spuStat2[1]=0x80; // DMA complete + spu->regArea[(PS2_C1_ADMAS)>>1]=0; // Auto DMA complete + spu->spuStat2[1]=0x80; // DMA complete } //////////////////////////////////////////////////////////////////////// @@ -101,39 +104,41 @@ EXPORT_GCC void CALLBACK SPU2readDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,int EXPORT_GCC void CALLBACK SPU2writeDMA4Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) { + spu2_state_t *spu = cpu->spu2; int i; u16 *ram16 = (u16 *)&cpu->psx_ram[0]; for(i=0;i<iSize;i++) { - spuMem[spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister + spu->spuMem[spu->spuAddr2[0]] = ram16[usPSXMem>>1]; // spu addr 0 got by writeregister usPSXMem+=2; - spuAddr2[0]++; // inc spu addr - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; // wrap + spu->spuAddr2[0]++; // inc spu addr + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; // wrap } - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; // got from J.F. and Kanodin... is it needed? - spuStat2[0]=0x80; // DMA complete + spu->spuStat2[0]=0x80; // DMA complete } EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) { + spu2_state_t *spu = cpu->spu2; int i; u16 *ram16 = (u16 *)&cpu->psx_ram[0]; for(i=0;i<iSize;i++) { - spuMem[spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister - spuAddr2[1]++; // inc spu addr - if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; // wrap + spu->spuMem[spu->spuAddr2[1]] = ram16[usPSXMem>>1]; // spu addr 1 got by writeregister + spu->spuAddr2[1]++; // inc spu addr + if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; // wrap } - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; // got from J.F. and Kanodin... is it needed? - spuStat2[1]=0x80; // DMA complete + spu->spuStat2[1]=0x80; // DMA complete } //////////////////////////////////////////////////////////////////////// @@ -142,14 +147,15 @@ EXPORT_GCC void CALLBACK SPU2writeDMA7Mem(mips_cpu_context *cpu, u32 usPSXMem,in void InterruptDMA4(mips_cpu_context *cpu) { + spu2_state_t *spu = cpu->spu2; // taken from linuzappz NULL spu2 // spu2Rs16(CORE0_ATTR)&= ~0x30; // spu2Rs16(REG__1B0) = 0; // spu2Rs16(SPU2_STATX_WRDY_M)|= 0x80; - spuCtrl2[0]&=~0x30; - regArea[(PS2_C0_ADMAS)>>1]=0; - spuStat2[0]|=0x80; + spu->spuCtrl2[0]&=~0x30; + spu->regArea[(PS2_C0_ADMAS)>>1]=0; + spu->spuStat2[0]|=0x80; } EXPORT_GCC void CALLBACK SPU2interruptDMA4(mips_cpu_context *cpu) @@ -159,14 +165,15 @@ EXPORT_GCC void CALLBACK SPU2interruptDMA4(mips_cpu_context *cpu) void InterruptDMA7(mips_cpu_context *cpu) { + spu2_state_t *spu = cpu->spu2; // taken from linuzappz NULL spu2 // spu2Rs16(CORE1_ATTR)&= ~0x30; // spu2Rs16(REG__5B0) = 0; // spu2Rs16(SPU2_STATX_DREQ)|= 0x80; - spuCtrl2[1]&=~0x30; - regArea[(PS2_C1_ADMAS)>>1]=0; - spuStat2[1]|=0x80; + spu->spuCtrl2[1]&=~0x30; + spu->regArea[(PS2_C1_ADMAS)>>1]=0; + spu->spuStat2[1]|=0x80; } EXPORT_GCC void CALLBACK SPU2interruptDMA7(mips_cpu_context *cpu) diff --git a/plugins/ao/eng_psf/peops2/externals.h b/plugins/ao/eng_psf/peops2/externals.h index c916af67..67958149 100644 --- a/plugins/ao/eng_psf/peops2/externals.h +++ b/plugins/ao/eng_psf/peops2/externals.h @@ -1,375 +1,307 @@ -/***************************************************************************
- externals.h - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove@addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2004/04/04 - Pete
-// - changed plugin to emulate PS2 spu
-//
-// 2002/04/04 - Pete
-// - increased channel struct for interpolation
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
-
-#ifndef PEOPS2_EXTERNALS
-#define PEOPS2_EXTERNALS
-
-#include "ao.h"
-
-//#if LSB_FIRST
-//static INLINE u16 BFLIP16(u16 x)
-//{
-// return x;
-//}
-//#else
-//static INLINE u16 BFLIP16(u16 x)
-//{
-// return( ((x>>8)&0xFF)| ((x&0xFF)<<8) );
-//}
-//#endif
-
-/////////////////////////////////////////////////////////
-// generic defines
-/////////////////////////////////////////////////////////
-
-//#define PSE_LT_SPU 4
-//#define PSE_SPU_ERR_SUCCESS 0
-//#define PSE_SPU_ERR -60
-//#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1
-//#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2
-
-#ifndef max
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// spu defines
-////////////////////////////////////////////////////////////////////////
-
-// sound buffer sizes
-// 400 ms complete sound buffer
+/*************************************************************************** + externals.h - description + ------------------- + begin : Wed May 15 2002 + copyright : (C) 2002 by Pete Bernert + email : BlackDove@addcom.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +//*************************************************************************// +// History of changes: +// +// 2004/04/04 - Pete +// - changed plugin to emulate PS2 spu +// +// 2002/04/04 - Pete +// - increased channel struct for interpolation +// +// 2002/05/15 - Pete +// - generic cleanup for the Peops release +// +//*************************************************************************// + +#ifndef PEOPS2_EXTERNALS +#define PEOPS2_EXTERNALS + +#include "ao.h" + +//#if LSB_FIRST +//static INLINE u16 BFLIP16(u16 x) +//{ +// return x; +//} +//#else +//static INLINE u16 BFLIP16(u16 x) +//{ +// return( ((x>>8)&0xFF)| ((x&0xFF)<<8) ); +//} +//#endif + +///////////////////////////////////////////////////////// +// generic defines +///////////////////////////////////////////////////////// + +//#define PSE_LT_SPU 4 +//#define PSE_SPU_ERR_SUCCESS 0 +//#define PSE_SPU_ERR -60 +//#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1 +//#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2 + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +//////////////////////////////////////////////////////////////////////// +// spu defines +//////////////////////////////////////////////////////////////////////// + +// sound buffer sizes +// 400 ms complete sound buffer #define SOUNDSIZE 76800 -// 137 ms test buffer... if less than that is buffered, a new upload will happen
+// 137 ms test buffer... if less than that is buffered, a new upload will happen #define TESTSIZE 26304 -
-// num of channels
-#define MAXCHAN 48
-#define HLFCHAN 24
-
-// ~ 1 ms of data (was 45)
+ +// num of channels +#define MAXCHAN 48 +#define HLFCHAN 24 + +// ~ 1 ms of data (was 45) #define NSSIZE 1 -//45
-
-///////////////////////////////////////////////////////////
-// struct defines
-///////////////////////////////////////////////////////////
-
-// ADSR INFOS PER CHANNEL
-typedef struct
-{
- int AttackModeExp;
- long AttackTime;
- long DecayTime;
- long SustainLevel;
- int SustainModeExp;
- long SustainModeDec;
- long SustainTime;
- int ReleaseModeExp;
- unsigned long ReleaseVal;
- long ReleaseTime;
- long ReleaseStartTime;
- long ReleaseVol;
- long lTime;
- long lVolume;
-} ADSRInfo;
-
-typedef struct
-{
- int State;
- int AttackModeExp;
- int AttackRate;
- int DecayRate;
- int SustainLevel;
- int SustainModeExp;
- int SustainIncrease;
- int SustainRate;
- int ReleaseModeExp;
- int ReleaseRate;
- int EnvelopeVol;
- long lVolume;
- long lDummy1;
- long lDummy2;
-} ADSRInfoEx;
-
-///////////////////////////////////////////////////////////
-
-// Tmp Flags
-
-// used for debug channel muting
-#define FLAG_MUTE 1
-
-// used for simple interpolation
-#define FLAG_IPOL0 2
-#define FLAG_IPOL1 4
-
-///////////////////////////////////////////////////////////
-
-// MAIN CHANNEL STRUCT
-typedef struct
-{
- // no mutexes used anymore... don't need them to sync access
- //HANDLE hMutex;
-
- int bNew; // start flag
-
- int iSBPos; // mixing stuff
- int spos;
- int sinc;
- int SB[32+32]; // Pete added another 32 dwords in 1.6 ... prevents overflow issues with gaussian/cubic interpolation (thanx xodnizel!), and can be used for even better interpolations, eh? :)
- int sval;
-
- unsigned char * pStart; // start ptr into sound mem
- unsigned char * pCurr; // current pos in sound mem
- unsigned char * pLoop; // loop ptr in sound mem
-
- int iStartAdr;
- int iLoopAdr;
- int iNextAdr;
-
- int bOn; // is channel active (sample playing?)
- int bStop; // is channel stopped (sample _can_ still be playing, ADSR Release phase)
- int bEndPoint; // end point reached
- int bReverbL; // can we do reverb on this channel? must have ctrl register bit, to get active
- int bReverbR;
-
- int bVolumeL; // Volume on/off
- int bVolumeR;
-
- int iActFreq; // current psx pitch
- int iUsedFreq; // current pc pitch
- int iLeftVolume; // left volume
- int iLeftVolRaw; // left psx volume value
- int bIgnoreLoop; // ignore loop bit, if an external loop address is used
- int iMute; // mute mode
- int iRightVolume; // right volume
- int iRightVolRaw; // right psx volume value
- int iRawPitch; // raw pitch (0...3fff)
- int iIrqDone; // debug irq done flag
- int s_1; // last decoding infos
- int s_2;
- int bRVBActive; // reverb active flag
- int bNoise; // noise active flag
- int bFMod; // freq mod (0=off, 1=sound channel, 2=freq channel)
- int iOldNoise; // old noise val for this channel
- ADSRInfo ADSR; // active ADSR settings
- ADSRInfoEx ADSRX; // next ADSR settings (will be moved to active on sample start)
-
-} SPUCHAN;
-
-///////////////////////////////////////////////////////////
-
-typedef struct
-{
- int StartAddr; // reverb area start addr in samples
- int EndAddr; // reverb area end addr in samples
- int CurrAddr; // reverb area curr addr in samples
-
- int VolLeft;
- int VolRight;
- int iLastRVBLeft;
- int iLastRVBRight;
- int iRVBLeft;
- int iRVBRight;
- int iCnt;
-
- int FB_SRC_A; // (offset)
- int FB_SRC_B; // (offset)
- int IIR_ALPHA; // (coef.)
- int ACC_COEF_A; // (coef.)
- int ACC_COEF_B; // (coef.)
- int ACC_COEF_C; // (coef.)
- int ACC_COEF_D; // (coef.)
- int IIR_COEF; // (coef.)
- int FB_ALPHA; // (coef.)
- int FB_X; // (coef.)
- int IIR_DEST_A0; // (offset)
- int IIR_DEST_A1; // (offset)
- int ACC_SRC_A0; // (offset)
- int ACC_SRC_A1; // (offset)
- int ACC_SRC_B0; // (offset)
- int ACC_SRC_B1; // (offset)
- int IIR_SRC_A0; // (offset)
- int IIR_SRC_A1; // (offset)
- int IIR_DEST_B0; // (offset)
- int IIR_DEST_B1; // (offset)
- int ACC_SRC_C0; // (offset)
- int ACC_SRC_C1; // (offset)
- int ACC_SRC_D0; // (offset)
- int ACC_SRC_D1; // (offset)
- int IIR_SRC_B1; // (offset)
- int IIR_SRC_B0; // (offset)
- int MIX_DEST_A0; // (offset)
- int MIX_DEST_A1; // (offset)
- int MIX_DEST_B0; // (offset)
- int MIX_DEST_B1; // (offset)
- int IN_COEF_L; // (coef.)
- int IN_COEF_R; // (coef.)
-} REVERBInfo;
-
-#ifdef _WINDOWS
-//extern HINSTANCE hInst;
-//#define WM_MUTE (WM_USER+543)
-#endif
-
-///////////////////////////////////////////////////////////
-// SPU.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_SPU
-
-// psx buffers / addresses
-
-extern unsigned short regArea[];
-extern unsigned short spuMem[];
-extern unsigned char * spuMemC;
-extern unsigned char * pSpuIrq[];
-extern unsigned char * pSpuBuffer;
-
-// user settings
-
-extern int iUseXA;
-extern int iVolume;
-extern int iXAPitch;
-extern int iUseTimer;
-extern int iSPUIRQWait;
-extern int iDebugMode;
-extern int iRecordMode;
-extern int iUseReverb;
-extern int iUseInterpolation;
-extern int iDisStereo;
-// MISC
-
-extern SPUCHAN s_chan[];
-extern REVERBInfo rvb[];
-
-extern unsigned long dwNoiseVal;
-extern unsigned short spuCtrl2[];
-extern unsigned short spuStat2[];
-extern unsigned long spuIrq2[];
-extern unsigned long spuAddr2[];
-extern unsigned long spuRvbAddr2[];
-extern unsigned long spuRvbAEnd2[];
-
-extern int bEndThread;
-extern int bThreadEnded;
-extern int bSpuInit;
-
-extern int SSumR[];
-extern int SSumL[];
-extern int iCycle;
-extern short * pS;
-extern unsigned long dwNewChannel2[];
-extern unsigned long dwEndChannel2[];
-
-extern int iSpuAsyncWait;
-
-#ifdef _WINDOWS
-//extern HWND hWMain; // window handle
-//extern HWND hWDebug;
-#endif
-
-extern void (CALLBACK *cddavCallback)(unsigned short,unsigned short);
-
-#endif
-
-///////////////////////////////////////////////////////////
-// CFG.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_CFG
-
-#ifndef _WINDOWS
-extern char * pConfigFile;
-#endif
-
-#endif
-
-///////////////////////////////////////////////////////////
-// DSOUND.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_DSOUND
-
-#ifdef _WINDOWS
-extern unsigned long LastWrite;
-extern unsigned long LastPlay;
-#endif
-
-#endif
-
-///////////////////////////////////////////////////////////
-// RECORD.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_RECORD
-
-#ifdef _WINDOWS
-extern int iDoRecord;
-#endif
-
-#endif
-
-///////////////////////////////////////////////////////////
-// XA.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_XA
-
-extern xa_decode_t * xapGlobal;
-
-extern unsigned long * XAFeed;
-extern unsigned long * XAPlay;
-extern unsigned long * XAStart;
-extern unsigned long * XAEnd;
-
-extern unsigned long XARepeat;
-extern unsigned long XALastVal;
-
-extern int iLeftXAVol;
-extern int iRightXAVol;
-
-#endif
-
-///////////////////////////////////////////////////////////
-// REVERB.C globals
-///////////////////////////////////////////////////////////
-
-#ifndef _IN_REVERB
-
-extern int * sRVBPlay[];
-extern int * sRVBEnd[];
-extern int * sRVBStart[];
-
-#endif
-
+//45 + +/////////////////////////////////////////////////////////// +// struct defines +/////////////////////////////////////////////////////////// + +// ADSR INFOS PER CHANNEL +typedef struct +{ + int AttackModeExp; + long AttackTime; + long DecayTime; + long SustainLevel; + int SustainModeExp; + long SustainModeDec; + long SustainTime; + int ReleaseModeExp; + unsigned long ReleaseVal; + long ReleaseTime; + long ReleaseStartTime; + long ReleaseVol; + long lTime; + long lVolume; +} ADSRInfo; + +typedef struct +{ + int State; + int AttackModeExp; + int AttackRate; + int DecayRate; + int SustainLevel; + int SustainModeExp; + int SustainIncrease; + int SustainRate; + int ReleaseModeExp; + int ReleaseRate; + int EnvelopeVol; + long lVolume; + long lDummy1; + long lDummy2; +} ADSRInfoEx; + +/////////////////////////////////////////////////////////// + +// Tmp Flags + +// used for debug channel muting +#define FLAG_MUTE 1 + +// used for simple interpolation +#define FLAG_IPOL0 2 +#define FLAG_IPOL1 4 + +/////////////////////////////////////////////////////////// + +// MAIN CHANNEL STRUCT +typedef struct +{ + // no mutexes used anymore... don't need them to sync access + //HANDLE hMutex; + + int bNew; // start flag + + int iSBPos; // mixing stuff + int spos; + int sinc; + int SB[32+32]; // Pete added another 32 dwords in 1.6 ... prevents overflow issues with gaussian/cubic interpolation (thanx xodnizel!), and can be used for even better interpolations, eh? :) + int sval; + + unsigned char * pStart; // start ptr into sound mem + unsigned char * pCurr; // current pos in sound mem + unsigned char * pLoop; // loop ptr in sound mem + + int iStartAdr; + int iLoopAdr; + int iNextAdr; + + int bOn; // is channel active (sample playing?) + int bStop; // is channel stopped (sample _can_ still be playing, ADSR Release phase) + int bEndPoint; // end point reached + int bReverbL; // can we do reverb on this channel? must have ctrl register bit, to get active + int bReverbR; + + int bVolumeL; // Volume on/off + int bVolumeR; + + int iActFreq; // current psx pitch + int iUsedFreq; // current pc pitch + int iLeftVolume; // left volume + int iLeftVolRaw; // left psx volume value + int bIgnoreLoop; // ignore loop bit, if an external loop address is used + int iMute; // mute mode + int iRightVolume; // right volume + int iRightVolRaw; // right psx volume value + int iRawPitch; // raw pitch (0...3fff) + int iIrqDone; // debug irq done flag + int s_1; // last decoding infos + int s_2; + int bRVBActive; // reverb active flag + int bNoise; // noise active flag + int bFMod; // freq mod (0=off, 1=sound channel, 2=freq channel) + int iOldNoise; // old noise val for this channel + ADSRInfo ADSR; // active ADSR settings + ADSRInfoEx ADSRX; // next ADSR settings (will be moved to active on sample start) + +} SPUCHAN; + +/////////////////////////////////////////////////////////// + +typedef struct +{ + int StartAddr; // reverb area start addr in samples + int EndAddr; // reverb area end addr in samples + int CurrAddr; // reverb area curr addr in samples + + int VolLeft; + int VolRight; + int iLastRVBLeft; + int iLastRVBRight; + int iRVBLeft; + int iRVBRight; + int iCnt; + + int FB_SRC_A; // (offset) + int FB_SRC_B; // (offset) + int IIR_ALPHA; // (coef.) + int ACC_COEF_A; // (coef.) + int ACC_COEF_B; // (coef.) + int ACC_COEF_C; // (coef.) + int ACC_COEF_D; // (coef.) + int IIR_COEF; // (coef.) + int FB_ALPHA; // (coef.) + int FB_X; // (coef.) + int IIR_DEST_A0; // (offset) + int IIR_DEST_A1; // (offset) + int ACC_SRC_A0; // (offset) + int ACC_SRC_A1; // (offset) + int ACC_SRC_B0; // (offset) + int ACC_SRC_B1; // (offset) + int IIR_SRC_A0; // (offset) + int IIR_SRC_A1; // (offset) + int IIR_DEST_B0; // (offset) + int IIR_DEST_B1; // (offset) + int ACC_SRC_C0; // (offset) + int ACC_SRC_C1; // (offset) + int ACC_SRC_D0; // (offset) + int ACC_SRC_D1; // (offset) + int IIR_SRC_B1; // (offset) + int IIR_SRC_B0; // (offset) + int MIX_DEST_A0; // (offset) + int MIX_DEST_A1; // (offset) + int MIX_DEST_B0; // (offset) + int MIX_DEST_B1; // (offset) + int IN_COEF_L; // (coef.) + int IN_COEF_R; // (coef.) +} REVERBInfo; + +#ifdef _WINDOWS +//extern HINSTANCE hInst; +//#define WM_MUTE (WM_USER+543) +#endif + +/////////////////////////////////////////////////////////// +// SPU.C globals +/////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////// +// CFG.C globals +/////////////////////////////////////////////////////////// + +#ifndef _IN_CFG + +#ifndef _WINDOWS +extern char * pConfigFile; +#endif + +#endif + +/////////////////////////////////////////////////////////// +// DSOUND.C globals +/////////////////////////////////////////////////////////// + +#ifndef _IN_DSOUND + +#ifdef _WINDOWS +extern unsigned long LastWrite; +extern unsigned long LastPlay; +#endif + +#endif + +/////////////////////////////////////////////////////////// +// RECORD.C globals +/////////////////////////////////////////////////////////// + +#ifndef _IN_RECORD + +#ifdef _WINDOWS +extern int iDoRecord; +#endif + +#endif + +/////////////////////////////////////////////////////////// +// XA.C globals +/////////////////////////////////////////////////////////// + +#ifndef _IN_XA + +extern xa_decode_t * xapGlobal; + +extern unsigned long * XAFeed; +extern unsigned long * XAPlay; +extern unsigned long * XAStart; +extern unsigned long * XAEnd; + +extern unsigned long XARepeat; +extern unsigned long XALastVal; + +extern int iLeftXAVol; +extern int iRightXAVol; + +#endif + #endif // PEOPS2_EXTERNALS diff --git a/plugins/ao/eng_psf/peops2/registers2.c b/plugins/ao/eng_psf/peops2/registers2.c index 7eec264b..42fa3238 100644 --- a/plugins/ao/eng_psf/peops2/registers2.c +++ b/plugins/ao/eng_psf/peops2/registers2.c @@ -45,6 +45,7 @@ #include "../peops2/registers.h" #include "../peops2/regs.h" #include "../peops2/reverb.h" +#include "../peops2/spu.h" #include "../psx.h" /* @@ -65,22 +66,16 @@ #define SUSTAIN_MS 441L #define RELEASE_MS 437L -// Prototypes -void SetVolumeL(unsigned char ch,short vol); -void SetVolumeR(unsigned char ch,short vol); -void ReverbOn(int start,int end,unsigned short val,int iRight); -void SetReverbAddr(int core); -void VolumeOn(int start,int end,unsigned short val,int iRight); - //////////////////////////////////////////////////////////////////////// // WRITE REGISTERS: called by main emu //////////////////////////////////////////////////////////////////////// EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, unsigned short val) { + spu2_state_t *spu = cpu->spu2; long r=reg&0xffff; - regArea[r>>1] = val; + spu->regArea[r>>1] = val; // printf("SPU2: %04x to %08x\n", val, reg); @@ -93,30 +88,30 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns { //------------------------------------------------// r volume case 0: - SetVolumeL((unsigned char)ch,val); + SetVolumeL(spu, (unsigned char)ch,val); break; //------------------------------------------------// l volume case 2: - SetVolumeR((unsigned char)ch,val); + SetVolumeR(spu, (unsigned char)ch,val); break; //------------------------------------------------// pitch case 4: - SetPitch(ch,val); + SetPitch(spu, ch,val); break; //------------------------------------------------// level with pre-calcs case 6: { const unsigned long lval=val;unsigned long lx; //---------------------------------------------// - s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; - s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f; - s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f; - s_chan[ch].ADSRX.SustainLevel=lval & 0x000f; + spu->s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; + spu->s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f; + spu->s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f; + spu->s_chan[ch].ADSRX.SustainLevel=lval & 0x000f; //---------------------------------------------// - if(!iDebugMode) break; + if(!spu->iDebugMode) break; //---------------------------------------------// stuff below is only for debug mode - s_chan[ch].ADSR.AttackModeExp=(lval&0x8000)?1:0; //0x007f + spu->s_chan[ch].ADSR.AttackModeExp=(lval&0x8000)?1:0; //0x007f lx=(((lval>>8) & 0x007f)>>2); // attack time to run from 0 to 100% volume lx=min(31,lx); // no overflow on shift! @@ -127,9 +122,9 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns else lx=(lx/10000L)*ATTACK_MS; if(!lx) lx=1; } - s_chan[ch].ADSR.AttackTime=lx; + spu->s_chan[ch].ADSR.AttackTime=lx; - s_chan[ch].ADSR.SustainLevel= // our adsr vol runs from 0 to 1024, so scale the sustain level + spu->s_chan[ch].ADSR.SustainLevel= // our adsr vol runs from 0 to 1024, so scale the sustain level (1024*((lval) & 0x000f))/15; lx=(lval>>4) & 0x000f; // decay: @@ -138,8 +133,8 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns lx = ((1<<(lx))*DECAY_MS)/10000L; if(!lx) lx=1; } - s_chan[ch].ADSR.DecayTime = // so calc how long does it take to run from 100% to the wanted sus level - (lx*(1024-s_chan[ch].ADSR.SustainLevel))/1024; + spu->s_chan[ch].ADSR.DecayTime = // so calc how long does it take to run from 100% to the wanted sus level + (lx*(1024-spu->s_chan[ch].ADSR.SustainLevel))/1024; } break; //------------------------------------------------// adsr times with pre-calcs @@ -148,17 +143,17 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns const unsigned long lval=val;unsigned long lx; //----------------------------------------------// - s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; - s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; - s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f; - s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; - s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f; + spu->s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; + spu->s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; + spu->s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f; + spu->s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; + spu->s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f; //----------------------------------------------// - if(!iDebugMode) break; + if(!spu->iDebugMode) break; //----------------------------------------------// stuff below is only for debug mode - s_chan[ch].ADSR.SustainModeExp = (lval&0x8000)?1:0; - s_chan[ch].ADSR.ReleaseModeExp = (lval&0x0020)?1:0; + spu->s_chan[ch].ADSR.SustainModeExp = (lval&0x8000)?1:0; + spu->s_chan[ch].ADSR.ReleaseModeExp = (lval&0x0020)?1:0; lx=((((lval>>6) & 0x007f)>>2)); // sustain time... often very high lx=min(31,lx); // values are used to hold the volume @@ -169,10 +164,10 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns else lx=(lx/10000L)*SUSTAIN_MS; // should be enuff... if the stop doesn't if(!lx) lx=1; // come in this time span, I don't care :) } - s_chan[ch].ADSR.SustainTime = lx; + spu->s_chan[ch].ADSR.SustainTime = lx; lx=(lval & 0x001f); - s_chan[ch].ADSR.ReleaseVal =lx; + spu->s_chan[ch].ADSR.ReleaseVal =lx; if(lx) // release time from 100% to 0% { // note: the release time will be lx = (1<<lx); // adjusted when a stop is coming, @@ -180,17 +175,17 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns else lx=(lx/10000L)*RELEASE_MS; // run from (current volume) to 0% if(!lx) lx=1; } - s_chan[ch].ADSR.ReleaseTime=lx; + spu->s_chan[ch].ADSR.ReleaseTime=lx; if(lval & 0x4000) // add/dec flag - s_chan[ch].ADSR.SustainModeDec=-1; - else s_chan[ch].ADSR.SustainModeDec=1; + spu->s_chan[ch].ADSR.SustainModeDec=-1; + else spu->s_chan[ch].ADSR.SustainModeDec=1; } break; //------------------------------------------------// } - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; return; } @@ -206,37 +201,37 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns { //------------------------------------------------// case 0x1C0: - s_chan[ch].iStartAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iStartAdr&0xFFFF); - s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1); + spu->s_chan[ch].iStartAdr=(((unsigned long)val&0xf)<<16)|(spu->s_chan[ch].iStartAdr&0xFFFF); + spu->s_chan[ch].pStart=spu->spuMemC+(spu->s_chan[ch].iStartAdr<<1); break; case 0x1C2: - s_chan[ch].iStartAdr=(s_chan[ch].iStartAdr & 0xF0000) | (val & 0xFFFF); - s_chan[ch].pStart=spuMemC+(s_chan[ch].iStartAdr<<1); + spu->s_chan[ch].iStartAdr=(spu->s_chan[ch].iStartAdr & 0xF0000) | (val & 0xFFFF); + spu->s_chan[ch].pStart=spu->spuMemC+(spu->s_chan[ch].iStartAdr<<1); break; //------------------------------------------------// case 0x1C4: - s_chan[ch].iLoopAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iLoopAdr&0xFFFF); - s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1); - s_chan[ch].bIgnoreLoop=1; + spu->s_chan[ch].iLoopAdr=(((unsigned long)val&0xf)<<16)|(spu->s_chan[ch].iLoopAdr&0xFFFF); + spu->s_chan[ch].pLoop=spu->spuMemC+(spu->s_chan[ch].iLoopAdr<<1); + spu->s_chan[ch].bIgnoreLoop=1; break; case 0x1C6: - s_chan[ch].iLoopAdr=(s_chan[ch].iLoopAdr & 0xF0000) | (val & 0xFFFF); - s_chan[ch].pLoop=spuMemC+(s_chan[ch].iLoopAdr<<1); - s_chan[ch].bIgnoreLoop=1; + spu->s_chan[ch].iLoopAdr=(spu->s_chan[ch].iLoopAdr & 0xF0000) | (val & 0xFFFF); + spu->s_chan[ch].pLoop=spu->spuMemC+(spu->s_chan[ch].iLoopAdr<<1); + spu->s_chan[ch].bIgnoreLoop=1; break; //------------------------------------------------// case 0x1C8: // unused... check if it gets written as well - s_chan[ch].iNextAdr=(((unsigned long)val&0xf)<<16)|(s_chan[ch].iNextAdr&0xFFFF); + spu->s_chan[ch].iNextAdr=(((unsigned long)val&0xf)<<16)|(spu->s_chan[ch].iNextAdr&0xFFFF); break; case 0x1CA: // unused... check if it gets written as well - s_chan[ch].iNextAdr=(s_chan[ch].iNextAdr & 0xF0000) | (val & 0xFFFF); + spu->s_chan[ch].iNextAdr=(spu->s_chan[ch].iNextAdr & 0xF0000) | (val & 0xFFFF); break; //------------------------------------------------// } - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; return; } @@ -245,541 +240,541 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns { //-------------------------------------------------// case PS2_C0_SPUaddr_Hi: - spuAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuAddr2[0]&0xFFFF); + spu->spuAddr2[0] = (((unsigned long)val&0xf)<<16)|(spu->spuAddr2[0]&0xFFFF); break; //-------------------------------------------------// case PS2_C0_SPUaddr_Lo: - spuAddr2[0] = (spuAddr2[0] & 0xF0000) | (val & 0xFFFF); + spu->spuAddr2[0] = (spu->spuAddr2[0] & 0xF0000) | (val & 0xFFFF); break; //-------------------------------------------------// case PS2_C1_SPUaddr_Hi: - spuAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuAddr2[1]&0xFFFF); + spu->spuAddr2[1] = (((unsigned long)val&0xf)<<16)|(spu->spuAddr2[1]&0xFFFF); break; //-------------------------------------------------// case PS2_C1_SPUaddr_Lo: - spuAddr2[1] = (spuAddr2[1] & 0xF0000) | (val & 0xFFFF); + spu->spuAddr2[1] = (spu->spuAddr2[1] & 0xF0000) | (val & 0xFFFF); break; //-------------------------------------------------// case PS2_C0_SPUdata: - spuMem[spuAddr2[0]] = val; - spuAddr2[0]++; - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; + spu->spuMem[spu->spuAddr2[0]] = val; + spu->spuAddr2[0]++; + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; break; //-------------------------------------------------// case PS2_C1_SPUdata: - spuMem[spuAddr2[1]] = val; - spuAddr2[1]++; - if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; + spu->spuMem[spu->spuAddr2[1]] = val; + spu->spuAddr2[1]++; + if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; break; //-------------------------------------------------// case PS2_C0_ATTR: - spuCtrl2[0]=val; + spu->spuCtrl2[0]=val; break; //-------------------------------------------------// case PS2_C1_ATTR: - spuCtrl2[1]=val; + spu->spuCtrl2[1]=val; break; //-------------------------------------------------// case PS2_C0_SPUstat: - spuStat2[0]=val; + spu->spuStat2[0]=val; break; //-------------------------------------------------// case PS2_C1_SPUstat: - spuStat2[1]=val; + spu->spuStat2[1]=val; break; //-------------------------------------------------// case PS2_C0_ReverbAddr_Hi: - spuRvbAddr2[0] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[0]&0xFFFF); - SetReverbAddr(0); + spu->spuRvbAddr2[0] = (((unsigned long)val&0xf)<<16)|(spu->spuRvbAddr2[0]&0xFFFF); + SetReverbAddr(spu, 0); break; //-------------------------------------------------// case PS2_C0_ReverbAddr_Lo: - spuRvbAddr2[0] = (spuRvbAddr2[0] & 0xF0000) | (val & 0xFFFF); - SetReverbAddr(0); + spu->spuRvbAddr2[0] = (spu->spuRvbAddr2[0] & 0xF0000) | (val & 0xFFFF); + SetReverbAddr(spu, 0); break; //-------------------------------------------------// case PS2_C0_ReverbAEnd_Hi: - spuRvbAEnd2[0] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[0]&*/0xFFFF); - rvb[0].EndAddr=spuRvbAEnd2[0]; + spu->spuRvbAEnd2[0] = (((unsigned long)val&0xf)<<16)|(/*spu->spuRvbAEnd2[0]&*/0xFFFF); + spu->rvb[0].EndAddr=spu->spuRvbAEnd2[0]; break; //-------------------------------------------------// case PS2_C1_ReverbAEnd_Hi: - spuRvbAEnd2[1] = (((unsigned long)val&0xf)<<16)|(/*spuRvbAEnd2[1]&*/0xFFFF); - rvb[1].EndAddr=spuRvbAEnd2[1]; + spu->spuRvbAEnd2[1] = (((unsigned long)val&0xf)<<16)|(/*spu->spuRvbAEnd2[1]&*/0xFFFF); + spu->rvb[1].EndAddr=spu->spuRvbAEnd2[1]; break; //-------------------------------------------------// case PS2_C1_ReverbAddr_Hi: - spuRvbAddr2[1] = (((unsigned long)val&0xf)<<16)|(spuRvbAddr2[1]&0xFFFF); - SetReverbAddr(1); + spu->spuRvbAddr2[1] = (((unsigned long)val&0xf)<<16)|(spu->spuRvbAddr2[1]&0xFFFF); + SetReverbAddr(spu, 1); break; //-------------------------------------------------// case PS2_C1_ReverbAddr_Lo: - spuRvbAddr2[1] = (spuRvbAddr2[1] & 0xF0000) | (val & 0xFFFF); - SetReverbAddr(1); + spu->spuRvbAddr2[1] = (spu->spuRvbAddr2[1] & 0xF0000) | (val & 0xFFFF); + SetReverbAddr(spu, 1); break; //-------------------------------------------------// case PS2_C0_SPUirqAddr_Hi: - spuIrq2[0] = (((unsigned long)val&0xf)<<16)|(spuIrq2[0]&0xFFFF); - pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1); + spu->spuIrq2[0] = (((unsigned long)val&0xf)<<16)|(spu->spuIrq2[0]&0xFFFF); + spu->pSpuIrq[0]=spu->spuMemC+(spu->spuIrq2[0]<<1); break; //-------------------------------------------------// case PS2_C0_SPUirqAddr_Lo: - spuIrq2[0] = (spuIrq2[0] & 0xF0000) | (val & 0xFFFF); - pSpuIrq[0]=spuMemC+(spuIrq2[0]<<1); + spu->spuIrq2[0] = (spu->spuIrq2[0] & 0xF0000) | (val & 0xFFFF); + spu->pSpuIrq[0]=spu->spuMemC+(spu->spuIrq2[0]<<1); break; //-------------------------------------------------// case PS2_C1_SPUirqAddr_Hi: - spuIrq2[1] = (((unsigned long)val&0xf)<<16)|(spuIrq2[1]&0xFFFF); - pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1); + spu->spuIrq2[1] = (((unsigned long)val&0xf)<<16)|(spu->spuIrq2[1]&0xFFFF); + spu->pSpuIrq[1]=spu->spuMemC+(spu->spuIrq2[1]<<1); break; //-------------------------------------------------// case PS2_C1_SPUirqAddr_Lo: - spuIrq2[1] = (spuIrq2[1] & 0xF0000) | (val & 0xFFFF); - pSpuIrq[1]=spuMemC+(spuIrq2[1]<<1); + spu->spuIrq2[1] = (spu->spuIrq2[1] & 0xF0000) | (val & 0xFFFF); + spu->pSpuIrq[1]=spu->spuMemC+(spu->spuIrq2[1]<<1); break; //-------------------------------------------------// case PS2_C0_SPUrvolL: - rvb[0].VolLeft=val; + spu->rvb[0].VolLeft=val; break; //-------------------------------------------------// case PS2_C0_SPUrvolR: - rvb[0].VolRight=val; + spu->rvb[0].VolRight=val; break; //-------------------------------------------------// case PS2_C1_SPUrvolL: - rvb[1].VolLeft=val; + spu->rvb[1].VolLeft=val; break; //-------------------------------------------------// case PS2_C1_SPUrvolR: - rvb[1].VolRight=val; + spu->rvb[1].VolRight=val; break; //-------------------------------------------------// case PS2_C0_SPUon1: - SoundOn(0,16,val); + SoundOn(spu, 0,16,val); break; //-------------------------------------------------// case PS2_C0_SPUon2: - SoundOn(16,24,val); + SoundOn(spu, 16,24,val); break; //-------------------------------------------------// case PS2_C1_SPUon1: - SoundOn(24,40,val); + SoundOn(spu, 24,40,val); break; //-------------------------------------------------// case PS2_C1_SPUon2: - SoundOn(40,48,val); + SoundOn(spu, 40,48,val); break; //-------------------------------------------------// case PS2_C0_SPUoff1: - SoundOff(0,16,val); + SoundOff(spu, 0,16,val); break; //-------------------------------------------------// case PS2_C0_SPUoff2: - SoundOff(16,24,val); + SoundOff(spu, 16,24,val); break; //-------------------------------------------------// case PS2_C1_SPUoff1: - SoundOff(24,40,val); + SoundOff(spu, 24,40,val); break; //-------------------------------------------------// case PS2_C1_SPUoff2: - SoundOff(40,48,val); + SoundOff(spu, 40,48,val); break; //-------------------------------------------------// case PS2_C0_SPUend1: case PS2_C0_SPUend2: - if(val) dwEndChannel2[0]=0; + if(val) spu->dwEndChannel2[0]=0; break; //-------------------------------------------------// case PS2_C1_SPUend1: case PS2_C1_SPUend2: - if(val) dwEndChannel2[1]=0; + if(val) spu->dwEndChannel2[1]=0; break; //-------------------------------------------------// case PS2_C0_FMod1: - FModOn(0,16,val); + FModOn(spu, 0,16,val); break; //-------------------------------------------------// case PS2_C0_FMod2: - FModOn(16,24,val); + FModOn(spu, 16,24,val); break; //-------------------------------------------------// case PS2_C1_FMod1: - FModOn(24,40,val); + FModOn(spu, 24,40,val); break; //-------------------------------------------------// case PS2_C1_FMod2: - FModOn(40,48,val); + FModOn(spu, 40,48,val); break; //-------------------------------------------------// case PS2_C0_Noise1: - NoiseOn(0,16,val); + NoiseOn(spu, 0,16,val); break; //-------------------------------------------------// case PS2_C0_Noise2: - NoiseOn(16,24,val); + NoiseOn(spu, 16,24,val); break; //-------------------------------------------------// case PS2_C1_Noise1: - NoiseOn(24,40,val); + NoiseOn(spu, 24,40,val); break; //-------------------------------------------------// case PS2_C1_Noise2: - NoiseOn(40,48,val); + NoiseOn(spu, 40,48,val); break; //-------------------------------------------------// case PS2_C0_DryL1: - VolumeOn(0,16,val,0); + VolumeOn(spu, 0,16,val,0); break; //-------------------------------------------------// case PS2_C0_DryL2: - VolumeOn(16,24,val,0); + VolumeOn(spu, 16,24,val,0); break; //-------------------------------------------------// case PS2_C1_DryL1: - VolumeOn(24,40,val,0); + VolumeOn(spu, 24,40,val,0); break; //-------------------------------------------------// case PS2_C1_DryL2: - VolumeOn(40,48,val,0); + VolumeOn(spu, 40,48,val,0); break; //-------------------------------------------------// case PS2_C0_DryR1: - VolumeOn(0,16,val,1); + VolumeOn(spu, 0,16,val,1); break; //-------------------------------------------------// case PS2_C0_DryR2: - VolumeOn(16,24,val,1); + VolumeOn(spu, 16,24,val,1); break; //-------------------------------------------------// case PS2_C1_DryR1: - VolumeOn(24,40,val,1); + VolumeOn(spu, 24,40,val,1); break; //-------------------------------------------------// case PS2_C1_DryR2: - VolumeOn(40,48,val,1); + VolumeOn(spu, 40,48,val,1); break; //-------------------------------------------------// case PS2_C0_RVBon1_L: - ReverbOn(0,16,val,0); + ReverbOn(spu, 0,16,val,0); break; //-------------------------------------------------// case PS2_C0_RVBon2_L: - ReverbOn(16,24,val,0); + ReverbOn(spu, 16,24,val,0); break; //-------------------------------------------------// case PS2_C1_RVBon1_L: - ReverbOn(24,40,val,0); + ReverbOn(spu, 24,40,val,0); break; //-------------------------------------------------// case PS2_C1_RVBon2_L: - ReverbOn(40,48,val,0); + ReverbOn(spu, 40,48,val,0); break; //-------------------------------------------------// case PS2_C0_RVBon1_R: - ReverbOn(0,16,val,1); + ReverbOn(spu, 0,16,val,1); break; //-------------------------------------------------// case PS2_C0_RVBon2_R: - ReverbOn(16,24,val,1); + ReverbOn(spu, 16,24,val,1); break; //-------------------------------------------------// case PS2_C1_RVBon1_R: - ReverbOn(24,40,val,1); + ReverbOn(spu, 24,40,val,1); break; //-------------------------------------------------// case PS2_C1_RVBon2_R: - ReverbOn(40,48,val,1); + ReverbOn(spu, 40,48,val,1); break; //-------------------------------------------------// case PS2_C0_Reverb+0: - rvb[0].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_A&0xFFFF); + spu->rvb[0].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].FB_SRC_A&0xFFFF); break; case PS2_C0_Reverb+2: - rvb[0].FB_SRC_A=(rvb[0].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].FB_SRC_A=(spu->rvb[0].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+4: - rvb[0].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[0].FB_SRC_B&0xFFFF); + spu->rvb[0].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].FB_SRC_B&0xFFFF); break; case PS2_C0_Reverb+6: - rvb[0].FB_SRC_B=(rvb[0].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].FB_SRC_B=(spu->rvb[0].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+8: - rvb[0].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A0&0xFFFF); + spu->rvb[0].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_DEST_A0&0xFFFF); break; case PS2_C0_Reverb+10: - rvb[0].IIR_DEST_A0=(rvb[0].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_DEST_A0=(spu->rvb[0].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+12: - rvb[0].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_A1&0xFFFF); + spu->rvb[0].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_DEST_A1&0xFFFF); break; case PS2_C0_Reverb+14: - rvb[0].IIR_DEST_A1=(rvb[0].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_DEST_A1=(spu->rvb[0].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+16: - rvb[0].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A0&0xFFFF); + spu->rvb[0].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_A0&0xFFFF); break; case PS2_C0_Reverb+18: - rvb[0].ACC_SRC_A0=(rvb[0].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_A0=(spu->rvb[0].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+20: - rvb[0].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_A1&0xFFFF); + spu->rvb[0].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_A1&0xFFFF); break; case PS2_C0_Reverb+22: - rvb[0].ACC_SRC_A1=(rvb[0].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_A1=(spu->rvb[0].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+24: - rvb[0].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B0&0xFFFF); + spu->rvb[0].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_B0&0xFFFF); break; case PS2_C0_Reverb+26: - rvb[0].ACC_SRC_B0=(rvb[0].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_B0=(spu->rvb[0].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+28: - rvb[0].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_B1&0xFFFF); + spu->rvb[0].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_B1&0xFFFF); break; case PS2_C0_Reverb+30: - rvb[0].ACC_SRC_B1=(rvb[0].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_B1=(spu->rvb[0].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+32: - rvb[0].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A0&0xFFFF); + spu->rvb[0].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_SRC_A0&0xFFFF); break; case PS2_C0_Reverb+34: - rvb[0].IIR_SRC_A0=(rvb[0].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_SRC_A0=(spu->rvb[0].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+36: - rvb[0].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_A1&0xFFFF); + spu->rvb[0].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_SRC_A1&0xFFFF); break; case PS2_C0_Reverb+38: - rvb[0].IIR_SRC_A1=(rvb[0].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_SRC_A1=(spu->rvb[0].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+40: - rvb[0].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B0&0xFFFF); + spu->rvb[0].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_DEST_B0&0xFFFF); break; case PS2_C0_Reverb+42: - rvb[0].IIR_DEST_B0=(rvb[0].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_DEST_B0=(spu->rvb[0].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+44: - rvb[0].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_DEST_B1&0xFFFF); + spu->rvb[0].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_DEST_B1&0xFFFF); break; case PS2_C0_Reverb+46: - rvb[0].IIR_DEST_B1=(rvb[0].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_DEST_B1=(spu->rvb[0].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+48: - rvb[0].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C0&0xFFFF); + spu->rvb[0].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_C0&0xFFFF); break; case PS2_C0_Reverb+50: - rvb[0].ACC_SRC_C0=(rvb[0].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_C0=(spu->rvb[0].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+52: - rvb[0].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_C1&0xFFFF); + spu->rvb[0].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_C1&0xFFFF); break; case PS2_C0_Reverb+54: - rvb[0].ACC_SRC_C1=(rvb[0].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_C1=(spu->rvb[0].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+56: - rvb[0].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D0&0xFFFF); + spu->rvb[0].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_D0&0xFFFF); break; case PS2_C0_Reverb+58: - rvb[0].ACC_SRC_D0=(rvb[0].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_D0=(spu->rvb[0].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+60: - rvb[0].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[0].ACC_SRC_D1&0xFFFF); + spu->rvb[0].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].ACC_SRC_D1&0xFFFF); break; case PS2_C0_Reverb+62: - rvb[0].ACC_SRC_D1=(rvb[0].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].ACC_SRC_D1=(spu->rvb[0].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+64: - rvb[0].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B1&0xFFFF); + spu->rvb[0].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_SRC_B1&0xFFFF); break; case PS2_C0_Reverb+66: - rvb[0].IIR_SRC_B1=(rvb[0].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_SRC_B1=(spu->rvb[0].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+68: - rvb[0].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].IIR_SRC_B0&0xFFFF); + spu->rvb[0].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].IIR_SRC_B0&0xFFFF); break; case PS2_C0_Reverb+70: - rvb[0].IIR_SRC_B0=(rvb[0].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].IIR_SRC_B0=(spu->rvb[0].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+72: - rvb[0].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A0&0xFFFF); + spu->rvb[0].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].MIX_DEST_A0&0xFFFF); break; case PS2_C0_Reverb+74: - rvb[0].MIX_DEST_A0=(rvb[0].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].MIX_DEST_A0=(spu->rvb[0].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+76: - rvb[0].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_A1&0xFFFF); + spu->rvb[0].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].MIX_DEST_A1&0xFFFF); break; case PS2_C0_Reverb+78: - rvb[0].MIX_DEST_A1=(rvb[0].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].MIX_DEST_A1=(spu->rvb[0].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+80: - rvb[0].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B0&0xFFFF); + spu->rvb[0].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].MIX_DEST_B0&0xFFFF); break; case PS2_C0_Reverb+82: - rvb[0].MIX_DEST_B0=(rvb[0].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[0].MIX_DEST_B0=(spu->rvb[0].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C0_Reverb+84: - rvb[0].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[0].MIX_DEST_B1&0xFFFF); + spu->rvb[0].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[0].MIX_DEST_B1&0xFFFF); break; case PS2_C0_Reverb+86: - rvb[0].MIX_DEST_B1=(rvb[0].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); - break; - case PS2_C0_ReverbX+0: rvb[0].IIR_ALPHA=(short)val; break; - case PS2_C0_ReverbX+2: rvb[0].ACC_COEF_A=(short)val; break; - case PS2_C0_ReverbX+4: rvb[0].ACC_COEF_B=(short)val; break; - case PS2_C0_ReverbX+6: rvb[0].ACC_COEF_C=(short)val; break; - case PS2_C0_ReverbX+8: rvb[0].ACC_COEF_D=(short)val; break; - case PS2_C0_ReverbX+10: rvb[0].IIR_COEF=(short)val; break; - case PS2_C0_ReverbX+12: rvb[0].FB_ALPHA=(short)val; break; - case PS2_C0_ReverbX+14: rvb[0].FB_X=(short)val; break; - case PS2_C0_ReverbX+16: rvb[0].IN_COEF_L=(short)val; break; - case PS2_C0_ReverbX+18: rvb[0].IN_COEF_R=(short)val; break; + spu->rvb[0].MIX_DEST_B1=(spu->rvb[0].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); + break; + case PS2_C0_ReverbX+0: spu->rvb[0].IIR_ALPHA=(short)val; break; + case PS2_C0_ReverbX+2: spu->rvb[0].ACC_COEF_A=(short)val; break; + case PS2_C0_ReverbX+4: spu->rvb[0].ACC_COEF_B=(short)val; break; + case PS2_C0_ReverbX+6: spu->rvb[0].ACC_COEF_C=(short)val; break; + case PS2_C0_ReverbX+8: spu->rvb[0].ACC_COEF_D=(short)val; break; + case PS2_C0_ReverbX+10: spu->rvb[0].IIR_COEF=(short)val; break; + case PS2_C0_ReverbX+12: spu->rvb[0].FB_ALPHA=(short)val; break; + case PS2_C0_ReverbX+14: spu->rvb[0].FB_X=(short)val; break; + case PS2_C0_ReverbX+16: spu->rvb[0].IN_COEF_L=(short)val; break; + case PS2_C0_ReverbX+18: spu->rvb[0].IN_COEF_R=(short)val; break; //-------------------------------------------------// case PS2_C1_Reverb+0: - rvb[1].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_A&0xFFFF); + spu->rvb[1].FB_SRC_A=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].FB_SRC_A&0xFFFF); break; case PS2_C1_Reverb+2: - rvb[1].FB_SRC_A=(rvb[1].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].FB_SRC_A=(spu->rvb[1].FB_SRC_A & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+4: - rvb[1].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(rvb[1].FB_SRC_B&0xFFFF); + spu->rvb[1].FB_SRC_B=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].FB_SRC_B&0xFFFF); break; case PS2_C1_Reverb+6: - rvb[1].FB_SRC_B=(rvb[1].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].FB_SRC_B=(spu->rvb[1].FB_SRC_B & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+8: - rvb[1].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A0&0xFFFF); + spu->rvb[1].IIR_DEST_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_DEST_A0&0xFFFF); break; case PS2_C1_Reverb+10: - rvb[1].IIR_DEST_A0=(rvb[1].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_DEST_A0=(spu->rvb[1].IIR_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+12: - rvb[1].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_A1&0xFFFF); + spu->rvb[1].IIR_DEST_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_DEST_A1&0xFFFF); break; case PS2_C1_Reverb+14: - rvb[1].IIR_DEST_A1=(rvb[1].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_DEST_A1=(spu->rvb[1].IIR_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+16: - rvb[1].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A0&0xFFFF); + spu->rvb[1].ACC_SRC_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_A0&0xFFFF); break; case PS2_C1_Reverb+18: - rvb[1].ACC_SRC_A0=(rvb[1].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_A0=(spu->rvb[1].ACC_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+20: - rvb[1].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_A1&0xFFFF); + spu->rvb[1].ACC_SRC_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_A1&0xFFFF); break; case PS2_C1_Reverb+22: - rvb[1].ACC_SRC_A1=(rvb[1].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_A1=(spu->rvb[1].ACC_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+24: - rvb[1].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B0&0xFFFF); + spu->rvb[1].ACC_SRC_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_B0&0xFFFF); break; case PS2_C1_Reverb+26: - rvb[1].ACC_SRC_B0=(rvb[1].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_B0=(spu->rvb[1].ACC_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+28: - rvb[1].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_B1&0xFFFF); + spu->rvb[1].ACC_SRC_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_B1&0xFFFF); break; case PS2_C1_Reverb+30: - rvb[1].ACC_SRC_B1=(rvb[1].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_B1=(spu->rvb[1].ACC_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+32: - rvb[1].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A0&0xFFFF); + spu->rvb[1].IIR_SRC_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_SRC_A0&0xFFFF); break; case PS2_C1_Reverb+34: - rvb[1].IIR_SRC_A0=(rvb[1].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_SRC_A0=(spu->rvb[1].IIR_SRC_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+36: - rvb[1].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_A1&0xFFFF); + spu->rvb[1].IIR_SRC_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_SRC_A1&0xFFFF); break; case PS2_C1_Reverb+38: - rvb[1].IIR_SRC_A1=(rvb[1].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_SRC_A1=(spu->rvb[1].IIR_SRC_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+40: - rvb[1].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B0&0xFFFF); + spu->rvb[1].IIR_DEST_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_DEST_B0&0xFFFF); break; case PS2_C1_Reverb+42: - rvb[1].IIR_DEST_B0=(rvb[1].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_DEST_B0=(spu->rvb[1].IIR_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+44: - rvb[1].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_DEST_B1&0xFFFF); + spu->rvb[1].IIR_DEST_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_DEST_B1&0xFFFF); break; case PS2_C1_Reverb+46: - rvb[1].IIR_DEST_B1=(rvb[1].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_DEST_B1=(spu->rvb[1].IIR_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+48: - rvb[1].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C0&0xFFFF); + spu->rvb[1].ACC_SRC_C0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_C0&0xFFFF); break; case PS2_C1_Reverb+50: - rvb[1].ACC_SRC_C0=(rvb[1].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_C0=(spu->rvb[1].ACC_SRC_C0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+52: - rvb[1].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_C1&0xFFFF); + spu->rvb[1].ACC_SRC_C1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_C1&0xFFFF); break; case PS2_C1_Reverb+54: - rvb[1].ACC_SRC_C1=(rvb[1].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_C1=(spu->rvb[1].ACC_SRC_C1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+56: - rvb[1].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D0&0xFFFF); + spu->rvb[1].ACC_SRC_D0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_D0&0xFFFF); break; case PS2_C1_Reverb+58: - rvb[1].ACC_SRC_D0=(rvb[1].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_D0=(spu->rvb[1].ACC_SRC_D0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+60: - rvb[1].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(rvb[1].ACC_SRC_D1&0xFFFF); + spu->rvb[1].ACC_SRC_D1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].ACC_SRC_D1&0xFFFF); break; case PS2_C1_Reverb+62: - rvb[1].ACC_SRC_D1=(rvb[1].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].ACC_SRC_D1=(spu->rvb[1].ACC_SRC_D1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+64: - rvb[1].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B1&0xFFFF); + spu->rvb[1].IIR_SRC_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_SRC_B1&0xFFFF); break; case PS2_C1_Reverb+66: - rvb[1].IIR_SRC_B1=(rvb[1].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_SRC_B1=(spu->rvb[1].IIR_SRC_B1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+68: - rvb[1].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].IIR_SRC_B0&0xFFFF); + spu->rvb[1].IIR_SRC_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].IIR_SRC_B0&0xFFFF); break; case PS2_C1_Reverb+70: - rvb[1].IIR_SRC_B0=(rvb[1].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].IIR_SRC_B0=(spu->rvb[1].IIR_SRC_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+72: - rvb[1].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A0&0xFFFF); + spu->rvb[1].MIX_DEST_A0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].MIX_DEST_A0&0xFFFF); break; case PS2_C1_Reverb+74: - rvb[1].MIX_DEST_A0=(rvb[1].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].MIX_DEST_A0=(spu->rvb[1].MIX_DEST_A0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+76: - rvb[1].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_A1&0xFFFF); + spu->rvb[1].MIX_DEST_A1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].MIX_DEST_A1&0xFFFF); break; case PS2_C1_Reverb+78: - rvb[1].MIX_DEST_A1=(rvb[1].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].MIX_DEST_A1=(spu->rvb[1].MIX_DEST_A1 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+80: - rvb[1].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B0&0xFFFF); + spu->rvb[1].MIX_DEST_B0=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].MIX_DEST_B0&0xFFFF); break; case PS2_C1_Reverb+82: - rvb[1].MIX_DEST_B0=(rvb[1].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); + spu->rvb[1].MIX_DEST_B0=(spu->rvb[1].MIX_DEST_B0 & 0xF0000) | ((val) & 0xFFFF); break; case PS2_C1_Reverb+84: - rvb[1].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(rvb[1].MIX_DEST_B1&0xFFFF); + spu->rvb[1].MIX_DEST_B1=(((unsigned long)val&0xf)<<16)|(spu->rvb[1].MIX_DEST_B1&0xFFFF); break; case PS2_C1_Reverb+86: - rvb[1].MIX_DEST_B1=(rvb[1].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); - break; - case PS2_C1_ReverbX+0: rvb[1].IIR_ALPHA=(short)val; break; - case PS2_C1_ReverbX+2: rvb[1].ACC_COEF_A=(short)val; break; - case PS2_C1_ReverbX+4: rvb[1].ACC_COEF_B=(short)val; break; - case PS2_C1_ReverbX+6: rvb[1].ACC_COEF_C=(short)val; break; - case PS2_C1_ReverbX+8: rvb[1].ACC_COEF_D=(short)val; break; - case PS2_C1_ReverbX+10: rvb[1].IIR_COEF=(short)val; break; - case PS2_C1_ReverbX+12: rvb[1].FB_ALPHA=(short)val; break; - case PS2_C1_ReverbX+14: rvb[1].FB_X=(short)val; break; - case PS2_C1_ReverbX+16: rvb[1].IN_COEF_L=(short)val; break; - case PS2_C1_ReverbX+18: rvb[1].IN_COEF_R=(short)val; break; + spu->rvb[1].MIX_DEST_B1=(spu->rvb[1].MIX_DEST_B1 & 0xF0000) | ((val) & 0xFFFF); + break; + case PS2_C1_ReverbX+0: spu->rvb[1].IIR_ALPHA=(short)val; break; + case PS2_C1_ReverbX+2: spu->rvb[1].ACC_COEF_A=(short)val; break; + case PS2_C1_ReverbX+4: spu->rvb[1].ACC_COEF_B=(short)val; break; + case PS2_C1_ReverbX+6: spu->rvb[1].ACC_COEF_C=(short)val; break; + case PS2_C1_ReverbX+8: spu->rvb[1].ACC_COEF_D=(short)val; break; + case PS2_C1_ReverbX+10: spu->rvb[1].IIR_COEF=(short)val; break; + case PS2_C1_ReverbX+12: spu->rvb[1].FB_ALPHA=(short)val; break; + case PS2_C1_ReverbX+14: spu->rvb[1].FB_X=(short)val; break; + case PS2_C1_ReverbX+16: spu->rvb[1].IN_COEF_L=(short)val; break; + case PS2_C1_ReverbX+18: spu->rvb[1].IN_COEF_R=(short)val; break; } - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; } @@ -789,13 +784,14 @@ EXPORT_GCC void CALLBACK SPU2write(mips_cpu_context *cpu, unsigned long reg, uns EXPORT_GCC unsigned short CALLBACK SPU2read(mips_cpu_context *cpu, unsigned long reg) { + spu2_state_t *spu = cpu->spu2; long r=reg&0xffff; #ifdef _WINDOWS // if(iDebugMode==1) logprintf("R_REG %X\r\n",reg&0xFFFF); #endif - iSpuAsyncWait=0; + spu->iSpuAsyncWait=0; if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info? { @@ -806,11 +802,11 @@ EXPORT_GCC unsigned short CALLBACK SPU2read(mips_cpu_context *cpu, unsigned long { int ch=(r>>4)&0x1f; if(r>=0x400) ch+=24; - if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1 - if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well - !s_chan[ch].ADSRX.EnvelopeVol) + if(spu->s_chan[ch].bNew) return 1; // we are started, but not processed? return 1 + if(spu->s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well + !spu->s_chan[ch].ADSRX.EnvelopeVol) return 1; - return (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol>>16); + return (unsigned short)(spu->s_chan[ch].ADSRX.EnvelopeVol>>16); }break; } } @@ -827,17 +823,17 @@ EXPORT_GCC unsigned short CALLBACK SPU2read(mips_cpu_context *cpu, unsigned long { //------------------------------------------------// case 0x1C4: - return (((s_chan[ch].pLoop-spuMemC)>>17)&0xF); + return (((spu->s_chan[ch].pLoop-spu->spuMemC)>>17)&0xF); break; case 0x1C6: - return (((s_chan[ch].pLoop-spuMemC)>>1)&0xFFFF); + return (((spu->s_chan[ch].pLoop-spu->spuMemC)>>1)&0xFFFF); break; //------------------------------------------------// case 0x1C8: - return (((s_chan[ch].pCurr-spuMemC)>>17)&0xF); + return (((spu->s_chan[ch].pCurr-spu->spuMemC)>>17)&0xF); break; case 0x1CA: - return (((s_chan[ch].pCurr-spuMemC)>>1)&0xFFFF); + return (((spu->s_chan[ch].pCurr-spu->spuMemC)>>1)&0xFFFF); break; //------------------------------------------------// } @@ -847,68 +843,69 @@ EXPORT_GCC unsigned short CALLBACK SPU2read(mips_cpu_context *cpu, unsigned long { //--------------------------------------------------// case PS2_C0_SPUend1: - return (unsigned short)((dwEndChannel2[0]&0xFFFF)); + return (unsigned short)((spu->dwEndChannel2[0]&0xFFFF)); case PS2_C0_SPUend2: - return (unsigned short)((dwEndChannel2[0]>>16)); + return (unsigned short)((spu->dwEndChannel2[0]>>16)); //--------------------------------------------------// case PS2_C1_SPUend1: - return (unsigned short)((dwEndChannel2[1]&0xFFFF)); + return (unsigned short)((spu->dwEndChannel2[1]&0xFFFF)); case PS2_C1_SPUend2: - return (unsigned short)((dwEndChannel2[1]>>16)); + return (unsigned short)((spu->dwEndChannel2[1]>>16)); //--------------------------------------------------// case PS2_C0_ATTR: - return spuCtrl2[0]; + return spu->spuCtrl2[0]; break; //--------------------------------------------------// case PS2_C1_ATTR: - return spuCtrl2[1]; + return spu->spuCtrl2[1]; break; //--------------------------------------------------// case PS2_C0_SPUstat: - return spuStat2[0]; + return spu->spuStat2[0]; break; //--------------------------------------------------// case PS2_C1_SPUstat: - return spuStat2[1]; + return spu->spuStat2[1]; break; //--------------------------------------------------// case PS2_C0_SPUdata: { - unsigned short s=spuMem[spuAddr2[0]]; - spuAddr2[0]++; - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; + unsigned short s=spu->spuMem[spu->spuAddr2[0]]; + spu->spuAddr2[0]++; + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; return s; } //--------------------------------------------------// case PS2_C1_SPUdata: { - unsigned short s=spuMem[spuAddr2[1]]; - spuAddr2[1]++; - if(spuAddr2[1]>0xfffff) spuAddr2[1]=0; + unsigned short s=spu->spuMem[spu->spuAddr2[1]]; + spu->spuAddr2[1]++; + if(spu->spuAddr2[1]>0xfffff) spu->spuAddr2[1]=0; return s; } //--------------------------------------------------// case PS2_C0_SPUaddr_Hi: - return (unsigned short)((spuAddr2[0]>>16)&0xF); + return (unsigned short)((spu->spuAddr2[0]>>16)&0xF); break; case PS2_C0_SPUaddr_Lo: - return (unsigned short)((spuAddr2[0]&0xFFFF)); + return (unsigned short)((spu->spuAddr2[0]&0xFFFF)); break; //--------------------------------------------------// case PS2_C1_SPUaddr_Hi: - return (unsigned short)((spuAddr2[1]>>16)&0xF); + return (unsigned short)((spu->spuAddr2[1]>>16)&0xF); break; case PS2_C1_SPUaddr_Lo: - return (unsigned short)((spuAddr2[1]&0xFFFF)); + return (unsigned short)((spu->spuAddr2[1]&0xFFFF)); break; //--------------------------------------------------// } - return regArea[r>>1]; + return spu->regArea[r>>1]; } EXPORT_GCC void CALLBACK SPU2writePS1Port(mips_cpu_context *cpu, unsigned long reg, unsigned short val) { + spu2_state_t *spu = cpu->spu2; const u32 r=reg&0xfff; if(r>=0xc00 && r<0xd80) // channel info @@ -921,13 +918,13 @@ EXPORT_GCC void CALLBACK SPU2writePS1Port(mips_cpu_context *cpu, unsigned long r { //-------------------------------------------------// case H_SPUaddr: - spuAddr2[0] = (u32) val<<2; + spu->spuAddr2[0] = (u32) val<<2; break; //-------------------------------------------------// case H_SPUdata: - spuMem[spuAddr2[0]] = BFLIP16(val); - spuAddr2[0]++; - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; + spu->spuMem[spu->spuAddr2[0]] = BFLIP16(val); + spu->spuAddr2[0]++; + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; break; //-------------------------------------------------// case H_SPUctrl: @@ -935,17 +932,17 @@ EXPORT_GCC void CALLBACK SPU2writePS1Port(mips_cpu_context *cpu, unsigned long r break; //-------------------------------------------------// case H_SPUstat: - spuStat2[0]=val & 0xf800; + spu->spuStat2[0]=val & 0xf800; break; //-------------------------------------------------// case H_SPUReverbAddr: - spuRvbAddr2[0] = val; - SetReverbAddr(0); + spu->spuRvbAddr2[0] = val; + SetReverbAddr(spu, 0); break; //-------------------------------------------------// case H_SPUirqAddr: - spuIrq2[0] = val<<2; - pSpuIrq[0]=spuMemC+((u32) val<<1); + spu->spuIrq2[0] = val<<2; + spu->pSpuIrq[0]=spu->spuMemC+((u32) val<<1); break; //-------------------------------------------------// /* Volume settings appear to be at least 15-bit unsigned in this case. @@ -953,12 +950,12 @@ EXPORT_GCC void CALLBACK SPU2writePS1Port(mips_cpu_context *cpu, unsigned long r Check out "Chrono Cross: Shadow's End Forest" */ case H_SPUrvolL: - rvb[0].VolLeft=(s16)val; + spu->rvb[0].VolLeft=(s16)val; //printf("%d\n",val); break; //-------------------------------------------------// case H_SPUrvolR: - rvb[0].VolRight=(s16)val; + spu->rvb[0].VolRight=(s16)val; //printf("%d\n",val); break; //-------------------------------------------------// @@ -990,89 +987,90 @@ EXPORT_GCC void CALLBACK SPU2writePS1Port(mips_cpu_context *cpu, unsigned long r */ //-------------------------------------------------// case H_SPUon1: - SoundOn(0,16,val); + SoundOn(spu, 0,16,val); break; //-------------------------------------------------// case H_SPUon2: //printf("Boop: %08x: %04x\n",reg,val); - SoundOn(16,24,val); + SoundOn(spu, 16,24,val); break; //-------------------------------------------------// case H_SPUoff1: - SoundOff(0,16,val); + SoundOff(spu, 0,16,val); break; //-------------------------------------------------// case H_SPUoff2: - SoundOff(16,24,val); + SoundOff(spu, 16,24,val); // printf("Boop: %08x: %04x\n",reg,val); break; //-------------------------------------------------// case H_FMod1: - FModOn(0,16,val); + FModOn(spu, 0,16,val); break; //-------------------------------------------------// case H_FMod2: - FModOn(16,24,val); + FModOn(spu, 16,24,val); break; //-------------------------------------------------// case H_Noise1: - NoiseOn(0,16,val); + NoiseOn(spu, 0,16,val); break; //-------------------------------------------------// case H_Noise2: - NoiseOn(16,24,val); + NoiseOn(spu, 16,24,val); break; //-------------------------------------------------// case H_RVBon1: - ReverbOn(0,16,val,0); + ReverbOn(spu, 0,16,val,0); break; //-------------------------------------------------// case H_RVBon2: - ReverbOn(16,24,val,0); + ReverbOn(spu, 16,24,val,0); break; //-------------------------------------------------// case H_Reverb+0: - rvb[0].FB_SRC_A=val; - break; - - case H_Reverb+2 : rvb[0].FB_SRC_B=(s16)val; break; - case H_Reverb+4 : rvb[0].IIR_ALPHA=(s16)val; break; - case H_Reverb+6 : rvb[0].ACC_COEF_A=(s16)val; break; - case H_Reverb+8 : rvb[0].ACC_COEF_B=(s16)val; break; - case H_Reverb+10 : rvb[0].ACC_COEF_C=(s16)val; break; - case H_Reverb+12 : rvb[0].ACC_COEF_D=(s16)val; break; - case H_Reverb+14 : rvb[0].IIR_COEF=(s16)val; break; - case H_Reverb+16 : rvb[0].FB_ALPHA=(s16)val; break; - case H_Reverb+18 : rvb[0].FB_X=(s16)val; break; - case H_Reverb+20 : rvb[0].IIR_DEST_A0=(s16)val; break; - case H_Reverb+22 : rvb[0].IIR_DEST_A1=(s16)val; break; - case H_Reverb+24 : rvb[0].ACC_SRC_A0=(s16)val; break; - case H_Reverb+26 : rvb[0].ACC_SRC_A1=(s16)val; break; - case H_Reverb+28 : rvb[0].ACC_SRC_B0=(s16)val; break; - case H_Reverb+30 : rvb[0].ACC_SRC_B1=(s16)val; break; - case H_Reverb+32 : rvb[0].IIR_SRC_A0=(s16)val; break; - case H_Reverb+34 : rvb[0].IIR_SRC_A1=(s16)val; break; - case H_Reverb+36 : rvb[0].IIR_DEST_B0=(s16)val; break; - case H_Reverb+38 : rvb[0].IIR_DEST_B1=(s16)val; break; - case H_Reverb+40 : rvb[0].ACC_SRC_C0=(s16)val; break; - case H_Reverb+42 : rvb[0].ACC_SRC_C1=(s16)val; break; - case H_Reverb+44 : rvb[0].ACC_SRC_D0=(s16)val; break; - case H_Reverb+46 : rvb[0].ACC_SRC_D1=(s16)val; break; - case H_Reverb+48 : rvb[0].IIR_SRC_B1=(s16)val; break; - case H_Reverb+50 : rvb[0].IIR_SRC_B0=(s16)val; break; - case H_Reverb+52 : rvb[0].MIX_DEST_A0=(s16)val; break; - case H_Reverb+54 : rvb[0].MIX_DEST_A1=(s16)val; break; - case H_Reverb+56 : rvb[0].MIX_DEST_B0=(s16)val; break; - case H_Reverb+58 : rvb[0].MIX_DEST_B1=(s16)val; break; - case H_Reverb+60 : rvb[0].IN_COEF_L=(s16)val; break; - case H_Reverb+62 : rvb[0].IN_COEF_R=(s16)val; break; + spu->rvb[0].FB_SRC_A=val; + break; + + case H_Reverb+2 : spu->rvb[0].FB_SRC_B=(s16)val; break; + case H_Reverb+4 : spu->rvb[0].IIR_ALPHA=(s16)val; break; + case H_Reverb+6 : spu->rvb[0].ACC_COEF_A=(s16)val; break; + case H_Reverb+8 : spu->rvb[0].ACC_COEF_B=(s16)val; break; + case H_Reverb+10 : spu->rvb[0].ACC_COEF_C=(s16)val; break; + case H_Reverb+12 : spu->rvb[0].ACC_COEF_D=(s16)val; break; + case H_Reverb+14 : spu->rvb[0].IIR_COEF=(s16)val; break; + case H_Reverb+16 : spu->rvb[0].FB_ALPHA=(s16)val; break; + case H_Reverb+18 : spu->rvb[0].FB_X=(s16)val; break; + case H_Reverb+20 : spu->rvb[0].IIR_DEST_A0=(s16)val; break; + case H_Reverb+22 : spu->rvb[0].IIR_DEST_A1=(s16)val; break; + case H_Reverb+24 : spu->rvb[0].ACC_SRC_A0=(s16)val; break; + case H_Reverb+26 : spu->rvb[0].ACC_SRC_A1=(s16)val; break; + case H_Reverb+28 : spu->rvb[0].ACC_SRC_B0=(s16)val; break; + case H_Reverb+30 : spu->rvb[0].ACC_SRC_B1=(s16)val; break; + case H_Reverb+32 : spu->rvb[0].IIR_SRC_A0=(s16)val; break; + case H_Reverb+34 : spu->rvb[0].IIR_SRC_A1=(s16)val; break; + case H_Reverb+36 : spu->rvb[0].IIR_DEST_B0=(s16)val; break; + case H_Reverb+38 : spu->rvb[0].IIR_DEST_B1=(s16)val; break; + case H_Reverb+40 : spu->rvb[0].ACC_SRC_C0=(s16)val; break; + case H_Reverb+42 : spu->rvb[0].ACC_SRC_C1=(s16)val; break; + case H_Reverb+44 : spu->rvb[0].ACC_SRC_D0=(s16)val; break; + case H_Reverb+46 : spu->rvb[0].ACC_SRC_D1=(s16)val; break; + case H_Reverb+48 : spu->rvb[0].IIR_SRC_B1=(s16)val; break; + case H_Reverb+50 : spu->rvb[0].IIR_SRC_B0=(s16)val; break; + case H_Reverb+52 : spu->rvb[0].MIX_DEST_A0=(s16)val; break; + case H_Reverb+54 : spu->rvb[0].MIX_DEST_A1=(s16)val; break; + case H_Reverb+56 : spu->rvb[0].MIX_DEST_B0=(s16)val; break; + case H_Reverb+58 : spu->rvb[0].MIX_DEST_B1=(s16)val; break; + case H_Reverb+60 : spu->rvb[0].IN_COEF_L=(s16)val; break; + case H_Reverb+62 : spu->rvb[0].IN_COEF_R=(s16)val; break; } } EXPORT_GCC unsigned short CALLBACK SPU2readPS1Port(mips_cpu_context *cpu, unsigned long reg) { + spu2_state_t *spu = cpu->spu2; const u32 r=reg&0xfff; if(r>=0x0c00 && r<0x0d80) @@ -1087,24 +1085,24 @@ EXPORT_GCC unsigned short CALLBACK SPU2readPS1Port(mips_cpu_context *cpu, unsign break; case H_SPUstat: - return spuStat2[0]; + return spu->spuStat2[0]; break; case H_SPUaddr: - return (u16)(spuAddr2[0]>>2); + return (u16)(spu->spuAddr2[0]>>2); break; case H_SPUdata: { - u16 s=BFLIP16(spuMem[spuAddr2[0]]); - spuAddr2[0]++; - if(spuAddr2[0]>0xfffff) spuAddr2[0]=0; + u16 s=BFLIP16(spu->spuMem[spu->spuAddr2[0]]); + spu->spuAddr2[0]++; + if(spu->spuAddr2[0]>0xfffff) spu->spuAddr2[0]=0; return s; } break; case H_SPUirqAddr: - return spuIrq2[0]>>2; + return spu->spuIrq2[0]>>2; break; } @@ -1115,17 +1113,17 @@ EXPORT_GCC unsigned short CALLBACK SPU2readPS1Port(mips_cpu_context *cpu, unsign // SOUND ON register write //////////////////////////////////////////////////////////////////////// -void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND +void SoundOn(spu2_state_t *spu, int start,int end,unsigned short val) // SOUND ON PSX COMAND { int ch; for(ch=start;ch<end;ch++,val>>=1) // loop channels { - if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?! + if((val&1) && spu->s_chan[ch].pStart) // mmm... start has to be set before key on !?! { - s_chan[ch].bIgnoreLoop=0; - s_chan[ch].bNew=1; - dwNewChannel2[ch/24]|=(1<<(ch%24)); // bitfield for faster testing + spu->s_chan[ch].bIgnoreLoop=0; + spu->s_chan[ch].bNew=1; + spu->dwNewChannel2[ch/24]|=(1<<(ch%24)); // bitfield for faster testing } } } @@ -1134,14 +1132,14 @@ void SoundOn(int start,int end,unsigned short val) // SOUND ON PSX COMAND // SOUND OFF register write //////////////////////////////////////////////////////////////////////// -void SoundOff(int start,int end,unsigned short val) // SOUND OFF PSX COMMAND +void SoundOff(spu2_state_t *spu, int start,int end,unsigned short val) // SOUND OFF PSX COMMAND { int ch; for(ch=start;ch<end;ch++,val>>=1) // loop channels { - if(val&1) // && s_chan[i].bOn) mmm... + if(val&1) // && spu->s_chan[i].bOn) mmm... { - s_chan[ch].bStop=1; + spu->s_chan[ch].bStop=1; } } } @@ -1150,7 +1148,7 @@ void SoundOff(int start,int end,unsigned short val) // SOUND OFF PSX COMMAND // FMOD register write //////////////////////////////////////////////////////////////////////// -void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND +void FModOn(spu2_state_t *spu, int start,int end,unsigned short val) // FMOD ON PSX COMMAND { int ch; @@ -1160,13 +1158,13 @@ void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND { if(ch>0) { - s_chan[ch].bFMod=1; // --> sound channel - s_chan[ch-1].bFMod=2; // --> freq channel + spu->s_chan[ch].bFMod=1; // --> sound channel + spu->s_chan[ch-1].bFMod=2; // --> freq channel } } else { - s_chan[ch].bFMod=0; // --> turn off fmod + spu->s_chan[ch].bFMod=0; // --> turn off fmod } } } @@ -1175,7 +1173,7 @@ void FModOn(int start,int end,unsigned short val) // FMOD ON PSX COMMAND // NOISE register write //////////////////////////////////////////////////////////////////////// -void NoiseOn(int start,int end,unsigned short val) // NOISE ON PSX COMMAND +void NoiseOn(spu2_state_t *spu, int start,int end,unsigned short val) // NOISE ON PSX COMMAND { int ch; @@ -1183,11 +1181,11 @@ void NoiseOn(int start,int end,unsigned short val) // NOISE ON PSX COMMAND { if(val&1) // -> noise on/off { - s_chan[ch].bNoise=1; + spu->s_chan[ch].bNoise=1; } else { - s_chan[ch].bNoise=0; + spu->s_chan[ch].bNoise=0; } } } @@ -1199,9 +1197,9 @@ void NoiseOn(int start,int end,unsigned short val) // NOISE ON PSX COMMAND // please note: sweep and phase invert are wrong... but I've never seen // them used -void SetVolumeL(unsigned char ch,short vol) // LEFT VOLUME +void SetVolumeL(spu2_state_t *spu, unsigned char ch,short vol) // LEFT VOLUME { - s_chan[ch].iLeftVolRaw=vol; + spu->s_chan[ch].iLeftVolRaw=vol; if(vol&0x8000) // sweep? { @@ -1220,16 +1218,16 @@ void SetVolumeL(unsigned char ch,short vol) // LEFT VOLUME } vol&=0x3fff; - s_chan[ch].iLeftVolume=vol; // store volume + spu->s_chan[ch].iLeftVolume=vol; // store volume } //////////////////////////////////////////////////////////////////////// // RIGHT VOLUME register write //////////////////////////////////////////////////////////////////////// -void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME +void SetVolumeR(spu2_state_t *spu, unsigned char ch,short vol) // RIGHT VOLUME { - s_chan[ch].iRightVolRaw=vol; + spu->s_chan[ch].iRightVolRaw=vol; if(vol&0x8000) // comments... see above :) { @@ -1247,14 +1245,14 @@ void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME } vol&=0x3fff; - s_chan[ch].iRightVolume=vol; + spu->s_chan[ch].iRightVolume=vol; } //////////////////////////////////////////////////////////////////////// // PITCH register write //////////////////////////////////////////////////////////////////////// -void SetPitch(int ch,unsigned short val) // SET PITCH +void SetPitch(spu2_state_t *spu, int ch,unsigned short val) // SET PITCH { int NP; double intr; @@ -1265,19 +1263,19 @@ void SetPitch(int ch,unsigned short val) // SET PITCH intr = (double)48000.0f / (double)44100.0f * (double)NP; NP = (UINT32)intr; - s_chan[ch].iRawPitch=NP; + spu->s_chan[ch].iRawPitch=NP; NP=(44100L*NP)/4096L; // calc frequency if(NP<1) NP=1; // some security - s_chan[ch].iActFreq=NP; // store frequency + spu->s_chan[ch].iActFreq=NP; // store frequency } //////////////////////////////////////////////////////////////////////// // REVERB register write //////////////////////////////////////////////////////////////////////// -void ReverbOn(int start,int end,unsigned short val,int iRight) // REVERB ON PSX COMMAND +void ReverbOn(spu2_state_t *spu, int start,int end,unsigned short val,int iRight) // REVERB ON PSX COMMAND { int ch; @@ -1285,13 +1283,13 @@ void ReverbOn(int start,int end,unsigned short val,int iRight) // REVERB ON PSX { if(val&1) // -> reverb on/off { - if(iRight) s_chan[ch].bReverbR=1; - else s_chan[ch].bReverbL=1; + if(iRight) spu->s_chan[ch].bReverbR=1; + else spu->s_chan[ch].bReverbL=1; } else { - if(iRight) s_chan[ch].bReverbR=0; - else s_chan[ch].bReverbL=0; + if(iRight) spu->s_chan[ch].bReverbR=0; + else spu->s_chan[ch].bReverbL=0; } } } @@ -1300,20 +1298,20 @@ void ReverbOn(int start,int end,unsigned short val,int iRight) // REVERB ON PSX // REVERB START register write //////////////////////////////////////////////////////////////////////// -void SetReverbAddr(int core) +void SetReverbAddr(spu2_state_t *spu, int core) { - long val=spuRvbAddr2[core]; + long val=spu->spuRvbAddr2[core]; - if(rvb[core].StartAddr!=val) + if(spu->rvb[core].StartAddr!=val) { if(val<=0x27ff) { - rvb[core].StartAddr=rvb[core].CurrAddr=0; + spu->rvb[core].StartAddr=spu->rvb[core].CurrAddr=0; } else { - rvb[core].StartAddr=val; - rvb[core].CurrAddr=rvb[core].StartAddr; + spu->rvb[core].StartAddr=val; + spu->rvb[core].CurrAddr=spu->rvb[core].StartAddr; } } } @@ -1322,7 +1320,7 @@ void SetReverbAddr(int core) // DRY LEFT/RIGHT per voice switches //////////////////////////////////////////////////////////////////////// -void VolumeOn(int start,int end,unsigned short val,int iRight) // VOLUME ON PSX COMMAND +void VolumeOn(spu2_state_t *spu, int start,int end,unsigned short val,int iRight) // VOLUME ON PSX COMMAND { int ch; @@ -1330,13 +1328,13 @@ void VolumeOn(int start,int end,unsigned short val,int iRight) // VOLUME ON PSX { if(val&1) // -> reverb on/off { - if(iRight) s_chan[ch].bVolumeR=1; - else s_chan[ch].bVolumeL=1; + if(iRight) spu->s_chan[ch].bVolumeR=1; + else spu->s_chan[ch].bVolumeL=1; } else { - if(iRight) s_chan[ch].bVolumeR=0; - else s_chan[ch].bVolumeL=0; + if(iRight) spu->s_chan[ch].bVolumeR=0; + else spu->s_chan[ch].bVolumeL=0; } } } diff --git a/plugins/ao/eng_psf/peops2/regs.h b/plugins/ao/eng_psf/peops2/regs.h index 5136b77a..0e795ed7 100644 --- a/plugins/ao/eng_psf/peops2/regs.h +++ b/plugins/ao/eng_psf/peops2/regs.h @@ -27,17 +27,18 @@ //
//*************************************************************************//
+struct spu2_state_s;
-void SoundOn(int start,int end,unsigned short val);
-void SoundOff(int start,int end,unsigned short val);
-void VolumeOn(int start,int end,unsigned short val,int iRight);
-void FModOn(int start,int end,unsigned short val);
-void NoiseOn(int start,int end,unsigned short val);
-void SetVolumeL(unsigned char ch,short vol);
-void SetVolumeR(unsigned char ch,short vol);
-void SetPitch(int ch,unsigned short val);
-void ReverbOn(int start,int end,unsigned short val,int iRight);
-void SetReverbAddr(int core);
+void SoundOn(struct spu2_state_s *spu, int start,int end,unsigned short val);
+void SoundOff(struct spu2_state_s *spu, int start,int end,unsigned short val);
+void VolumeOn(struct spu2_state_s *spu, int start,int end,unsigned short val,int iRight);
+void FModOn(struct spu2_state_s *spu, int start,int end,unsigned short val);
+void NoiseOn(struct spu2_state_s *spu, int start,int end,unsigned short val);
+void SetVolumeL(struct spu2_state_s *spu, unsigned char ch,short vol);
+void SetVolumeR(struct spu2_state_s *spu, unsigned char ch,short vol);
+void SetPitch(struct spu2_state_s *spu, int ch,unsigned short val);
+void ReverbOn(struct spu2_state_s *spu, int start,int end,unsigned short val,int iRight);
+void SetReverbAddr(struct spu2_state_s *spu, int core);
//EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val);
diff --git a/plugins/ao/eng_psf/peops2/reverb2.c b/plugins/ao/eng_psf/peops2/reverb2.c index da37ef90..ceab8c54 100644 --- a/plugins/ao/eng_psf/peops2/reverb2.c +++ b/plugins/ao/eng_psf/peops2/reverb2.c @@ -47,37 +47,31 @@ // globals
////////////////////////////////////////////////////////////////////////
-// REVERB info and timing vars...
-
-int * sRVBPlay[2];
-int * sRVBEnd[2];
-int * sRVBStart[2];
-
////////////////////////////////////////////////////////////////////////
// START REVERB
////////////////////////////////////////////////////////////////////////
-INLINE void StartREVERB(int ch)
+INLINE void StartREVERB(spu2_state_t *spu, int ch)
{
int core=ch/24;
- if((s_chan[ch].bReverbL || s_chan[ch].bReverbR) && (spuCtrl2[core]&0x80)) // reverb possible?
+ if((spu->s_chan[ch].bReverbL || spu->s_chan[ch].bReverbR) && (spu->spuCtrl2[core]&0x80)) // reverb possible?
{
- if(iUseReverb==1) s_chan[ch].bRVBActive=1;
+ if(spu->iUseReverb==1) spu->s_chan[ch].bRVBActive=1;
}
- else s_chan[ch].bRVBActive=0; // else -> no reverb
+ else spu->s_chan[ch].bRVBActive=0; // else -> no reverb
}
////////////////////////////////////////////////////////////////////////
// HELPER FOR NEILL'S REVERB: re-inits our reverb mixing buf
////////////////////////////////////////////////////////////////////////
-INLINE void InitREVERB(void)
+INLINE void InitREVERB(spu2_state_t *spu)
{
- if(iUseReverb==1)
+ if(spu->iUseReverb==1)
{
- memset(sRVBStart[0],0,NSSIZE*2*4);
- memset(sRVBStart[1],0,NSSIZE*2*4);
+ memset(spu->sRVBStart[0],0,NSSIZE*2*4);
+ memset(spu->sRVBStart[1],0,NSSIZE*2*4);
}
}
@@ -85,154 +79,154 @@ INLINE void InitREVERB(void) // STORE REVERB
////////////////////////////////////////////////////////////////////////
-INLINE void StoreREVERB(int ch,int ns)
+INLINE void StoreREVERB(spu2_state_t *spu, int ch,int ns)
{
int core=ch/24;
- if(iUseReverb==0) return;
+ if(spu->iUseReverb==0) return;
else
- if(iUseReverb==1) // -------------------------------- // Neil's reverb
+ if(spu->iUseReverb==1) // -------------------------------- // Neil's reverb
{
- const int iRxl=(s_chan[ch].sval*s_chan[ch].iLeftVolume*s_chan[ch].bReverbL)/0x4000;
- const int iRxr=(s_chan[ch].sval*s_chan[ch].iRightVolume*s_chan[ch].bReverbR)/0x4000;
+ const int iRxl=(spu->s_chan[ch].sval*spu->s_chan[ch].iLeftVolume*spu->s_chan[ch].bReverbL)/0x4000;
+ const int iRxr=(spu->s_chan[ch].sval*spu->s_chan[ch].iRightVolume*spu->s_chan[ch].bReverbR)/0x4000;
ns<<=1;
- *(sRVBStart[core]+ns) +=iRxl; // -> we mix all active reverb channels into an extra buffer
- *(sRVBStart[core]+ns+1)+=iRxr;
+ *(spu->sRVBStart[core]+ns) +=iRxl; // -> we mix all active reverb channels into an extra buffer
+ *(spu->sRVBStart[core]+ns+1)+=iRxr;
}
}
////////////////////////////////////////////////////////////////////////
-INLINE int g_buffer(int iOff,int core) // get_buffer content helper: takes care about wraps
+INLINE int g_buffer(spu2_state_t *spu, int iOff,int core) // get_buffer content helper: takes care about wraps
{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ short * p=(short *)spu->spuMem;
+ iOff=(iOff)+spu->rvb[core].CurrAddr;
+ while(iOff>spu->rvb[core].EndAddr) iOff=spu->rvb[core].StartAddr+(iOff-(spu->rvb[core].EndAddr+1));
+ while(iOff<spu->rvb[core].StartAddr) iOff=spu->rvb[core].EndAddr-(spu->rvb[core].StartAddr-iOff);
return (int)*(p+iOff);
}
////////////////////////////////////////////////////////////////////////
-INLINE void s_buffer(int iOff,int iVal,int core) // set_buffer content helper: takes care about wraps and clipping
+INLINE void s_buffer(spu2_state_t *spu, int iOff,int iVal,int core) // set_buffer content helper: takes care about wraps and clipping
{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ short * p=(short *)spu->spuMem;
+ iOff=(iOff)+spu->rvb[core].CurrAddr;
+ while(iOff>spu->rvb[core].EndAddr) iOff=spu->rvb[core].StartAddr+(iOff-(spu->rvb[core].EndAddr+1));
+ while(iOff<spu->rvb[core].StartAddr) iOff=spu->rvb[core].EndAddr-(spu->rvb[core].StartAddr-iOff);
if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
*(p+iOff)=(short)iVal;
}
////////////////////////////////////////////////////////////////////////
-INLINE void s_buffer1(int iOff,int iVal,int core) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
+INLINE void s_buffer1(spu2_state_t *spu, int iOff,int iVal,int core) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
{
- short * p=(short *)spuMem;
- iOff=(iOff)+rvb[core].CurrAddr+1;
- while(iOff>rvb[core].EndAddr) iOff=rvb[core].StartAddr+(iOff-(rvb[core].EndAddr+1));
- while(iOff<rvb[core].StartAddr) iOff=rvb[core].EndAddr-(rvb[core].StartAddr-iOff);
+ short * p=(short *)spu->spuMem;
+ iOff=(iOff)+spu->rvb[core].CurrAddr+1;
+ while(iOff>spu->rvb[core].EndAddr) iOff=spu->rvb[core].StartAddr+(iOff-(spu->rvb[core].EndAddr+1));
+ while(iOff<spu->rvb[core].StartAddr) iOff=spu->rvb[core].EndAddr-(spu->rvb[core].StartAddr-iOff);
if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L;
*(p+iOff)=(short)iVal;
}
////////////////////////////////////////////////////////////////////////
-INLINE int MixREVERBLeft(int ns,int core)
+INLINE int MixREVERBLeft(spu2_state_t *spu, int ns,int core)
{
- if(iUseReverb==1)
+ if(spu->iUseReverb==1)
{
- if(!rvb[core].StartAddr || !rvb[core].EndAddr ||
- rvb[core].StartAddr>=rvb[core].EndAddr) // reverb is off
+ if(!spu->rvb[core].StartAddr || !spu->rvb[core].EndAddr ||
+ spu->rvb[core].StartAddr>=spu->rvb[core].EndAddr) // reverb is off
{
- rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
+ spu->rvb[core].iLastRVBLeft=spu->rvb[core].iLastRVBRight=spu->rvb[core].iRVBLeft=spu->rvb[core].iRVBRight=0;
return 0;
}
- rvb[core].iCnt++;
+ spu->rvb[core].iCnt++;
- if(rvb[core].iCnt&1) // we work on every second left value: downsample to 22 khz
+ if(spu->rvb[core].iCnt&1) // we work on every second left value: downsample to 22 khz
{
- if((spuCtrl2[core]&0x80)) // -> reverb on? oki
+ if((spu->spuCtrl2[core]&0x80)) // -> reverb on? oki
{
int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
- const int INPUT_SAMPLE_L=*(sRVBStart[core]+(ns<<1));
- const int INPUT_SAMPLE_R=*(sRVBStart[core]+(ns<<1)+1);
+ const int INPUT_SAMPLE_L=*(spu->sRVBStart[core]+(ns<<1));
+ const int INPUT_SAMPLE_R=*(spu->sRVBStart[core]+(ns<<1)+1);
- const int IIR_INPUT_A0 = (g_buffer(rvb[core].IIR_SRC_A0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
- const int IIR_INPUT_A1 = (g_buffer(rvb[core].IIR_SRC_A1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
- const int IIR_INPUT_B0 = (g_buffer(rvb[core].IIR_SRC_B0,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * rvb[core].IN_COEF_L)/32768L;
- const int IIR_INPUT_B1 = (g_buffer(rvb[core].IIR_SRC_B1,core) * rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * rvb[core].IN_COEF_R)/32768L;
+ const int IIR_INPUT_A0 = (g_buffer(spu, spu->rvb[core].IIR_SRC_A0,core) * spu->rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * spu->rvb[core].IN_COEF_L)/32768L;
+ const int IIR_INPUT_A1 = (g_buffer(spu, spu->rvb[core].IIR_SRC_A1,core) * spu->rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * spu->rvb[core].IN_COEF_R)/32768L;
+ const int IIR_INPUT_B0 = (g_buffer(spu, spu->rvb[core].IIR_SRC_B0,core) * spu->rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_L * spu->rvb[core].IN_COEF_L)/32768L;
+ const int IIR_INPUT_B1 = (g_buffer(spu, spu->rvb[core].IIR_SRC_B1,core) * spu->rvb[core].IIR_COEF)/32768L + (INPUT_SAMPLE_R * spu->rvb[core].IN_COEF_R)/32768L;
- const int IIR_A0 = (IIR_INPUT_A0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_A1 = (IIR_INPUT_A1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_A1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_B0 = (IIR_INPUT_B0 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B0,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
- const int IIR_B1 = (IIR_INPUT_B1 * rvb[core].IIR_ALPHA)/32768L + (g_buffer(rvb[core].IIR_DEST_B1,core) * (32768L - rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_A0 = (IIR_INPUT_A0 * spu->rvb[core].IIR_ALPHA)/32768L + (g_buffer(spu, spu->rvb[core].IIR_DEST_A0,core) * (32768L - spu->rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_A1 = (IIR_INPUT_A1 * spu->rvb[core].IIR_ALPHA)/32768L + (g_buffer(spu, spu->rvb[core].IIR_DEST_A1,core) * (32768L - spu->rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_B0 = (IIR_INPUT_B0 * spu->rvb[core].IIR_ALPHA)/32768L + (g_buffer(spu, spu->rvb[core].IIR_DEST_B0,core) * (32768L - spu->rvb[core].IIR_ALPHA))/32768L;
+ const int IIR_B1 = (IIR_INPUT_B1 * spu->rvb[core].IIR_ALPHA)/32768L + (g_buffer(spu, spu->rvb[core].IIR_DEST_B1,core) * (32768L - spu->rvb[core].IIR_ALPHA))/32768L;
- s_buffer1(rvb[core].IIR_DEST_A0, IIR_A0,core);
- s_buffer1(rvb[core].IIR_DEST_A1, IIR_A1,core);
- s_buffer1(rvb[core].IIR_DEST_B0, IIR_B0,core);
- s_buffer1(rvb[core].IIR_DEST_B1, IIR_B1,core);
+ s_buffer1(spu, spu->rvb[core].IIR_DEST_A0, IIR_A0,core);
+ s_buffer1(spu, spu->rvb[core].IIR_DEST_A1, IIR_A1,core);
+ s_buffer1(spu, spu->rvb[core].IIR_DEST_B0, IIR_B0,core);
+ s_buffer1(spu, spu->rvb[core].IIR_DEST_B1, IIR_B1,core);
- ACC0 = (g_buffer(rvb[core].ACC_SRC_A0,core) * rvb[core].ACC_COEF_A)/32768L +
- (g_buffer(rvb[core].ACC_SRC_B0,core) * rvb[core].ACC_COEF_B)/32768L +
- (g_buffer(rvb[core].ACC_SRC_C0,core) * rvb[core].ACC_COEF_C)/32768L +
- (g_buffer(rvb[core].ACC_SRC_D0,core) * rvb[core].ACC_COEF_D)/32768L;
- ACC1 = (g_buffer(rvb[core].ACC_SRC_A1,core) * rvb[core].ACC_COEF_A)/32768L +
- (g_buffer(rvb[core].ACC_SRC_B1,core) * rvb[core].ACC_COEF_B)/32768L +
- (g_buffer(rvb[core].ACC_SRC_C1,core) * rvb[core].ACC_COEF_C)/32768L +
- (g_buffer(rvb[core].ACC_SRC_D1,core) * rvb[core].ACC_COEF_D)/32768L;
-
- FB_A0 = g_buffer(rvb[core].MIX_DEST_A0 - rvb[core].FB_SRC_A,core);
- FB_A1 = g_buffer(rvb[core].MIX_DEST_A1 - rvb[core].FB_SRC_A,core);
- FB_B0 = g_buffer(rvb[core].MIX_DEST_B0 - rvb[core].FB_SRC_B,core);
- FB_B1 = g_buffer(rvb[core].MIX_DEST_B1 - rvb[core].FB_SRC_B,core);
-
- s_buffer(rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * rvb[core].FB_ALPHA)/32768L,core);
- s_buffer(rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * rvb[core].FB_ALPHA)/32768L,core);
+ ACC0 = (g_buffer(spu, spu->rvb[core].ACC_SRC_A0,core) * spu->rvb[core].ACC_COEF_A)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_B0,core) * spu->rvb[core].ACC_COEF_B)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_C0,core) * spu->rvb[core].ACC_COEF_C)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_D0,core) * spu->rvb[core].ACC_COEF_D)/32768L;
+ ACC1 = (g_buffer(spu, spu->rvb[core].ACC_SRC_A1,core) * spu->rvb[core].ACC_COEF_A)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_B1,core) * spu->rvb[core].ACC_COEF_B)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_C1,core) * spu->rvb[core].ACC_COEF_C)/32768L +
+ (g_buffer(spu, spu->rvb[core].ACC_SRC_D1,core) * spu->rvb[core].ACC_COEF_D)/32768L;
+
+ FB_A0 = g_buffer(spu, spu->rvb[core].MIX_DEST_A0 - spu->rvb[core].FB_SRC_A,core);
+ FB_A1 = g_buffer(spu, spu->rvb[core].MIX_DEST_A1 - spu->rvb[core].FB_SRC_A,core);
+ FB_B0 = g_buffer(spu, spu->rvb[core].MIX_DEST_B0 - spu->rvb[core].FB_SRC_B,core);
+ FB_B1 = g_buffer(spu, spu->rvb[core].MIX_DEST_B1 - spu->rvb[core].FB_SRC_B,core);
+
+ s_buffer(spu, spu->rvb[core].MIX_DEST_A0, ACC0 - (FB_A0 * spu->rvb[core].FB_ALPHA)/32768L,core);
+ s_buffer(spu, spu->rvb[core].MIX_DEST_A1, ACC1 - (FB_A1 * spu->rvb[core].FB_ALPHA)/32768L,core);
- s_buffer(rvb[core].MIX_DEST_B0, (rvb[core].FB_ALPHA * ACC0)/32768L - (FB_A0 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B0 * rvb[core].FB_X)/32768L,core);
- s_buffer(rvb[core].MIX_DEST_B1, (rvb[core].FB_ALPHA * ACC1)/32768L - (FB_A1 * (int)(rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B1 * rvb[core].FB_X)/32768L,core);
+ s_buffer(spu, spu->rvb[core].MIX_DEST_B0, (spu->rvb[core].FB_ALPHA * ACC0)/32768L - (FB_A0 * (int)(spu->rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B0 * spu->rvb[core].FB_X)/32768L,core);
+ s_buffer(spu, spu->rvb[core].MIX_DEST_B1, (spu->rvb[core].FB_ALPHA * ACC1)/32768L - (FB_A1 * (int)(spu->rvb[core].FB_ALPHA^0xFFFF8000))/32768L - (FB_B1 * spu->rvb[core].FB_X)/32768L,core);
- rvb[core].iLastRVBLeft = rvb[core].iRVBLeft;
- rvb[core].iLastRVBRight = rvb[core].iRVBRight;
+ spu->rvb[core].iLastRVBLeft = spu->rvb[core].iRVBLeft;
+ spu->rvb[core].iLastRVBRight = spu->rvb[core].iRVBRight;
- rvb[core].iRVBLeft = (g_buffer(rvb[core].MIX_DEST_A0,core)+g_buffer(rvb[core].MIX_DEST_B0,core))/3;
- rvb[core].iRVBRight = (g_buffer(rvb[core].MIX_DEST_A1,core)+g_buffer(rvb[core].MIX_DEST_B1,core))/3;
+ spu->rvb[core].iRVBLeft = (g_buffer(spu, spu->rvb[core].MIX_DEST_A0,core)+g_buffer(spu, spu->rvb[core].MIX_DEST_B0,core))/3;
+ spu->rvb[core].iRVBRight = (g_buffer(spu, spu->rvb[core].MIX_DEST_A1,core)+g_buffer(spu, spu->rvb[core].MIX_DEST_B1,core))/3;
- rvb[core].iRVBLeft = (rvb[core].iRVBLeft * rvb[core].VolLeft) / 0x4000;
- rvb[core].iRVBRight = (rvb[core].iRVBRight * rvb[core].VolRight) / 0x4000;
+ spu->rvb[core].iRVBLeft = (spu->rvb[core].iRVBLeft * spu->rvb[core].VolLeft) / 0x4000;
+ spu->rvb[core].iRVBRight = (spu->rvb[core].iRVBRight * spu->rvb[core].VolRight) / 0x4000;
- rvb[core].CurrAddr++;
- if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
+ spu->rvb[core].CurrAddr++;
+ if(spu->rvb[core].CurrAddr>spu->rvb[core].EndAddr) spu->rvb[core].CurrAddr=spu->rvb[core].StartAddr;
- return rvb[core].iLastRVBLeft+(rvb[core].iRVBLeft-rvb[core].iLastRVBLeft)/2;
+ return spu->rvb[core].iLastRVBLeft+(spu->rvb[core].iRVBLeft-spu->rvb[core].iLastRVBLeft)/2;
}
else // -> reverb off
{
- rvb[core].iLastRVBLeft=rvb[core].iLastRVBRight=rvb[core].iRVBLeft=rvb[core].iRVBRight=0;
+ spu->rvb[core].iLastRVBLeft=spu->rvb[core].iLastRVBRight=spu->rvb[core].iRVBLeft=spu->rvb[core].iRVBRight=0;
}
- rvb[core].CurrAddr++;
- if(rvb[core].CurrAddr>rvb[core].EndAddr) rvb[core].CurrAddr=rvb[core].StartAddr;
+ spu->rvb[core].CurrAddr++;
+ if(spu->rvb[core].CurrAddr>spu->rvb[core].EndAddr) spu->rvb[core].CurrAddr=spu->rvb[core].StartAddr;
}
- return rvb[core].iLastRVBLeft;
+ return spu->rvb[core].iLastRVBLeft;
}
return 0;
}
////////////////////////////////////////////////////////////////////////
-INLINE int MixREVERBRight(int core)
+INLINE int MixREVERBRight(spu2_state_t *spu, int core)
{
- if(iUseReverb==1) // Neill's reverb:
+ if(spu->iUseReverb==1) // Neill's reverb:
{
- int i=rvb[core].iLastRVBRight+(rvb[core].iRVBRight-rvb[core].iLastRVBRight)/2;
- rvb[core].iLastRVBRight=rvb[core].iRVBRight;
+ int i=spu->rvb[core].iLastRVBRight+(spu->rvb[core].iRVBRight-spu->rvb[core].iLastRVBRight)/2;
+ spu->rvb[core].iLastRVBRight=spu->rvb[core].iRVBRight;
return i; // -> just return the last right reverb val (little bit scaled by the previous right val)
}
return 0;
diff --git a/plugins/ao/eng_psf/peops2/spu.h b/plugins/ao/eng_psf/peops2/spu.h index be69a4ea..0400e306 100644 --- a/plugins/ao/eng_psf/peops2/spu.h +++ b/plugins/ao/eng_psf/peops2/spu.h @@ -1,41 +1,109 @@ -/***************************************************************************
- spu.h - description
- -------------------
- begin : Wed May 15 2002
- copyright : (C) 2002 by Pete Bernert
- email : BlackDove@addcom.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. See also the license.txt file for *
- * additional informations. *
- * *
- ***************************************************************************/
-
-//*************************************************************************//
-// History of changes:
-//
-// 2004/04/04 - Pete
-// - changed plugin to emulate PS2 spu
-//
-// 2002/05/15 - Pete
-// - generic cleanup for the Peops release
-//
-//*************************************************************************//
+/*************************************************************************** + spu.h - description + ------------------- + begin : Wed May 15 2002 + copyright : (C) 2002 by Pete Bernert + email : BlackDove@addcom.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. See also the license.txt file for * + * additional informations. * + * * + ***************************************************************************/ + +//*************************************************************************// +// History of changes: +// +// 2004/04/04 - Pete +// - changed plugin to emulate PS2 spu +// +// 2002/05/15 - Pete +// - generic cleanup for the Peops release +// +//*************************************************************************// #include "../psx.h" -
-
-//void SetupTimer(mips_cpu_context *cpu);
-//void RemoveTimer(mips_cpu_context *cpu);
-//EXPORT_GCC void CALLBACK SPU2playADPCMchannel(mips_cpu_context *cpu, xa_decode_t *xap);
-
+ +typedef struct spu2_state_s { + // psx buffer / addresses + + unsigned short regArea[32*1024]; + unsigned short spuMem[1*1024*1024]; + unsigned char * spuMemC; + unsigned char * pSpuIrq[2]; + unsigned char * pSpuBuffer; + + // user settings + + int iUseXA;//=0; + int iVolume;//=3; + int iXAPitch;//=1; + int iUseTimer;//=2; + int iSPUIRQWait;//=1; + int iDebugMode;//=0; + int iRecordMode;//=0; + int iUseReverb;//=1; + int iUseInterpolation;//=2; + + // MAIN infos struct for each channel + + SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) + REVERBInfo rvb[2]; + + unsigned long dwNoiseVal;//=1; // global noise generator + + unsigned short spuCtrl2[2]; // some vars to store psx reg infos + unsigned short spuStat2[2]; + unsigned long spuIrq2[2]; + unsigned long spuAddr2[2]; // address into spu mem + unsigned long spuRvbAddr2[2]; + unsigned long spuRvbAEnd2[2]; + int bEndThread; // thread handlers + int bThreadEnded; + int bSpuInit; + int bSPUIsOpen; + + unsigned long dwNewChannel2[2]; // flags for faster testing, if new channel starts + unsigned long dwEndChannel2[2]; + + // UNUSED IN PS2 YET + void (CALLBACK *irqCallback)(void); // func of main emu, called on spu irq + void (CALLBACK *cddavCallback)(unsigned short,unsigned short); + + int SSumR[NSSIZE]; + int SSumL[NSSIZE]; + int iCycle; + short * pS; + + int lastch;//=-1; // last channel processed on spu irq in timer mode + int lastns; // last ns pos + int iSecureStart; // secure start counter + + u32 sampcount; + u32 decaybegin; + u32 decayend; + + // REVERB info and timing vars... + int * sRVBPlay[2]; + int * sRVBEnd[2]; + int * sRVBStart[2]; + + int iSpuAsyncWait; +} spu2_state_t; + + +//void SetupTimer(mips_cpu_context *cpu); +//void RemoveTimer(mips_cpu_context *cpu); +//EXPORT_GCC void CALLBACK SPU2playADPCMchannel(mips_cpu_context *cpu, xa_decode_t *xap); + EXPORT_GCC long CALLBACK SPU2init(mips_cpu_context *cpu, void (*callback)(unsigned char *, long, void *), void *data); -EXPORT_GCC long CALLBACK SPU2open(mips_cpu_context *cpu, void *pDsp);
-EXPORT_GCC void CALLBACK SPU2async(mips_cpu_context *cpu, unsigned long cycle);
+EXPORT_GCC long CALLBACK SPU2open(mips_cpu_context *cpu, void *pDsp); +EXPORT_GCC void CALLBACK SPU2async(mips_cpu_context *cpu, unsigned long cycle); EXPORT_GCC void CALLBACK SPU2close(mips_cpu_context *cpu); +void setlength2(spu2_state_t *spu, s32 stop, s32 fade); diff --git a/plugins/ao/eng_psf/peops2/spu2.c b/plugins/ao/eng_psf/peops2/spu2.c index 4ae14247..5b7ae050 100644 --- a/plugins/ao/eng_psf/peops2/spu2.c +++ b/plugins/ao/eng_psf/peops2/spu2.c @@ -99,6 +99,7 @@ #define _IN_SPU +#include "../psx.h" #include "../peops2/externals.h" #include "../peops2/regs.h" #include "../peops2/dma.h" @@ -108,50 +109,6 @@ // globals //////////////////////////////////////////////////////////////////////// -// psx buffer / addresses - -unsigned short regArea[32*1024]; -unsigned short spuMem[1*1024*1024]; -unsigned char * spuMemC; -unsigned char * pSpuIrq[2]; -unsigned char * pSpuBuffer; - -// user settings - -int iUseXA=0; -int iVolume=3; -int iXAPitch=1; -int iUseTimer=2; -int iSPUIRQWait=1; -int iDebugMode=0; -int iRecordMode=0; -int iUseReverb=1; -int iUseInterpolation=2; - -// MAIN infos struct for each channel - -SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) -REVERBInfo rvb[2]; - -unsigned long dwNoiseVal=1; // global noise generator - -unsigned short spuCtrl2[2]; // some vars to store psx reg infos -unsigned short spuStat2[2]; -unsigned long spuIrq2[2]; -unsigned long spuAddr2[2]; // address into spu mem -unsigned long spuRvbAddr2[2]; -unsigned long spuRvbAEnd2[2]; -int bEndThread=0; // thread handlers -int bThreadEnded=0; -int bSpuInit=0; -int bSPUIsOpen=0; - -unsigned long dwNewChannel2[2]; // flags for faster testing, if new channel starts -unsigned long dwEndChannel2[2]; - -// UNUSED IN PS2 YET -void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq -void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0; // certain globals (were local before, but with the new timeproc I need em global) @@ -160,14 +117,6 @@ const int f[5][2] = { { 0, 0 }, { 115, -52 }, { 98, -55 }, { 122, -60 } }; -int SSumR[NSSIZE]; -int SSumL[NSSIZE]; -int iCycle=0; -short * pS; - -static int lastch=-1; // last channel processed on spu irq in timer mode -static int lastns=0; // last ns pos -static int iSecureStart=0; // secure start counter //////////////////////////////////////////////////////////////////////// // CODE AREA @@ -221,69 +170,69 @@ static int iSecureStart=0; // secure start counter // -INLINE void InterpolateUp(int ch) +INLINE void InterpolateUp(spu2_state_t *spu, int ch) { - if(s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass + if(spu->s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass { - const int id1=s_chan[ch].SB[30]-s_chan[ch].SB[29]; // curr delta to next val - const int id2=s_chan[ch].SB[31]-s_chan[ch].SB[30]; // and next delta to next-next val :) + const int id1=spu->s_chan[ch].SB[30]-spu->s_chan[ch].SB[29]; // curr delta to next val + const int id2=spu->s_chan[ch].SB[31]-spu->s_chan[ch].SB[30]; // and next delta to next-next val :) - s_chan[ch].SB[32]=0; + spu->s_chan[ch].SB[32]=0; if(id1>0) // curr delta positive { if(id2<id1) - {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;} + {spu->s_chan[ch].SB[28]=id1;spu->s_chan[ch].SB[32]=2;} else if(id2<(id1<<1)) - s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L; + spu->s_chan[ch].SB[28]=(id1*spu->s_chan[ch].sinc)/0x10000L; else - s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L; + spu->s_chan[ch].SB[28]=(id1*spu->s_chan[ch].sinc)/0x20000L; } else // curr delta negative { if(id2>id1) - {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;} + {spu->s_chan[ch].SB[28]=id1;spu->s_chan[ch].SB[32]=2;} else if(id2>(id1<<1)) - s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L; + spu->s_chan[ch].SB[28]=(id1*spu->s_chan[ch].sinc)/0x10000L; else - s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L; + spu->s_chan[ch].SB[28]=(id1*spu->s_chan[ch].sinc)/0x20000L; } } else - if(s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass + if(spu->s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass { - s_chan[ch].SB[32]=0; + spu->s_chan[ch].SB[32]=0; - s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L; - if(s_chan[ch].sinc<=0x8000) - s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1)); - else s_chan[ch].SB[29]+=s_chan[ch].SB[28]; + spu->s_chan[ch].SB[28]=(spu->s_chan[ch].SB[28]*spu->s_chan[ch].sinc)/0x20000L; + if(spu->s_chan[ch].sinc<=0x8000) + spu->s_chan[ch].SB[29]=spu->s_chan[ch].SB[30]-(spu->s_chan[ch].SB[28]*((0x10000/spu->s_chan[ch].sinc)-1)); + else spu->s_chan[ch].SB[29]+=spu->s_chan[ch].SB[28]; } else // no flags? add bigger val (if possible), calc smaller step, set flag1 - s_chan[ch].SB[29]+=s_chan[ch].SB[28]; + spu->s_chan[ch].SB[29]+=spu->s_chan[ch].SB[28]; } // // even easier interpolation on downsampling, also no special filter, again just "Pete's common sense" tm // -INLINE void InterpolateDown(int ch) +INLINE void InterpolateDown(spu2_state_t *spu, int ch) { - if(s_chan[ch].sinc>=0x20000L) // we would skip at least one val? + if(spu->s_chan[ch].sinc>=0x20000L) // we would skip at least one val? { - s_chan[ch].SB[29]+=(s_chan[ch].SB[30]-s_chan[ch].SB[29])/2; // add easy weight - if(s_chan[ch].sinc>=0x30000L) // we would skip even more vals? - s_chan[ch].SB[29]+=(s_chan[ch].SB[31]-s_chan[ch].SB[30])/2;// add additional next weight + spu->s_chan[ch].SB[29]+=(spu->s_chan[ch].SB[30]-spu->s_chan[ch].SB[29])/2; // add easy weight + if(spu->s_chan[ch].sinc>=0x30000L) // we would skip even more vals? + spu->s_chan[ch].SB[29]+=(spu->s_chan[ch].SB[31]-spu->s_chan[ch].SB[30])/2;// add additional next weight } } //////////////////////////////////////////////////////////////////////// // helpers for gauss interpolation -#define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos]) -#define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3]) +#define gval0 (((short*)(&spu->s_chan[ch].SB[29]))[gpos]) +#define gval(x) (((short*)(&spu->s_chan[ch].SB[29]))[(gpos+x)&3]) #include "gauss_i.h" @@ -295,30 +244,30 @@ INLINE void InterpolateDown(int ch) // START SOUND... called by main thread to setup a new sound on a channel //////////////////////////////////////////////////////////////////////// -INLINE void StartSound(int ch) +INLINE void StartSound(spu2_state_t *spu, int ch) { - dwNewChannel2[ch/24]&=~(1<<(ch%24)); // clear new channel bit - dwEndChannel2[ch/24]&=~(1<<(ch%24)); // clear end channel bit + spu->dwNewChannel2[ch/24]&=~(1<<(ch%24)); // clear new channel bit + spu->dwEndChannel2[ch/24]&=~(1<<(ch%24)); // clear end channel bit - StartADSR(ch); - StartREVERB(ch); + StartADSR(spu, ch); + StartREVERB(spu, ch); - s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start + spu->s_chan[ch].pCurr=spu->s_chan[ch].pStart; // set sample start - s_chan[ch].s_1=0; // init mixing vars - s_chan[ch].s_2=0; - s_chan[ch].iSBPos=28; + spu->s_chan[ch].s_1=0; // init mixing vars + spu->s_chan[ch].s_2=0; + spu->s_chan[ch].iSBPos=28; - s_chan[ch].bNew=0; // init channel flags - s_chan[ch].bStop=0; - s_chan[ch].bOn=1; + spu->s_chan[ch].bNew=0; // init channel flags + spu->s_chan[ch].bStop=0; + spu->s_chan[ch].bOn=1; - s_chan[ch].SB[29]=0; // init our interpolation helpers - s_chan[ch].SB[30]=0; + spu->s_chan[ch].SB[29]=0; // init our interpolation helpers + spu->s_chan[ch].SB[30]=0; - if(iUseInterpolation>=2) // gauss interpolation? - {s_chan[ch].spos=0x30000L;s_chan[ch].SB[28]=0;} // -> start with more decoding - else {s_chan[ch].spos=0x10000L;s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding + if(spu->iUseInterpolation>=2) // gauss interpolation? + {spu->s_chan[ch].spos=0x30000L;spu->s_chan[ch].SB[28]=0;} // -> start with more decoding + else {spu->s_chan[ch].spos=0x10000L;spu->s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding } //////////////////////////////////////////////////////////////////////// @@ -327,24 +276,20 @@ INLINE void StartSound(int ch) // basically the whole sound processing is done in this fat func! //////////////////////////////////////////////////////////////////////// -static u32 sampcount; -static u32 decaybegin; -static u32 decayend; - // Counting to 65536 results in full volume offage. -void setlength2(s32 stop, s32 fade) +void setlength2(spu2_state_t *spu, s32 stop, s32 fade) { if(stop==~0) { - decaybegin=~0; + spu->decaybegin=~0; } else { stop=(stop*441)/10; fade=(fade*441)/10; - decaybegin=stop; - decayend=stop+fade; + spu->decaybegin=stop; + spu->decayend=stop+fade; } } // 5 ms waiting phase, if buffer is full and no new sound has to get started @@ -356,11 +301,10 @@ void setlength2(s32 stop, s32 fade) //////////////////////////////////////////////////////////////////////// -int iSpuAsyncWait=0; - static void *MAINThread(mips_cpu_context *cpu, int samp2run) { - int s_1,s_2,fa,voldiv=iVolume; + spu2_state_t *spu = cpu->spu2; + int s_1,s_2,fa,voldiv=spu->iVolume; unsigned char * start;unsigned int nSample; int ch,predict_nr,shift_factor,flags,d,d2,s; int gpos,bIRQReturn=0; @@ -375,12 +319,12 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) // until enuff free place is available/a new channel gets // started - if(dwNewChannel2[0] || dwNewChannel2[1]) // new channel should start immedately? + if(spu->dwNewChannel2[0] || spu->dwNewChannel2[1]) // new channel should start immedately? { // (at least one bit 0 ... MAXCHANNEL is set?) - iSecureStart++; // -> set iSecure - if(iSecureStart>5) iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance) + spu->iSecureStart++; // -> set iSecure + if(spu->iSecureStart>5) spu->iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance) } - else iSecureStart=0; // 0: no new channel should start + else spu->iSecureStart=0; // 0: no new channel should start /* if (!iSecureStart) { @@ -403,9 +347,9 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) //--------------------------------------------------// continue from irq handling in timer mode? - if(lastch>=0) // will be -1 if no continue is pending + if(spu->lastch>=0) // will be -1 if no continue is pending { - ch=lastch; lastch=-1; // -> setup all kind of vars to continue + ch=spu->lastch; spu->lastch=-1; // -> setup all kind of vars to continue goto GOON; // -> directly jump to the continue point } @@ -415,39 +359,39 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) { for(ch=0;ch<MAXCHAN;ch++) // loop em all... we will collect 1 ms of sound of each playing channel { - if(s_chan[ch].bNew) StartSound(ch); // start new sound - if(!s_chan[ch].bOn) continue; // channel not playing? next + if(spu->s_chan[ch].bNew) StartSound(spu, ch); // start new sound + if(!spu->s_chan[ch].bOn) continue; // channel not playing? next - if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency? + if(spu->s_chan[ch].iActFreq!=spu->s_chan[ch].iUsedFreq) // new psx frequency? { - s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps - s_chan[ch].sinc=s_chan[ch].iRawPitch<<4; - if(!s_chan[ch].sinc) s_chan[ch].sinc=1; - if(iUseInterpolation==1) s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag + spu->s_chan[ch].iUsedFreq=spu->s_chan[ch].iActFreq; // -> take it and calc steps + spu->s_chan[ch].sinc=spu->s_chan[ch].iRawPitch<<4; + if(!spu->s_chan[ch].sinc) spu->s_chan[ch].sinc=1; + if(spu->iUseInterpolation==1) spu->s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag } // ns=0; // while(ns<NSSIZE) // loop until 1 ms of data is reached { - while(s_chan[ch].spos>=0x10000L) + while(spu->s_chan[ch].spos>=0x10000L) { - if(s_chan[ch].iSBPos==28) // 28 reached? + if(spu->s_chan[ch].iSBPos==28) // 28 reached? { - start=s_chan[ch].pCurr; // set up the current pos + start=spu->s_chan[ch].pCurr; // set up the current pos if (start == (unsigned char*)-1) // special "stop" sign { - s_chan[ch].bOn=0; // -> turn everything off - s_chan[ch].ADSRX.lVolume=0; - s_chan[ch].ADSRX.EnvelopeVol=0; + spu->s_chan[ch].bOn=0; // -> turn everything off + spu->s_chan[ch].ADSRX.lVolume=0; + spu->s_chan[ch].ADSRX.EnvelopeVol=0; goto ENDX; // -> and done for this channel } - s_chan[ch].iSBPos=0; + spu->s_chan[ch].iSBPos=0; //////////////////////////////////////////// spu irq handler here? mmm... do it later - s_1=s_chan[ch].s_1; - s_2=s_chan[ch].s_2; + s_1=spu->s_chan[ch].s_1; + s_2=spu->s_chan[ch].s_2; predict_nr=(int)*start;start++; shift_factor=predict_nr&0xf; @@ -467,38 +411,38 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) s_2=s_1;s_1=fa; s=((d & 0xf0) << 8); - s_chan[ch].SB[nSample++]=fa; + spu->s_chan[ch].SB[nSample++]=fa; if(s&0x8000) s|=0xffff0000; fa=(s>>shift_factor); fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); s_2=s_1;s_1=fa; - s_chan[ch].SB[nSample++]=fa; + spu->s_chan[ch].SB[nSample++]=fa; } //////////////////////////////////////////// irq check - if(spuCtrl2[ch/24]&0x40) // some irq active? + if(spu->spuCtrl2[ch/24]&0x40) // some irq active? { - if((pSpuIrq[ch/24] > start-16 && // irq address reached? - pSpuIrq[ch/24] <= start) || + if((spu->pSpuIrq[ch/24] > start-16 && // irq address reached? + spu->pSpuIrq[ch/24] <= start) || ((flags&1) && // special: irq on looping addr, when stop/loop flag is set - (pSpuIrq[ch/24] > s_chan[ch].pLoop-16 && - pSpuIrq[ch/24] <= s_chan[ch].pLoop))) + (spu->pSpuIrq[ch/24] > spu->s_chan[ch].pLoop-16 && + spu->pSpuIrq[ch/24] <= spu->s_chan[ch].pLoop))) { - s_chan[ch].iIrqDone=1; // -> debug flag + spu->s_chan[ch].iIrqDone=1; // -> debug flag - if(irqCallback) irqCallback(); // -> call main emu (not supported in SPU2 right now) + if(spu->irqCallback) spu->irqCallback(); // -> call main emu (not supported in SPU2 right now) else { - if(ch<24) InterruptDMA4(); // -> let's see what is happening if we call our irqs instead ;) - else InterruptDMA7(); + if(ch<24) InterruptDMA4(cpu); // -> let's see what is happening if we call our irqs instead ;) + else InterruptDMA7(cpu); } - if(iSPUIRQWait) // -> option: wait after irq for main emu + if(spu->iSPUIRQWait) // -> option: wait after irq for main emu { - iSpuAsyncWait=1; + spu->iSpuAsyncWait=1; bIRQReturn=1; } } @@ -506,29 +450,29 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) //////////////////////////////////////////// flag handler - if((flags&4) && (!s_chan[ch].bIgnoreLoop)) - s_chan[ch].pLoop=start-16; // loop adress + if((flags&4) && (!spu->s_chan[ch].bIgnoreLoop)) + spu->s_chan[ch].pLoop=start-16; // loop adress if(flags&1) // 1: stop/loop { - dwEndChannel2[ch/24]|=(1<<(ch%24)); + spu->dwEndChannel2[ch/24]|=(1<<(ch%24)); // We play this block out first... - //if(!(flags&2)|| s_chan[ch].pLoop==NULL) + //if(!(flags&2)|| spu->s_chan[ch].pLoop==NULL) // 1+2: do loop... otherwise: stop - if(flags!=3 || s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example) + if(flags!=3 || spu->s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example) { // and checking if pLoop is set avoids crashes, yeah start = (unsigned char*)-1; } else { - start = s_chan[ch].pLoop; + start = spu->s_chan[ch].pLoop; } } - s_chan[ch].pCurr=start; // store values for next cycle - s_chan[ch].s_1=s_1; - s_chan[ch].s_2=s_2; + spu->s_chan[ch].pCurr=start; // store values for next cycle + spu->s_chan[ch].s_1=s_1; + spu->s_chan[ch].s_2=s_2; //////////////////////////////////////////// @@ -536,7 +480,7 @@ static void *MAINThread(mips_cpu_context *cpu, int samp2run) { bIRQReturn=0; { - lastch=ch; + spu->lastch=ch; // lastns=ns; // changemeback return 0; @@ -549,34 +493,34 @@ GOON: ; } - fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data + fa=spu->s_chan[ch].SB[spu->s_chan[ch].iSBPos++]; // get sample data -// if((spuCtrl2[ch/24]&0x4000)==0) fa=0; // muted? +// if((spu->spuCtrl2[ch/24]&0x4000)==0) fa=0; // muted? // else // else adjust { if(fa>32767L) fa=32767L; if(fa<-32767L) fa=-32767L; } - if(iUseInterpolation>=2) // gauss/cubic interpolation + if(spu->iUseInterpolation>=2) // gauss/cubic interpolation { - gpos = s_chan[ch].SB[28]; + gpos = spu->s_chan[ch].SB[28]; gval0 = fa; gpos = (gpos+1) & 3; - s_chan[ch].SB[28] = gpos; + spu->s_chan[ch].SB[28] = gpos; } else - if(iUseInterpolation==1) // simple interpolation + if(spu->iUseInterpolation==1) // simple interpolation { - s_chan[ch].SB[28] = 0; - s_chan[ch].SB[29] = s_chan[ch].SB[30]; // -> helpers for simple linear interpolation: delay real val for two slots, and calc the two deltas, for a 'look at the future behaviour' - s_chan[ch].SB[30] = s_chan[ch].SB[31]; - s_chan[ch].SB[31] = fa; - s_chan[ch].SB[32] = 1; // -> flag: calc new interolation + spu->s_chan[ch].SB[28] = 0; + spu->s_chan[ch].SB[29] = spu->s_chan[ch].SB[30]; // -> helpers for simple linear interpolation: delay real val for two slots, and calc the two deltas, for a 'look at the future behaviour' + spu->s_chan[ch].SB[30] = spu->s_chan[ch].SB[31]; + spu->s_chan[ch].SB[31] = fa; + spu->s_chan[ch].SB[32] = 1; // -> flag: calc new interolation } - else s_chan[ch].SB[29]=fa; // no interpolation + else spu->s_chan[ch].SB[29]=fa; // no interpolation - s_chan[ch].spos -= 0x10000L; + spu->s_chan[ch].spos -= 0x10000L; } //////////////////////////////////////////////// @@ -584,32 +528,32 @@ GOON: ; // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used... // and sometimes the noise will be used as fmod modulation... pfff - if(s_chan[ch].bNoise) + if(spu->s_chan[ch].bNoise) { - if((dwNoiseVal<<=1)&0x80000000L) + if((spu->dwNoiseVal<<=1)&0x80000000L) { - dwNoiseVal^=0x0040001L; - fa=((dwNoiseVal>>2)&0x7fff); + spu->dwNoiseVal^=0x0040001L; + fa=((spu->dwNoiseVal>>2)&0x7fff); fa=-fa; } - else fa=(dwNoiseVal>>2)&0x7fff; + else fa=(spu->dwNoiseVal>>2)&0x7fff; // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val - fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl2[ch/24]&0x3f00)>>9))+1)); + fa=spu->s_chan[ch].iOldNoise+((fa-spu->s_chan[ch].iOldNoise)/((0x001f-((spu->spuCtrl2[ch/24]&0x3f00)>>9))+1)); if(fa>32767L) fa=32767L; if(fa<-32767L) fa=-32767L; - s_chan[ch].iOldNoise=fa; + spu->s_chan[ch].iOldNoise=fa; - if(iUseInterpolation<2) // no gauss/cubic interpolation? - s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot + if(spu->iUseInterpolation<2) // no gauss/cubic interpolation? + spu->s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot } //---------------------------------------- else // NO NOISE (NORMAL SAMPLE DATA) HERE {//------------------------------------------// - if(iUseInterpolation==3) // cubic interpolation + if(spu->iUseInterpolation==3) // cubic interpolation { long xd; - xd = ((s_chan[ch].spos) >> 1)+1; - gpos = s_chan[ch].SB[28]; + xd = ((spu->s_chan[ch].spos) >> 1)+1; + gpos = spu->s_chan[ch].SB[28]; fa = gval(3) - 3*gval(2) + 3*gval(1) - gval0; fa *= (xd - (2<<15)) / 6; @@ -624,11 +568,11 @@ GOON: ; } //------------------------------------------// else - if(iUseInterpolation==2) // gauss interpolation + if(spu->iUseInterpolation==2) // gauss interpolation { int vl, vr; - vl = (s_chan[ch].spos >> 6) & ~3; - gpos = s_chan[ch].SB[28]; + vl = (spu->s_chan[ch].spos >> 6) & ~3; + gpos = spu->s_chan[ch].SB[28]; vr=(gauss[vl]*gval0)&~2047; vr+=(gauss[vl+1]*gval(1))&~2047; vr+=(gauss[vl+2]*gval(2))&~2047; @@ -644,25 +588,25 @@ GOON: ; } //------------------------------------------// else - if(iUseInterpolation==1) // simple interpolation + if(spu->iUseInterpolation==1) // simple interpolation { - if(s_chan[ch].sinc<0x10000L) // -> upsampling? - InterpolateUp(ch); // --> interpolate up - else InterpolateDown(ch); // --> else down - fa=s_chan[ch].SB[29]; + if(spu->s_chan[ch].sinc<0x10000L) // -> upsampling? + InterpolateUp(spu, ch); // --> interpolate up + else InterpolateDown(spu, ch); // --> else down + fa=spu->s_chan[ch].SB[29]; } //------------------------------------------// - else fa=s_chan[ch].SB[29]; // no interpolation + else fa=spu->s_chan[ch].SB[29]; // no interpolation } - s_chan[ch].sval = (MixADSR(ch) * fa) / 1023; // add adsr + spu->s_chan[ch].sval = (MixADSR(spu, ch) * fa) / 1023; // add adsr - if(s_chan[ch].bFMod==2) // fmod freq channel + if(spu->s_chan[ch].bFMod==2) // fmod freq channel { - int NP=s_chan[ch+1].iRawPitch; + int NP=spu->s_chan[ch+1].iRawPitch; double intr; - NP=((32768L+s_chan[ch].sval)*NP)/32768L; // mmm... I still need to adjust that to 1/48 khz... we will wait for the first game/demo using it to decide how to do it :) + NP=((32768L+spu->s_chan[ch].sval)*NP)/32768L; // mmm... I still need to adjust that to 1/48 khz... we will wait for the first game/demo using it to decide how to do it :) if(NP>0x3fff) NP=0x3fff; if(NP<0x1) NP=0x1; @@ -672,42 +616,42 @@ GOON: ; NP=(44100L*NP)/(4096L); // calc frequency - s_chan[ch+1].iActFreq=NP; - s_chan[ch+1].iUsedFreq=NP; - s_chan[ch+1].sinc=(((NP/10)<<16)/4410); - if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1; - if(iUseInterpolation==1) // freq change in sipmle interpolation mode - s_chan[ch+1].SB[32]=1; + spu->s_chan[ch+1].iActFreq=NP; + spu->s_chan[ch+1].iUsedFreq=NP; + spu->s_chan[ch+1].sinc=(((NP/10)<<16)/4410); + if(!spu->s_chan[ch+1].sinc) spu->s_chan[ch+1].sinc=1; + if(spu->iUseInterpolation==1) // freq change in sipmle interpolation mode + spu->s_chan[ch+1].SB[32]=1; // mmmm... set up freq decoding positions? -// s_chan[ch+1].iSBPos=28; -// s_chan[ch+1].spos=0x10000L; +// spu->s_chan[ch+1].iSBPos=28; +// spu->s_chan[ch+1].spos=0x10000L; } else { ////////////////////////////////////////////// // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff) - if(s_chan[ch].iMute) - s_chan[ch].sval=0; // debug mute + if(spu->s_chan[ch].iMute) + spu->s_chan[ch].sval=0; // debug mute else { - if(s_chan[ch].bVolumeL) - SSumL[0]+=(s_chan[ch].sval*s_chan[ch].iLeftVolume)/0x4000L; - if(s_chan[ch].bVolumeR) - SSumR[0]+=(s_chan[ch].sval*s_chan[ch].iRightVolume)/0x4000L; + if(spu->s_chan[ch].bVolumeL) + spu->SSumL[0]+=(spu->s_chan[ch].sval*spu->s_chan[ch].iLeftVolume)/0x4000L; + if(spu->s_chan[ch].bVolumeR) + spu->SSumR[0]+=(spu->s_chan[ch].sval*spu->s_chan[ch].iRightVolume)/0x4000L; } ////////////////////////////////////////////// // now let us store sound data for reverb - if(s_chan[ch].bRVBActive) StoreREVERB(ch,0); + if(spu->s_chan[ch].bRVBActive) StoreREVERB(spu, ch,0); } //////////////////////////////////////////////// // ok, go on until 1 ms data of this channel is collected - s_chan[ch].spos += s_chan[ch].sinc; + spu->s_chan[ch].spos += spu->s_chan[ch].sinc; } ENDX: ; @@ -721,54 +665,54 @@ ENDX: ; /////////////////////////////////////////////////////// // mix all channels (including reverb) into one buffer - SSumL[0]+=MixREVERBLeft(0,0); - SSumL[0]+=MixREVERBLeft(0,1); - SSumR[0]+=MixREVERBRight(0); - SSumR[0]+=MixREVERBRight(1); + spu->SSumL[0]+=MixREVERBLeft(spu, 0,0); + spu->SSumL[0]+=MixREVERBLeft(spu, 0,1); + spu->SSumR[0]+=MixREVERBRight(spu, 0); + spu->SSumR[0]+=MixREVERBRight(spu, 1); - d=SSumL[0]/voldiv;SSumL[0]=0; - d2=SSumR[0]/voldiv;SSumR[0]=0; + d=spu->SSumL[0]/voldiv;spu->SSumL[0]=0; + d2=spu->SSumR[0]/voldiv;spu->SSumR[0]=0; if(d<-32767) d=-32767;if(d>32767) d=32767; if(d2<-32767) d2=-32767;if(d2>32767) d2=32767; - if(sampcount>=decaybegin) + if(spu->sampcount>=spu->decaybegin) { s32 dmul; - if(decaybegin!=~0) // Is anyone REALLY going to be playing a song + if(spu->decaybegin!=~0) // Is anyone REALLY going to be playing a song // for 13 hours? { - if(sampcount>=decayend) + if(spu->sampcount>=spu->decayend) { // ao_song_done = 1; return(0); } - dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin)); + dmul=256-(256*(spu->sampcount-spu->decaybegin)/(spu->decayend-spu->decaybegin)); d=(d*dmul)>>8; d2=(d2*dmul)>>8; } } - sampcount++; + spu->sampcount++; - *pS++=d; - *pS++=d2; + *spu->pS++=d; + *spu->pS++=d2; - InitREVERB(); + InitREVERB(spu); ////////////////////////////////////////////////////// // feed the sound // wanna have around 1/60 sec (16.666 ms) updates - if ((((unsigned char *)pS)-((unsigned char *)pSpuBuffer)) == (735*4)) + if ((((unsigned char *)spu->pS)-((unsigned char *)spu->pSpuBuffer)) == (735*4)) { - cpu->spu_callback((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer, cpu->spu_callback_data); - pS=(short *)pSpuBuffer; + cpu->spu_callback((u8*)spu->pSpuBuffer,(u8*)spu->pS-(u8*)spu->pSpuBuffer, cpu->spu_callback_data); + spu->pS=(short *)spu->pSpuBuffer; } } // end of big main loop... - bThreadEnded=1; + spu->bThreadEnded=1; return 0; } @@ -784,11 +728,12 @@ ENDX: ; EXPORT_GCC void CALLBACK SPU2async(mips_cpu_context *cpu, unsigned long cycle) { - if(iSpuAsyncWait) + spu2_state_t *spu = cpu->spu2; + if(spu->iSpuAsyncWait) { - iSpuAsyncWait++; - if(iSpuAsyncWait<=64) return; - iSpuAsyncWait=0; + spu->iSpuAsyncWait++; + if(spu->iSpuAsyncWait<=64) return; + spu->iSpuAsyncWait=0; } MAINThread(cpu, 0); // -> linux high-compat mode @@ -805,13 +750,27 @@ EXPORT_GCC void CALLBACK SPU2async(mips_cpu_context *cpu, unsigned long cycle) EXPORT_GCC long CALLBACK SPU2init(mips_cpu_context *cpu, void (*callback)(unsigned char *, long, void *), void *data) { + cpu->spu2 = malloc (sizeof (spu2_state_t)); + memset (cpu->spu2, 0, sizeof (spu2_state_t)); + cpu->spu2->iUseXA=0; + cpu->spu2->iVolume=3; + cpu->spu2->iXAPitch=1; + cpu->spu2->iUseTimer=2; + cpu->spu2->iSPUIRQWait=1; + cpu->spu2->iDebugMode=0; + cpu->spu2->iRecordMode=0; + cpu->spu2->iUseReverb=1; + cpu->spu2->iUseInterpolation=2; + cpu->spu2->dwNoiseVal=1; // global noise generator + cpu->spu2->lastch=-1; + cpu->spu_callback = callback; cpu->spu_callback_data = data; - spuMemC=(unsigned char *)spuMem; // just small setup - memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN)); - memset(rvb,0,2*sizeof(REVERBInfo)); + cpu->spu2->spuMemC=(unsigned char *)cpu->spu2->spuMem; // just small setup + memset((void *)cpu->spu2->s_chan,0,MAXCHAN*sizeof(SPUCHAN)); + memset(cpu->spu2->rvb,0,2*sizeof(REVERBInfo)); - sampcount = 0; + cpu->spu2->sampcount = 0; InitADSR(); @@ -824,13 +783,14 @@ EXPORT_GCC long CALLBACK SPU2init(mips_cpu_context *cpu, void (*callback)(unsign static void SetupTimer(mips_cpu_context *cpu) { - memset(SSumR,0,NSSIZE*sizeof(int)); // init some mixing buffers - memset(SSumL,0,NSSIZE*sizeof(int)); - pS=(short *)pSpuBuffer; // setup soundbuffer pointer - - bEndThread=0; // init thread vars - bThreadEnded=0; - bSpuInit=1; // flag: we are inited + spu2_state_t *spu = cpu->spu2; + memset(spu->SSumR,0,NSSIZE*sizeof(int)); // init some mixing buffers + memset(spu->SSumL,0,NSSIZE*sizeof(int)); + spu->pS=(short *)spu->pSpuBuffer; // setup soundbuffer pointer + + spu->bEndThread=0; // init thread vars + spu->bThreadEnded=0; + spu->bSpuInit=1; // flag: we are inited } //////////////////////////////////////////////////////////////////////// @@ -839,9 +799,10 @@ static void SetupTimer(mips_cpu_context *cpu) static void RemoveTimer(mips_cpu_context *cpu) { - bEndThread=1; // raise flag to end thread - bThreadEnded=0; // no more spu is running - bSpuInit=0; + spu2_state_t *spu = cpu->spu2; + spu->bEndThread=1; // raise flag to end thread + spu->bThreadEnded=0; // no more spu is running + spu->bSpuInit=0; } //////////////////////////////////////////////////////////////////////// @@ -850,32 +811,33 @@ static void RemoveTimer(mips_cpu_context *cpu) static void SetupStreams(mips_cpu_context *cpu) { + spu2_state_t *spu = cpu->spu2; int i; - pSpuBuffer=(unsigned char *)malloc(32768); // alloc mixing buffer + spu->pSpuBuffer=(unsigned char *)malloc(32768); // alloc mixing buffer i=NSSIZE*2; - sRVBStart[0] = (int *)malloc(i*4); // alloc reverb buffer - memset(sRVBStart[0],0,i*4); - sRVBEnd[0] = sRVBStart[0] + i; - sRVBPlay[0] = sRVBStart[0]; - sRVBStart[1] = (int *)malloc(i*4); // alloc reverb buffer - memset(sRVBStart[1],0,i*4); - sRVBEnd[1] = sRVBStart[1] + i; - sRVBPlay[1] = sRVBStart[1]; + spu->sRVBStart[0] = (int *)malloc(i*4); // alloc reverb buffer + memset(spu->sRVBStart[0],0,i*4); + spu->sRVBEnd[0] = spu->sRVBStart[0] + i; + spu->sRVBPlay[0] = spu->sRVBStart[0]; + spu->sRVBStart[1] = (int *)malloc(i*4); // alloc reverb buffer + memset(spu->sRVBStart[1],0,i*4); + spu->sRVBEnd[1] = spu->sRVBStart[1] + i; + spu->sRVBPlay[1] = spu->sRVBStart[1]; for(i=0;i<MAXCHAN;i++) // loop sound channels { // we don't use mutex sync... not needed, would only // slow us down: -// s_chan[i].hMutex=CreateMutex(NULL,FALSE,NULL); - s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain - s_chan[i].iMute=0; - s_chan[i].iIrqDone=0; - s_chan[i].pLoop=spuMemC; - s_chan[i].pStart=spuMemC; - s_chan[i].pCurr=spuMemC; +// spu->s_chan[i].hMutex=CreateMutex(NULL,FALSE,NULL); + spu->s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain + spu->s_chan[i].iMute=0; + spu->s_chan[i].iIrqDone=0; + spu->s_chan[i].pLoop=spu->spuMemC; + spu->s_chan[i].pStart=spu->spuMemC; + spu->s_chan[i].pCurr=spu->spuMemC; } } @@ -885,21 +847,22 @@ static void SetupStreams(mips_cpu_context *cpu) static void RemoveStreams(mips_cpu_context *cpu) { - free(pSpuBuffer); // free mixing buffer - pSpuBuffer=NULL; - free(sRVBStart[0]); // free reverb buffer - sRVBStart[0]=0; - free(sRVBStart[1]); // free reverb buffer - sRVBStart[1]=0; + spu2_state_t *spu = cpu->spu2; + free(spu->pSpuBuffer); // free mixing buffer + spu->pSpuBuffer=NULL; + free(spu->sRVBStart[0]); // free reverb buffer + spu->sRVBStart[0]=0; + free(spu->sRVBStart[1]); // free reverb buffer + spu->sRVBStart[1]=0; /* int i; for(i=0;i<MAXCHAN;i++) { - WaitForSingleObject(s_chan[i].hMutex,2000); - ReleaseMutex(s_chan[i].hMutex); - if(s_chan[i].hMutex) - {CloseHandle(s_chan[i].hMutex);s_chan[i].hMutex=0;} + WaitForSingleObject(spu->s_chan[i].hMutex,2000); + ReleaseMutex(spu->s_chan[i].hMutex); + if(spu->s_chan[i].hMutex) + {CloseHandle(spu->s_chan[i].hMutex);spu->s_chan[i].hMutex=0;} } */ } @@ -911,33 +874,34 @@ static void RemoveStreams(mips_cpu_context *cpu) EXPORT_GCC long CALLBACK SPU2open(mips_cpu_context *cpu, void *pDsp) { - if(bSPUIsOpen) return 0; // security for some stupid main emus - - iUseXA=0; // just small setup - iVolume=3; - bEndThread=0; - bThreadEnded=0; - spuMemC=(unsigned char *)spuMem; - memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN)); - pSpuIrq[0]=0; - pSpuIrq[1]=0; - iSPUIRQWait=1; - dwNewChannel2[0]=0; - dwNewChannel2[1]=0; - dwEndChannel2[0]=0; - dwEndChannel2[1]=0; - spuCtrl2[0]=0; - spuCtrl2[1]=0; - spuStat2[0]=0; - spuStat2[1]=0; - spuIrq2[0]=0; - spuIrq2[1]=0; - spuAddr2[0]=0xffffffff; - spuAddr2[1]=0xffffffff; - spuRvbAddr2[0]=0; - spuRvbAddr2[1]=0; - spuRvbAEnd2[0]=0; - spuRvbAEnd2[1]=0; + spu2_state_t *spu = cpu->spu2; + if(spu->bSPUIsOpen) return 0; // security for some stupid main emus + + spu->iUseXA=0; // just small setup + spu->iVolume=3; + spu->bEndThread=0; + spu->bThreadEnded=0; + spu->spuMemC=(unsigned char *)spu->spuMem; + memset((void *)spu->s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN)); + spu->pSpuIrq[0]=0; + spu->pSpuIrq[1]=0; + spu->iSPUIRQWait=1; + spu->dwNewChannel2[0]=0; + spu->dwNewChannel2[1]=0; + spu->dwEndChannel2[0]=0; + spu->dwEndChannel2[1]=0; + spu->spuCtrl2[0]=0; + spu->spuCtrl2[1]=0; + spu->spuStat2[0]=0; + spu->spuStat2[1]=0; + spu->spuIrq2[0]=0; + spu->spuIrq2[1]=0; + spu->spuAddr2[0]=0xffffffff; + spu->spuAddr2[1]=0xffffffff; + spu->spuRvbAddr2[0]=0; + spu->spuRvbAddr2[1]=0; + spu->spuRvbAEnd2[0]=0; + spu->spuRvbAEnd2[1]=0; // ReadConfig(); // read user stuff @@ -947,7 +911,7 @@ EXPORT_GCC long CALLBACK SPU2open(mips_cpu_context *cpu, void *pDsp) SetupTimer(cpu); // timer for feeding data - bSPUIsOpen=1; + spu->bSPUIsOpen=1; return 0; } @@ -960,9 +924,10 @@ EXPORT_GCC long CALLBACK SPU2open(mips_cpu_context *cpu, void *pDsp) EXPORT_GCC void CALLBACK SPU2close(mips_cpu_context *cpu) { - if(!bSPUIsOpen) return; // some security + spu2_state_t *spu = cpu->spu2; + if(!spu->bSPUIsOpen) return; // some security - bSPUIsOpen=0; // no more open + spu->bSPUIsOpen=0; // no more open RemoveTimer(cpu); // no more feeding @@ -995,6 +960,7 @@ EXPORT_GCC long CALLBACK SPU2test(void) // passes a callback that should be called on SPU-IRQ/cdda volume change //////////////////////////////////////////////////////////////////////// +#if 0 // not used yet EXPORT_GCC void CALLBACK SPU2irqCallback(void (CALLBACK *callback)(void)) { @@ -1012,3 +978,4 @@ EXPORT_GCC void CALLBACK SPU2registerCDDAVolume(void (CALLBACK *CDDAVcallback)(u { cddavCallback = CDDAVcallback; } +#endif |