From e8eba665eaa2befeab7edc54646dc5cd02b6e472 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sun, 27 Jun 2010 21:33:12 +0200 Subject: ao psf2 spu reentrancy --- plugins/ao/eng_psf/peops2/adsr2.c | 196 ++++----- plugins/ao/eng_psf/peops2/dma.h | 4 +- plugins/ao/eng_psf/peops2/dma2.c | 67 +-- plugins/ao/eng_psf/peops2/externals.h | 674 ++++++++++++++----------------- plugins/ao/eng_psf/peops2/registers2.c | 718 ++++++++++++++++----------------- plugins/ao/eng_psf/peops2/regs.h | 21 +- plugins/ao/eng_psf/peops2/reverb2.c | 180 ++++----- plugins/ao/eng_psf/peops2/spu.h | 140 +++++-- plugins/ao/eng_psf/peops2/spu2.c | 559 ++++++++++++------------- 9 files changed, 1263 insertions(+), 1296 deletions(-) (limited to 'plugins/ao/eng_psf/peops2') 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 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(lTs_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(lTs_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>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>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>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>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<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>=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>=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(iOffspuMem; + iOff=(iOff)+spu->rvb[core].CurrAddr; + while(iOff>spu->rvb[core].EndAddr) iOff=spu->rvb[core].StartAddr+(iOff-(spu->rvb[core].EndAddr+1)); + while(iOffrvb[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(iOffspuMem; + iOff=(iOff)+spu->rvb[core].CurrAddr; + while(iOff>spu->rvb[core].EndAddr) iOff=spu->rvb[core].StartAddr+(iOff-(spu->rvb[core].EndAddr+1)); + while(iOffrvb[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(iOffspuMem; + 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(iOffrvb[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(id2s_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;chs_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=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 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;is_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 -- cgit v1.2.3