mirror of https://github.com/PCSX2/pcsx2.git
SPU2-X: Reverb compatibility improvements (fixes Ys6).
* EEA / ESA writes are ignored when Effects are enabled. * When effects are disabled, reverb does not process IRQs or produce sound. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3326 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7dbbaf1c04
commit
af40a22ee8
|
@ -34,13 +34,10 @@ namespace soundtouch
|
|||
#include <assert.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
// This will be brought in later anyways, but if we bring it in now, it'll avoid
|
||||
// warnings about redefining __LINUX__.
|
||||
|
|
|
@ -667,23 +667,33 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input,
|
|||
TD.Left += Ext.Left & DryGate.ExtL;
|
||||
TD.Right += Ext.Right & DryGate.ExtR;
|
||||
|
||||
// User-level Effects disabling. Nice speedup but breaks games that depend on
|
||||
// reverb IRQs (very few -- if you find one name it here!).
|
||||
if( EffectsDisabled ) return TD;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reverberation Effects Processing
|
||||
// ----------------------------------------------------------------------------
|
||||
// The FxEnable bit is, like many other things in the SPU2, only a partial systems
|
||||
// toogle. It disables the *inputs* to the reverb, such that the reverb is fed silence,
|
||||
// but it does not actually disable reverb effects processing. In practical terms
|
||||
// this means that when a game turns off reverb, an existing reverb effect should trail
|
||||
// off naturally, instead of being chopped off dead silent.
|
||||
// SPU2 has an FxEnable bit which seems to disable all reverb processing *and*
|
||||
// output, but does *not* disable the advancing buffers. IRQs are not triggered
|
||||
// and reverb is rendered silent.
|
||||
//
|
||||
// Technically we should advance the buffers even when fx are disabled. However
|
||||
// there are two things that make this very unlikely to matter:
|
||||
//
|
||||
// 1. Any SPU2 app wanting to avoid noise or pops needs to clear the reverb buffers
|
||||
// when adjusting settings anyway; so the read/write positions in the reverb
|
||||
// buffer after FxEnabled is set back to 1 doesn't really matter.
|
||||
//
|
||||
// 2. Writes to ESA (and possibly EEA) reset the buffer pointers to 0.
|
||||
//
|
||||
// On the other hand, updating the buffer is cheap and easy, so might as well. ;)
|
||||
|
||||
Reverb_AdvanceBuffer();
|
||||
if (!FxEnable) return TD;
|
||||
|
||||
StereoOut32 TW;
|
||||
|
||||
if( FxEnable )
|
||||
{
|
||||
// Mix Input, Voice, and External data:
|
||||
|
||||
TW.Left = Input.Left & WetGate.InpL;
|
||||
|
@ -693,7 +703,6 @@ StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input,
|
|||
TW.Right += Voices.Wet.Right & WetGate.SndR;
|
||||
TW.Left += Ext.Left & WetGate.ExtL;
|
||||
TW.Right += Ext.Right & WetGate.ExtR;
|
||||
}
|
||||
|
||||
WaveDump::WriteCore( Index, CoreSrc_PreReverb, TW );
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "Global.h"
|
||||
#include "soundtouch/SoundTouch.h"
|
||||
|
||||
|
||||
static soundtouch::SoundTouch* pSoundTouch = NULL;
|
||||
static int ts_stats_stretchblocks = 0;
|
||||
static int ts_stats_normalblocks = 0;
|
||||
|
|
|
@ -930,10 +930,12 @@ static void __fastcall RegWrite_Core( u16 value )
|
|||
|
||||
case REG_C_ATTR:
|
||||
{
|
||||
bool fxenable = thiscore.FxEnable;
|
||||
bool irqe = thiscore.IRQEnable;
|
||||
int bit0 = thiscore.AttrBit0;
|
||||
u8 oldDmaMode = thiscore.DmaMode;
|
||||
|
||||
|
||||
if( ((value>>15)&1) && (!thiscore.CoreEnabled) && (thiscore.InitDelay==0) ) // on init/reset
|
||||
{
|
||||
// When we have exact cycle update info from the Pcsx2 IOP unit, then use
|
||||
|
@ -960,10 +962,13 @@ static void __fastcall RegWrite_Core( u16 value )
|
|||
thiscore.FxEnable =(value>> 7) & 0x01; //1 bit
|
||||
thiscore.NoiseClk =(value>> 8) & 0x3f; //6 bits
|
||||
//thiscore.Mute =(value>>14) & 0x01; //1 bit
|
||||
thiscore.Mute=0;
|
||||
thiscore.Mute =0;
|
||||
thiscore.CoreEnabled=(value>>15) & 0x01; //1 bit
|
||||
thiscore.Regs.ATTR =value&0x7fff;
|
||||
|
||||
if (!fxenable && thiscore.FxEnable)
|
||||
thiscore.RevBuffers.NeedsUpdated = true;
|
||||
|
||||
if(oldDmaMode != thiscore.DmaMode)
|
||||
{
|
||||
// FIXME... maybe: if this mode was cleared in the middle of a DMA, should we interrupt it?
|
||||
|
@ -1111,31 +1116,36 @@ static void __fastcall RegWrite_Core( u16 value )
|
|||
break;
|
||||
|
||||
// Reverb Start and End Address Writes!
|
||||
// * These regs are only writable when Effects are *DISABLED* (FxEnable is false).
|
||||
// Writes while enabled should be ignored.
|
||||
// * Yes, these are backwards from all the volumes -- the hiword comes FIRST (wtf!)
|
||||
// * End position is a hiword only! Loword is always ffff.
|
||||
// * The Reverb buffer position resets on writes to StartA. It probably resets
|
||||
// on writes to End too. Docs don't say, but they're for PSX, which couldn't
|
||||
// change the end address anyway.
|
||||
|
||||
//
|
||||
case REG_A_ESA:
|
||||
//if (thiscore.FxEnable){printf("!! ESA\n"); return;}
|
||||
if (!thiscore.FxEnable)
|
||||
{
|
||||
SetHiWord( thiscore.EffectsStartA, value );
|
||||
thiscore.RevBuffers.NeedsUpdated = true;
|
||||
thiscore.ReverbX = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case (REG_A_ESA + 2):
|
||||
//if (thiscore.FxEnable){printf("!! ESA\n"); return;}
|
||||
if (!thiscore.FxEnable)
|
||||
{
|
||||
SetLoWord( thiscore.EffectsStartA, value );
|
||||
thiscore.RevBuffers.NeedsUpdated = true;
|
||||
thiscore.ReverbX = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_A_EEA:
|
||||
//if (thiscore.FxEnable){printf("!! EEA\n"); return;}
|
||||
if (!thiscore.FxEnable)
|
||||
{
|
||||
thiscore.EffectsEndA = ((u32)value<<16) | 0xFFFF;
|
||||
thiscore.RevBuffers.NeedsUpdated = true;
|
||||
thiscore.ReverbX = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_S_ADMAS:
|
||||
|
|
Loading…
Reference in New Issue