diff --git a/pcsx2/SPU2/Mixer.cpp b/pcsx2/SPU2/Mixer.cpp index e6dff6b0104030..0fcbd4f8126d7d 100644 --- a/pcsx2/SPU2/Mixer.cpp +++ b/pcsx2/SPU2/Mixer.cpp @@ -578,12 +578,6 @@ StereoOut32 V_Core::Mix(const VoiceMixSet& inVoices, const StereoOut32& Input, c Reverb_AdvanceBuffer(); // Updates the reverb work area as well, if needed. - // ToDo: - // Bad EndA causes memory corruption. Bad for us, unknown on PS2! - // According to no$psx, effects always run but don't always write back, so the FxEnable check may be wrong - if (!FxEnable || EffectsEndA >= 0x100000) - return TD; - StereoOut32 TW; // Mix Input, Voice, and External data: diff --git a/pcsx2/SPU2/Reverb.cpp b/pcsx2/SPU2/Reverb.cpp index a3e3f5ab8b8c73..b28243b6d3c0a8 100644 --- a/pcsx2/SPU2/Reverb.cpp +++ b/pcsx2/SPU2/Reverb.cpp @@ -17,38 +17,78 @@ #include "Global.h" #include -__forceinline s32 V_Core::RevbGetIndexer(s32 offset) + +void V_Core::AnalyzeReverbPreset() { - u32 pos = ReverbX + offset; + Console.WriteLn("Reverb Parameter Update for Core %d:", Index); + Console.WriteLn("----------------------------------------------------------"); + + Console.WriteLn(" IN_COEF_L, IN_COEF_R 0x%08x, 0x%08x", Revb.IN_COEF_L, Revb.IN_COEF_R); + Console.WriteLn(" APF1_SIZE, APF2_SIZE 0x%08x, 0x%08x", Revb.APF1_SIZE, Revb.APF2_SIZE); + Console.WriteLn(" APF1_VOL, APF2_VOL 0x%08x, 0x%08x", Revb.APF1_VOL, Revb.APF2_VOL); + + Console.WriteLn(" COMB1_VOL 0x%08x", Revb.COMB1_VOL); + Console.WriteLn(" COMB2_VOL 0x%08x", Revb.COMB2_VOL); + Console.WriteLn(" COMB3_VOL 0x%08x", Revb.COMB3_VOL); + Console.WriteLn(" COMB4_VOL 0x%08x", Revb.COMB4_VOL); + + Console.WriteLn(" COMB1_L_SRC, COMB1_R_SRC 0x%08x, 0x%08x", Revb.COMB1_L_SRC, Revb.COMB1_R_SRC); + Console.WriteLn(" COMB2_L_SRC, COMB2_R_SRC 0x%08x, 0x%08x", Revb.COMB2_L_SRC, Revb.COMB2_R_SRC); + Console.WriteLn(" COMB3_L_SRC, COMB3_R_SRC 0x%08x, 0x%08x", Revb.COMB3_L_SRC, Revb.COMB3_R_SRC); + Console.WriteLn(" COMB4_L_SRC, COMB4_R_SRC 0x%08x, 0x%08x", Revb.COMB4_L_SRC, Revb.COMB4_R_SRC); + + Console.WriteLn(" SAME_L_SRC, SAME_R_SRC 0x%08x, 0x%08x", Revb.SAME_L_SRC, Revb.SAME_R_SRC); + Console.WriteLn(" DIFF_L_SRC, DIFF_R_SRC 0x%08x, 0x%08x", Revb.DIFF_L_SRC, Revb.DIFF_R_SRC); + Console.WriteLn(" SAME_L_DST, SAME_R_DST 0x%08x, 0x%08x", Revb.SAME_L_DST, Revb.SAME_R_DST); + Console.WriteLn(" DIFF_L_DST, DIFF_R_DST 0x%08x, 0x%08x", Revb.DIFF_L_DST, Revb.DIFF_R_DST); + Console.WriteLn(" IIR_VOL, WALL_VOL 0x%08x, 0x%08x", Revb.IIR_VOL, Revb.WALL_VOL); + + Console.WriteLn(" APF1_L_DST 0x%08x", Revb.APF1_L_DST); + Console.WriteLn(" APF1_R_DST 0x%08x", Revb.APF1_R_DST); + Console.WriteLn(" APF2_L_DST 0x%08x", Revb.APF2_L_DST); + Console.WriteLn(" APF2_R_DST 0x%08x", Revb.APF2_R_DST); + + Console.WriteLn(" EffectStartA 0x%x", EffectsStartA); + Console.WriteLn(" EffectsEndA 0x%x", EffectsEndA); + Console.WriteLn("----------------------------------------------------------"); +} - // Fast and simple single step wrapping, made possible by the preparation of the - // effects buffer addresses. +__forceinline s32 V_Core::RevbGetIndexer(s32 offset) +{ + u32 pos = ReverbX + std::clamp(offset, 0, INT_MAX); - if (pos > EffectsEndA) - { - pos -= EffectsEndA + 1; - pos += EffectsStartA; + if (pos > EffectsEndA) { + pos -= EffectsEndA - EffectsStartA; } - assert(pos >= EffectsStartA && pos <= EffectsEndA); + //if (pos > EffectsEndA) + //{ + // pos -= EffectsEndA + 1; + // pos += EffectsStartA; + //} + + //assert(pos >= EffectsStartA && pos <= EffectsEndA); return pos; } void V_Core::Reverb_AdvanceBuffer() { - if (RevBuffers.NeedsUpdated) - UpdateEffectsBufferSize(); + if (Revb.Updated) + { + AnalyzeReverbPreset(); + RevBuffers = Revb; + Revb.Updated = false; + } - if ((Cycles & 1) && (EffectsBufferSize > 0)) + if ((Cycles & 1)) { ReverbX += 1; - if (ReverbX >= (u32)EffectsBufferSize) - ReverbX = 0; + if (ReverbX > EffectsEndA) { + ReverbX = EffectsStartA; + } } } - - static constexpr u32 NUM_TAPS = 39; // 39 tap filter, the 0's could be optimized out static constexpr std::array filter_coefs = { @@ -112,7 +152,6 @@ s32 __forceinline V_Core::ReverbDownsample(bool right) return out; } - StereoOut32 __forceinline V_Core::ReverbUpsample(bool phase) { s32 ls = 0, rs = 0; @@ -124,7 +163,6 @@ StereoOut32 __forceinline V_Core::ReverbUpsample(bool phase) } else { - for (u32 i = 0; i < (NUM_TAPS >> 1) + 1; i++) { ls += RevbUpBuf[0][(((RevbSampleBufPos - NUM_TAPS) >> 1) + i) & 63] * filter_coefs[i * 2]; @@ -140,14 +178,24 @@ StereoOut32 __forceinline V_Core::ReverbUpsample(bool phase) rs >>= 14; rs = std::clamp(rs, INT16_MIN, INT16_MAX); - return StereoOut32(ls, rs); + return {ls, rs}; } ///////////////////////////////////////////////////////////////////////////////////////// +static __forceinline s16 ReverbRead(u32 addr) +{ + return _spu2mem[addr & 0xF'FFFF]; +} + +static __forceinline void ReverbWrite(u32 addr, s16 val) +{ + _spu2mem[addr & 0xF'FFFF] = val; +} + StereoOut32 V_Core::DoReverb(const StereoOut32& Input) { - if (EffectsBufferSize <= 0) + if (EffectsStartA >= EffectsEndA) { return StereoOut32::Empty; } @@ -161,20 +209,20 @@ StereoOut32 V_Core::DoReverb(const StereoOut32& Input) const u32 same_src = RevbGetIndexer(R ? RevBuffers.SAME_R_SRC : RevBuffers.SAME_L_SRC); const u32 same_dst = RevbGetIndexer(R ? RevBuffers.SAME_R_DST : RevBuffers.SAME_L_DST); - const u32 same_prv = RevbGetIndexer(R ? RevBuffers.SAME_R_PRV : RevBuffers.SAME_L_PRV); + const u32 same_prv = RevbGetIndexer(R ? RevBuffers.SAME_R_DST - 1 : RevBuffers.SAME_L_DST - 1); const u32 diff_src = RevbGetIndexer(R ? RevBuffers.DIFF_L_SRC : RevBuffers.DIFF_R_SRC); const u32 diff_dst = RevbGetIndexer(R ? RevBuffers.DIFF_R_DST : RevBuffers.DIFF_L_DST); - const u32 diff_prv = RevbGetIndexer(R ? RevBuffers.DIFF_R_PRV : RevBuffers.DIFF_L_PRV); + const u32 diff_prv = RevbGetIndexer(R ? RevBuffers.DIFF_R_DST - 1 : RevBuffers.DIFF_L_DST - 1); const u32 comb1_src = RevbGetIndexer(R ? RevBuffers.COMB1_R_SRC : RevBuffers.COMB1_L_SRC); const u32 comb2_src = RevbGetIndexer(R ? RevBuffers.COMB2_R_SRC : RevBuffers.COMB2_L_SRC); const u32 comb3_src = RevbGetIndexer(R ? RevBuffers.COMB3_R_SRC : RevBuffers.COMB3_L_SRC); const u32 comb4_src = RevbGetIndexer(R ? RevBuffers.COMB4_R_SRC : RevBuffers.COMB4_L_SRC); - const u32 apf1_src = RevbGetIndexer(R ? RevBuffers.APF1_R_SRC : RevBuffers.APF1_L_SRC); + const u32 apf1_src = RevbGetIndexer(R ? (RevBuffers.APF1_R_DST - Revb.APF1_SIZE) : (RevBuffers.APF1_L_DST - Revb.APF1_SIZE)); const u32 apf1_dst = RevbGetIndexer(R ? RevBuffers.APF1_R_DST : RevBuffers.APF1_L_DST); - const u32 apf2_src = RevbGetIndexer(R ? RevBuffers.APF2_R_SRC : RevBuffers.APF2_L_SRC); + const u32 apf2_src = RevbGetIndexer(R ? (RevBuffers.APF2_R_DST - Revb.APF2_SIZE) : (RevBuffers.APF2_L_DST - Revb.APF2_SIZE)); const u32 apf2_dst = RevbGetIndexer(R ? RevBuffers.APF2_R_DST : RevBuffers.APF2_L_DST); // ----------------------------------------- @@ -214,23 +262,23 @@ StereoOut32 V_Core::DoReverb(const StereoOut32& Input) #define MUL(x, y) ((x) * (y) >> 15) in = MUL(R ? Revb.IN_COEF_R : Revb.IN_COEF_L, ReverbDownsample(R)); - same = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, _spu2mem[same_src]) - _spu2mem[same_prv]) + _spu2mem[same_prv]; - diff = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, _spu2mem[diff_src]) - _spu2mem[diff_prv]) + _spu2mem[diff_prv]; + same = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, ReverbRead(same_src)) - ReverbRead(same_prv)) + ReverbRead(same_prv); + diff = MUL(Revb.IIR_VOL, in + MUL(Revb.WALL_VOL, ReverbRead(diff_src)) - ReverbRead(diff_prv)) + ReverbRead(diff_prv); - out = MUL(Revb.COMB1_VOL, _spu2mem[comb1_src]) + MUL(Revb.COMB2_VOL, _spu2mem[comb2_src]) + MUL(Revb.COMB3_VOL, _spu2mem[comb3_src]) + MUL(Revb.COMB4_VOL, _spu2mem[comb4_src]); + out = MUL(Revb.COMB1_VOL, ReverbRead(comb1_src)) + MUL(Revb.COMB2_VOL, ReverbRead(comb2_src)) + MUL(Revb.COMB3_VOL, ReverbRead(comb3_src)) + MUL(Revb.COMB4_VOL, ReverbRead(comb4_src)); - apf1 = out - MUL(Revb.APF1_VOL, _spu2mem[apf1_src]); - out = _spu2mem[apf1_src] + MUL(Revb.APF1_VOL, apf1); - apf2 = out - MUL(Revb.APF2_VOL, _spu2mem[apf2_src]); - out = _spu2mem[apf2_src] + MUL(Revb.APF2_VOL, apf2); + apf1 = out - MUL(Revb.APF1_VOL, ReverbRead(apf1_src)); + out = ReverbRead(apf1_src) + MUL(Revb.APF1_VOL, apf1); + apf2 = out - MUL(Revb.APF2_VOL, ReverbRead(apf2_src)); + out = ReverbRead(apf2_src) + MUL(Revb.APF2_VOL, apf2); // According to no$psx the effects always run but don't always write back, see check in V_Core::Mix if (FxEnable) { - _spu2mem[same_dst] = clamp_mix(same); - _spu2mem[diff_dst] = clamp_mix(diff); - _spu2mem[apf1_dst] = clamp_mix(apf1); - _spu2mem[apf2_dst] = clamp_mix(apf2); + ReverbWrite(same_dst, clamp_mix(same)); + ReverbWrite(diff_dst, clamp_mix(diff)); + ReverbWrite(apf1_dst, clamp_mix(apf1)); + ReverbWrite(apf2_dst, clamp_mix(apf2)); } RevbUpBuf[R][(RevbSampleBufPos >> 1) & 63] = clamp_mix(out); diff --git a/pcsx2/SPU2/defs.h b/pcsx2/SPU2/defs.h index 69c659914ad6fb..8ce5f13f82f6d1 100644 --- a/pcsx2/SPU2/defs.h +++ b/pcsx2/SPU2/defs.h @@ -277,44 +277,8 @@ struct V_Reverb u32 APF1_R_DST; u32 APF2_L_DST; u32 APF2_R_DST; -}; -struct V_ReverbBuffers -{ - s32 SAME_L_SRC; - s32 SAME_R_SRC; - s32 DIFF_R_SRC; - s32 DIFF_L_SRC; - s32 SAME_L_DST; - s32 SAME_R_DST; - s32 DIFF_L_DST; - s32 DIFF_R_DST; - - s32 COMB1_L_SRC; - s32 COMB1_R_SRC; - s32 COMB2_L_SRC; - s32 COMB2_R_SRC; - s32 COMB3_L_SRC; - s32 COMB3_R_SRC; - s32 COMB4_L_SRC; - s32 COMB4_R_SRC; - - s32 APF1_L_DST; - s32 APF1_R_DST; - s32 APF2_L_DST; - s32 APF2_R_DST; - - s32 SAME_L_PRV; - s32 SAME_R_PRV; - s32 DIFF_L_PRV; - s32 DIFF_R_PRV; - - s32 APF1_L_SRC; - s32 APF1_R_SRC; - s32 APF2_L_SRC; - s32 APF2_R_SRC; - - bool NeedsUpdated; + bool Updated; }; struct V_SPDIF @@ -425,7 +389,7 @@ struct V_Core u32 InputDataProgress; V_Reverb Revb; // Reverb Registers - V_ReverbBuffers RevBuffers; // buffer pointers for reverb, pre-calculated and pre-clipped. + V_Reverb RevBuffers; s32 RevbDownBuf[2][64]; // Downsample buffer for reverb, one for each channel s32 RevbUpBuf[2][64]; // Upsample buffer for reverb, one for each channel @@ -436,12 +400,6 @@ struct V_Core u32 ExtEffectsEndA; u32 ReverbX; - // Current size of and position of the effects buffer. Pre-caculated when the effects start - // or end position registers are written. CAN BE NEGATIVE OR ZERO, in which - // case reverb should be disabled. - s32 EffectsBufferSize; - u32 EffectsBufferStart; - V_CoreRegs Regs; // Registers // Preserves the channel processed last cycle @@ -490,8 +448,6 @@ struct V_Core void UpdateEffectsBufferSize(); void AnalyzeReverbPreset(); - s32 EffectsBufferIndexer(s32 offset) const; - void WriteRegPS1(u32 mem, u16 value); u16 ReadRegPS1(u32 mem); diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 78890ecfa78f1e..fa533a98d04688 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -141,7 +141,6 @@ void V_Core::Init(int index) InputPosWrite = 0x100; InputDataProgress = 0; InputDataTransferred = 0; - ReverbX = 0; LastEffect.Left = 0; LastEffect.Right = 0; CoreEnabled = 0; @@ -182,6 +181,7 @@ void V_Core::Init(int index) Regs.VMIXER = 0xFFFFFF; EffectsStartA = c ? 0xFFFF8 : 0xEFFF8; EffectsEndA = c ? 0xFFFFF : 0xEFFFF; + ReverbX = EffectsStartA; ExtEffectsStartA = EffectsStartA; ExtEffectsEndA = EffectsEndA; @@ -221,112 +221,10 @@ void V_Core::Init(int index) Regs.STATX = 0x80; Regs.ENDX = 0xffffff; // PS2 confirmed - RevBuffers.NeedsUpdated = true; + RevBuffers.Updated = true; RevbSampleBufPos = 0; memset(RevbDownBuf, 0, sizeof(RevbDownBuf)); memset(RevbUpBuf, 0, sizeof(RevbUpBuf)); - - UpdateEffectsBufferSize(); -} - -void V_Core::AnalyzeReverbPreset() -{ - SPU2::ConLog("Reverb Parameter Update for Core %d:\n", Index); - SPU2::ConLog("----------------------------------------------------------\n"); - - SPU2::ConLog(" IN_COEF_L, IN_COEF_R 0x%08x, 0x%08x\n", Revb.IN_COEF_L, Revb.IN_COEF_R); - SPU2::ConLog(" APF1_SIZE, APF2_SIZE 0x%08x, 0x%08x\n", Revb.APF1_SIZE, Revb.APF2_SIZE); - SPU2::ConLog(" APF1_VOL, APF2_VOL 0x%08x, 0x%08x\n", Revb.APF1_VOL, Revb.APF2_VOL); - - SPU2::ConLog(" COMB1_VOL 0x%08x\n", Revb.COMB1_VOL); - SPU2::ConLog(" COMB2_VOL 0x%08x\n", Revb.COMB2_VOL); - SPU2::ConLog(" COMB3_VOL 0x%08x\n", Revb.COMB3_VOL); - SPU2::ConLog(" COMB4_VOL 0x%08x\n", Revb.COMB4_VOL); - - SPU2::ConLog(" COMB1_L_SRC, COMB1_R_SRC 0x%08x, 0x%08x\n", Revb.COMB1_L_SRC, Revb.COMB1_R_SRC); - SPU2::ConLog(" COMB2_L_SRC, COMB2_R_SRC 0x%08x, 0x%08x\n", Revb.COMB2_L_SRC, Revb.COMB2_R_SRC); - SPU2::ConLog(" COMB3_L_SRC, COMB3_R_SRC 0x%08x, 0x%08x\n", Revb.COMB3_L_SRC, Revb.COMB3_R_SRC); - SPU2::ConLog(" COMB4_L_SRC, COMB4_R_SRC 0x%08x, 0x%08x\n", Revb.COMB4_L_SRC, Revb.COMB4_R_SRC); - - SPU2::ConLog(" SAME_L_SRC, SAME_R_SRC 0x%08x, 0x%08x\n", Revb.SAME_L_SRC, Revb.SAME_R_SRC); - SPU2::ConLog(" DIFF_L_SRC, DIFF_R_SRC 0x%08x, 0x%08x\n", Revb.DIFF_L_SRC, Revb.DIFF_R_SRC); - SPU2::ConLog(" SAME_L_DST, SAME_R_DST 0x%08x, 0x%08x\n", Revb.SAME_L_DST, Revb.SAME_R_DST); - SPU2::ConLog(" DIFF_L_DST, DIFF_R_DST 0x%08x, 0x%08x\n", Revb.DIFF_L_DST, Revb.DIFF_R_DST); - SPU2::ConLog(" IIR_VOL, WALL_VOL 0x%08x, 0x%08x\n", Revb.IIR_VOL, Revb.WALL_VOL); - - SPU2::ConLog(" APF1_L_DST 0x%08x\n", Revb.APF1_L_DST); - SPU2::ConLog(" APF1_R_DST 0x%08x\n", Revb.APF1_R_DST); - SPU2::ConLog(" APF2_L_DST 0x%08x\n", Revb.APF2_L_DST); - SPU2::ConLog(" APF2_R_DST 0x%08x\n", Revb.APF2_R_DST); - - SPU2::ConLog(" EffectsBufferSize 0x%x\n", EffectsBufferSize); - SPU2::ConLog("----------------------------------------------------------\n"); -} -s32 V_Core::EffectsBufferIndexer(s32 offset) const -{ - // Should offsets be multipled by 4 or not? Reverse-engineering of IOP code reveals - // that it *4's all addresses before upping them to the SPU2 -- so our buffers are - // already x4'd. It doesn't really make sense that we should x4 them again, and this - // seems to work. (feedback-free in bios and DDS) --air - - // Need to use modulus here, because games can and will drop the buffer size - // without notice, and it leads to offsets several times past the end of the buffer. - - if (static_cast(offset) >= static_cast(EffectsBufferSize)) - return EffectsStartA + (offset % EffectsBufferSize) + (offset < 0 ? EffectsBufferSize : 0); - else - return EffectsStartA + offset; -} - -void V_Core::UpdateEffectsBufferSize() -{ - const s32 newbufsize = EffectsEndA - EffectsStartA + 1; - - RevBuffers.NeedsUpdated = false; - EffectsBufferSize = newbufsize; - EffectsBufferStart = EffectsStartA; - - if (EffectsBufferSize <= 0) - return; - - // debug: shows reverb parameters in console - if (SPU2::MsgToConsole()) - AnalyzeReverbPreset(); - - // Rebuild buffer indexers. - RevBuffers.COMB1_L_SRC = EffectsBufferIndexer(Revb.COMB1_L_SRC); - RevBuffers.COMB1_R_SRC = EffectsBufferIndexer(Revb.COMB1_R_SRC); - RevBuffers.COMB2_L_SRC = EffectsBufferIndexer(Revb.COMB2_L_SRC); - RevBuffers.COMB2_R_SRC = EffectsBufferIndexer(Revb.COMB2_R_SRC); - RevBuffers.COMB3_L_SRC = EffectsBufferIndexer(Revb.COMB3_L_SRC); - RevBuffers.COMB3_R_SRC = EffectsBufferIndexer(Revb.COMB3_R_SRC); - RevBuffers.COMB4_L_SRC = EffectsBufferIndexer(Revb.COMB4_L_SRC); - RevBuffers.COMB4_R_SRC = EffectsBufferIndexer(Revb.COMB4_R_SRC); - - RevBuffers.SAME_L_DST = EffectsBufferIndexer(Revb.SAME_L_DST); - RevBuffers.SAME_R_DST = EffectsBufferIndexer(Revb.SAME_R_DST); - RevBuffers.DIFF_L_DST = EffectsBufferIndexer(Revb.DIFF_L_DST); - RevBuffers.DIFF_R_DST = EffectsBufferIndexer(Revb.DIFF_R_DST); - - RevBuffers.SAME_L_SRC = EffectsBufferIndexer(Revb.SAME_L_SRC); - RevBuffers.SAME_R_SRC = EffectsBufferIndexer(Revb.SAME_R_SRC); - RevBuffers.DIFF_L_SRC = EffectsBufferIndexer(Revb.DIFF_L_SRC); - RevBuffers.DIFF_R_SRC = EffectsBufferIndexer(Revb.DIFF_R_SRC); - - RevBuffers.APF1_L_DST = EffectsBufferIndexer(Revb.APF1_L_DST); - RevBuffers.APF1_R_DST = EffectsBufferIndexer(Revb.APF1_R_DST); - RevBuffers.APF2_L_DST = EffectsBufferIndexer(Revb.APF2_L_DST); - RevBuffers.APF2_R_DST = EffectsBufferIndexer(Revb.APF2_R_DST); - - RevBuffers.SAME_L_PRV = EffectsBufferIndexer(Revb.SAME_L_DST - 1); - RevBuffers.SAME_R_PRV = EffectsBufferIndexer(Revb.SAME_R_DST - 1); - RevBuffers.DIFF_L_PRV = EffectsBufferIndexer(Revb.DIFF_L_DST - 1); - RevBuffers.DIFF_R_PRV = EffectsBufferIndexer(Revb.DIFF_R_DST - 1); - - RevBuffers.APF1_L_SRC = EffectsBufferIndexer(Revb.APF1_L_DST - Revb.APF1_SIZE); - RevBuffers.APF1_R_SRC = EffectsBufferIndexer(Revb.APF1_R_DST - Revb.APF1_SIZE); - RevBuffers.APF2_L_SRC = EffectsBufferIndexer(Revb.APF2_L_DST - Revb.APF2_SIZE); - RevBuffers.APF2_R_SRC = EffectsBufferIndexer(Revb.APF2_R_DST - Revb.APF2_SIZE); } void V_Voice::Start() @@ -779,8 +677,8 @@ void V_Core::WriteRegPS1(u32 mem, u16 value) { EffectsStartA = map_spu1to2(value); //EffectsEndA = 0xFFFFF; // fixed EndA in psx mode - Cores[0].RevBuffers.NeedsUpdated = true; - ReverbX = 0; + Cores[0].RevBuffers.Updated = true; + ReverbX = EffectsStartA; } break; @@ -1302,10 +1200,10 @@ static void RegWrite_Core(u16 value) if (fxenable && !thiscore.FxEnable && (thiscore.EffectsStartA != thiscore.ExtEffectsStartA || thiscore.EffectsEndA != thiscore.ExtEffectsEndA)) { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.EffectsEndA = thiscore.ExtEffectsEndA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; + thiscore.EffectsStartA = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.EffectsEndA = thiscore.ExtEffectsEndA & 0xFFFFF; + thiscore.ReverbX = thiscore.EffectsStartA & 0xFFFFF; + thiscore.RevBuffers.Updated = true; } if (!thiscore.DmaMode && !(thiscore.Regs.STATX & 0x400)) @@ -1477,12 +1375,12 @@ static void RegWrite_Core(u16 value) // change the end address anyway. // case REG_A_ESA: - SetHiWord(thiscore.ExtEffectsStartA, value & 0xF); + SetHiWord(thiscore.ExtEffectsStartA, value); if (!thiscore.FxEnable) { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; + thiscore.EffectsStartA = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.ReverbX = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.Revb.Updated = true; } break; @@ -1490,19 +1388,19 @@ static void RegWrite_Core(u16 value) SetLoWord(thiscore.ExtEffectsStartA, value); if (!thiscore.FxEnable) { - thiscore.EffectsStartA = thiscore.ExtEffectsStartA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; + thiscore.EffectsStartA = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.ReverbX = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.Revb.Updated = true; } break; case REG_A_EEA: - thiscore.ExtEffectsEndA = ((u32)(value & 0xF) << 16) | 0xFFFF; + thiscore.ExtEffectsEndA = ((u32)value << 16) | 0xFFFF; if (!thiscore.FxEnable) { - thiscore.EffectsEndA = thiscore.ExtEffectsEndA; - thiscore.ReverbX = 0; - thiscore.RevBuffers.NeedsUpdated = true; + thiscore.EffectsEndA = thiscore.ExtEffectsEndA & 0xFFFFF; + thiscore.ReverbX = thiscore.ExtEffectsStartA & 0xFFFFF; + thiscore.Revb.Updated = true; } break; @@ -1525,10 +1423,10 @@ static void RegWrite_Core(u16 value) Cores[1].EffectsEndA = 0x7FFFF; Cores[1].ExtEffectsStartA = 0x7FFF8; Cores[1].ExtEffectsEndA = 0x7FFFF; - Cores[1].ReverbX = 0; - Cores[1].RevBuffers.NeedsUpdated = true; - Cores[0].ReverbX = 0; - Cores[0].RevBuffers.NeedsUpdated = true; + Cores[1].ReverbX = Cores[1].EffectsStartA; + Cores[1].RevBuffers.Updated = true; + Cores[0].ReverbX = Cores[0].EffectsStartA; + Cores[0].RevBuffers.Updated = true; for (uint v = 0; v < 24; ++v) { Cores[1].Voices[v].Volume = V_VolumeSlideLR(0, 0); // V_VolumeSlideLR::Max;