diff --git a/plugins/spu2-x/src/ADSR.cpp b/plugins/spu2-x/src/ADSR.cpp
index a79142fa69..903fdef4a2 100644
--- a/plugins/spu2-x/src/ADSR.cpp
+++ b/plugins/spu2-x/src/ADSR.cpp
@@ -15,7 +15,7 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
static const s32 ADSR_MAX_VOL = 0x7fffffff;
@@ -34,7 +34,7 @@ void InitADSR() // INIT ADSR
else
rate <<= shift;
- PsxRates[i] = (int)min( rate, 0x3fffffffLL );
+ PsxRates[i] = (int)std::min( rate, 0x3fffffffLL );
}
}
diff --git a/plugins/spu2-x/src/BaseTypes.h b/plugins/spu2-x/src/BaseTypes.h
deleted file mode 100644
index cb72ed104f..0000000000
--- a/plugins/spu2-x/src/BaseTypes.h
+++ /dev/null
@@ -1,119 +0,0 @@
-
-#ifndef _BASETYPES_H_
-#define _BASETYPES_H_
-
-#include "PS2Edefs.h"
-
-//system defines
-#ifdef __LINUX__
-# undef __LINUX__ // supress gtk's warnings on redefinition
-# include
-#else
-# define WINVER 0x0501
-# define _WIN32_WINNT 0x0501
-# include
-# include
-# include
-# include "resource.h"
-#endif
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using std::string;
-using std::wstring;
-
-//////////////////////////////////////////////////////////////////////////
-// Override Win32 min/max macros with the STL's type safe and macro
-// free varieties (much safer!)
-
-#undef min
-#undef max
-
-#include
-
-using std::min;
-using std::max;
-
-template< typename T >
-static __forceinline void Clampify( T& src, T min, T max )
-{
- src = std::min( std::max( src, min ), max );
-}
-
-template< typename T >
-static __forceinline T GetClamped( T src, T min, T max )
-{
- return std::min( std::max( src, min ), max );
-}
-
-extern void SysMessage(const char *fmt, ...);
-
-//////////////////////////////////////////////////////////////
-// Dev / Debug conditionals --
-// Consts for using if() statements instead of uglier #ifdef macros.
-// Abbreviated macros for dev/debug only consoles and msgboxes.
-
-#ifdef SPU2X_DEVBUILD
-# define DevCon Console
-# define DevMsg MsgBox
-#else
-# define DevCon 0&&Console
-# define DevMsg
-#endif
-
-#ifdef PCSX2_DEBUG
-# define DbgCon Console
-#else
-# define DbgCon 0&&Console
-#endif
-
-struct StereoOut16;
-struct StereoOutFloat;
-
-struct StereoOut32
-{
- static StereoOut32 Empty;
-
- s32 Left;
- s32 Right;
-
- StereoOut32() :
- Left( 0 ),
- Right( 0 )
- {
- }
-
- StereoOut32( s32 left, s32 right ) :
- Left( left ),
- Right( right )
- {
- }
-
- StereoOut32( const StereoOut16& src );
- explicit StereoOut32( const StereoOutFloat& src );
-
- StereoOut16 DownSample() const;
-
- StereoOut32 operator+( const StereoOut32& right ) const
- {
- return StereoOut32(
- Left + right.Left,
- Right + right.Right
- );
- }
-
- StereoOut32 operator/( int src ) const
- {
- return StereoOut32( Left / src, Right / src );
- }
-};
-
-#endif
diff --git a/plugins/spu2-x/src/Config.h b/plugins/spu2-x/src/Config.h
new file mode 100644
index 0000000000..190bd88891
--- /dev/null
+++ b/plugins/spu2-x/src/Config.h
@@ -0,0 +1,88 @@
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
+
+#pragma once
+
+extern bool DebugEnabled;
+
+extern bool _MsgToConsole;
+extern bool _MsgKeyOnOff;
+extern bool _MsgVoiceOff;
+extern bool _MsgDMA;
+extern bool _MsgAutoDMA;
+extern bool _MsgOverruns;
+extern bool _MsgCache;
+
+extern bool _AccessLog;
+extern bool _DMALog;
+extern bool _WaveLog;
+
+extern bool _CoresDump;
+extern bool _MemDump;
+extern bool _RegDump;
+
+static __forceinline bool MsgToConsole() { return _MsgToConsole & DebugEnabled; }
+
+static __forceinline bool MsgKeyOnOff() { return _MsgKeyOnOff & MsgToConsole(); }
+static __forceinline bool MsgVoiceOff() { return _MsgVoiceOff & MsgToConsole(); }
+static __forceinline bool MsgDMA() { return _MsgDMA & MsgToConsole(); }
+static __forceinline bool MsgAutoDMA() { return _MsgAutoDMA & MsgDMA(); }
+static __forceinline bool MsgOverruns() { return _MsgOverruns & MsgToConsole(); }
+static __forceinline bool MsgCache() { return _MsgCache & MsgToConsole(); }
+
+static __forceinline bool AccessLog() { return _AccessLog & DebugEnabled; }
+static __forceinline bool DMALog() { return _DMALog & DebugEnabled; }
+static __forceinline bool WaveLog() { return _WaveLog & DebugEnabled; }
+
+static __forceinline bool CoresDump() { return _CoresDump & DebugEnabled; }
+static __forceinline bool MemDump() { return _MemDump & DebugEnabled; }
+static __forceinline bool RegDump() { return _RegDump & DebugEnabled; }
+
+
+extern wchar_t AccessLogFileName[255];
+extern wchar_t WaveLogFileName[255];
+extern wchar_t DMA4LogFileName[255];
+extern wchar_t DMA7LogFileName[255];
+extern wchar_t CoresDumpFileName[255];
+extern wchar_t MemDumpFileName[255];
+extern wchar_t RegDumpFileName[255];
+
+extern int Interpolation;
+
+extern bool EffectsDisabled;
+
+extern u32 OutputModule;
+extern int SndOutLatencyMS;
+
+extern wchar_t dspPlugin[];
+extern int dspPluginModule;
+
+extern bool dspPluginEnabled;
+extern bool timeStretchDisabled;
+extern bool StereoExpansionEnabled;
+
+namespace SoundtouchCfg
+{
+ extern void ApplySettings( soundtouch::SoundTouch& sndtouch );
+}
+
+//////
+
+extern void ReadSettings();
+extern void WriteSettings();
+extern void configure();
+extern void AboutBox();
diff --git a/plugins/spu2-x/src/ConvertUTF.cpp b/plugins/spu2-x/src/ConvertUTF.cpp
index 24679ae4fd..66d031607d 100644
--- a/plugins/spu2-x/src/ConvertUTF.cpp
+++ b/plugins/spu2-x/src/ConvertUTF.cpp
@@ -38,13 +38,9 @@
------------------------------------------------------------------------ */
-#include "PS2Etypes.h"
-
-#include
-#include
+#include "Global.h"
#include "ConvertUTF.h"
-
using std::string;
using std::wstring;
diff --git a/plugins/spu2-x/src/Debug.cpp b/plugins/spu2-x/src/Debug.cpp
index 404db45524..114f728ff1 100644
--- a/plugins/spu2-x/src/Debug.cpp
+++ b/plugins/spu2-x/src/Debug.cpp
@@ -15,7 +15,7 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
int crazy_debug=0;
diff --git a/plugins/spu2-x/src/Decoder.cpp b/plugins/spu2-x/src/Decoder.cpp
index f2174be3ef..5f76691481 100644
--- a/plugins/spu2-x/src/Decoder.cpp
+++ b/plugins/spu2-x/src/Decoder.cpp
@@ -15,7 +15,8 @@
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-#include "Spu2.h"
+
+#include "Global.h"
extern "C" {
#include "liba52/inttypes.h"
@@ -129,12 +130,13 @@ s32 stoi(sample_t n) //input: [-1..1]
void spdif_update()
{
- StereoOut32 Data;
+
for(int i=0;i.
*/
-#include "Spu2.h"
+#include "Global.h"
+#include "dma.h"
+
+#include "PS2E-spu2.h" // temporary until I resolve cyclePtr/TimeUpdate dependencies.
extern u8 callirq;
-FILE *DMA4LogFile=0;
-FILE *DMA7LogFile=0;
-FILE *ADMA4LogFile=0;
-FILE *ADMA7LogFile=0;
-FILE *ADMAOutLogFile=0;
+static FILE *DMA4LogFile = NULL;
+static FILE *DMA7LogFile = NULL;
+static FILE *ADMA4LogFile = NULL;
+static FILE *ADMA7LogFile = NULL;
+static FILE *ADMAOutLogFile = NULL;
-FILE *REGWRTLogFile[2]={0,0};
-
-int packcount=0;
-
-u16* MBASE[2] = {0,0};
-
-u16* DMABaseAddr;
+static FILE *REGWRTLogFile[2] = {0,0};
void DMALogOpen()
{
@@ -56,16 +53,6 @@ void DMA7LogWrite(void *lpData, u32 ulSize) {
fwrite(lpData,ulSize,1,DMA7LogFile);
}
-void ADMA4LogWrite(void *lpData, u32 ulSize) {
- if(!DMALog()) return;
- if (!ADMA4LogFile) return;
- fwrite(lpData,ulSize,1,ADMA4LogFile);
-}
-void ADMA7LogWrite(void *lpData, u32 ulSize) {
- if(!DMALog()) return;
- if (!ADMA7LogFile) return;
- fwrite(lpData,ulSize,1,ADMA7LogFile);
-}
void ADMAOutLogWrite(void *lpData, u32 ulSize) {
if(!DMALog()) return;
if (!ADMAOutLogFile) return;
@@ -79,118 +66,110 @@ void RegWriteLog(u32 core,u16 value)
fwrite(&value,2,1,REGWRTLogFile[core]);
}
-void DMALogClose() {
- if(!DMALog()) return;
- if (DMA4LogFile) fclose(DMA4LogFile);
- if (DMA7LogFile) fclose(DMA7LogFile);
- if (REGWRTLogFile[0]) fclose(REGWRTLogFile[0]);
- if (REGWRTLogFile[1]) fclose(REGWRTLogFile[1]);
- if (ADMA4LogFile) fclose(ADMA4LogFile);
- if (ADMA7LogFile) fclose(ADMA7LogFile);
- if (ADMAOutLogFile) fclose(ADMAOutLogFile);
+void DMALogClose()
+{
+ safe_fclose(DMA4LogFile);
+ safe_fclose(DMA7LogFile);
+ safe_fclose(REGWRTLogFile[0]);
+ safe_fclose(REGWRTLogFile[1]);
+ safe_fclose(ADMA4LogFile);
+ safe_fclose(ADMA7LogFile);
+ safe_fclose(ADMAOutLogFile);
}
-
-__forceinline u16 DmaRead(u32 core)
+void V_Core::LogAutoDMA( FILE* fp )
{
- const u16 ret = (u16)spu2M_Read(Cores[core].TDA);
- Cores[core].TDA++;
- Cores[core].TDA&=0xfffff;
- return ret;
+ if( !DMALog() || !fp ) return;
+ fwrite( DMAPtr+InputDataProgress, 0x400, 1, fp );
}
-__forceinline void DmaWrite(u32 core, u16 value)
+void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not split stereo
{
- spu2M_Write( Cores[core].TSA, value );
- Cores[core].TSA++;
- Cores[core].TSA&=0xfffff;
-}
+ int spos = ((InputPos+0xff)&0x100); //starting position of the free buffer
-void AutoDMAReadBuffer(int core, int mode) //mode: 0= split stereo; 1 = do not split stereo
-{
- int spos=((Cores[core].InputPos+0xff)&0x100); //starting position of the free buffer
+ LogAutoDMA( Index ? ADMA7LogFile : ADMA4LogFile );
- if(core==0)
- ADMA4LogWrite(Cores[core].DMAPtr+Cores[core].InputDataProgress,0x400);
- else
- ADMA7LogWrite(Cores[core].DMAPtr+Cores[core].InputDataProgress,0x400);
+ // HACKFIX!! DMAPtr can be invalid after a savestate load, so the savestate just forces it
+ // to NULL and we ignore it here. (used to work in old VM editions of PCSX2 with fixed
+ // addressing, but new PCSX2s have dynamic memory addressing).
if(mode)
- {
- //hacky :p
-
- memcpy((Cores[core].ADMATempBuffer+(spos<<1)),Cores[core].DMAPtr+Cores[core].InputDataProgress,0x400);
- Cores[core].MADR+=0x400;
- Cores[core].InputDataLeft-=0x200;
- Cores[core].InputDataProgress+=0x200;
+ {
+ if( DMAPtr != NULL )
+ memcpy((ADMATempBuffer+(spos<<1)),DMAPtr+InputDataProgress,0x400);
+ MADR+=0x400;
+ InputDataLeft-=0x200;
+ InputDataProgress+=0x200;
}
else
{
- memcpy((Cores[core].ADMATempBuffer+spos),Cores[core].DMAPtr+Cores[core].InputDataProgress,0x200);
- //memcpy((spu2mem+0x2000+(core<<10)+spos),Cores[core].DMAPtr+Cores[core].InputDataProgress,0x200);
- Cores[core].MADR+=0x200;
- Cores[core].InputDataLeft-=0x100;
- Cores[core].InputDataProgress+=0x100;
+ if( DMAPtr != NULL )
+ memcpy((ADMATempBuffer+spos),DMAPtr+InputDataProgress,0x200);
+ //memcpy((spu2mem+0x2000+(core<<10)+spos),DMAPtr+InputDataProgress,0x200);
+ MADR+=0x200;
+ InputDataLeft-=0x100;
+ InputDataProgress+=0x100;
- memcpy((Cores[core].ADMATempBuffer+spos+0x200),Cores[core].DMAPtr+Cores[core].InputDataProgress,0x200);
- //memcpy((spu2mem+0x2200+(core<<10)+spos),Cores[core].DMAPtr+Cores[core].InputDataProgress,0x200);
- Cores[core].MADR+=0x200;
- Cores[core].InputDataLeft-=0x100;
- Cores[core].InputDataProgress+=0x100;
+ if( DMAPtr != NULL )
+ memcpy((ADMATempBuffer+spos+0x200),DMAPtr+InputDataProgress,0x200);
+ //memcpy((spu2mem+0x2200+(core<<10)+spos),DMAPtr+InputDataProgress,0x200);
+ MADR+=0x200;
+ InputDataLeft-=0x100;
+ InputDataProgress+=0x100;
}
// See ReadInput at mixer.cpp for explanation on the commented out lines
//
}
-void StartADMAWrite(int core,u16 *pMem, u32 sz)
+void V_Core::StartADMAWrite(u16 *pMem, u32 sz)
{
- int size=(sz)&(~511);
+ int size = (sz)&(~511);
if(MsgAutoDMA()) ConLog(" * SPU2: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n",
- (core==0)?'4':'7',size<<1,Cores[core].TSA,Cores[core].DMABits,Cores[core].AutoDMACtrl,(~Cores[core].Regs.ATTR)&0x7fff);
+ GetDmaIndexChar(), size<<1, TSA, DMABits, AutoDMACtrl, (~Regs.ATTR)&0x7fff);
- Cores[core].InputDataProgress=0;
- if((Cores[core].AutoDMACtrl&(core+1))==0)
+ InputDataProgress=0;
+ if((AutoDMACtrl&(Index+1))==0)
{
- Cores[core].TSA=0x2000+(core<<10);
- Cores[core].DMAICounter=size;
+ TSA=0x2000+(Index<<10);
+ DMAICounter=size;
}
else if(size>=512)
{
- Cores[core].InputDataLeft=size;
- if(Cores[core].AdmaInProgress==0)
+ InputDataLeft=size;
+ if(AdmaInProgress==0)
{
#ifdef PCM24_S1_INTERLEAVE
- if((core==1)&&((PlayMode&8)==8))
+ if((Index==1)&&((PlayMode&8)==8))
{
- AutoDMAReadBuffer(core,1);
+ AutoDMAReadBuffer(Index,1);
}
else
{
- AutoDMAReadBuffer(core,0);
+ AutoDMAReadBuffer(Index,0);
}
#else
- if(((PlayMode&4)==4)&&(core==0))
+ if(((PlayMode&4)==4)&&(Index==0))
Cores[0].InputPos=0;
- AutoDMAReadBuffer(core,0);
+ AutoDMAReadBuffer(0);
#endif
if(size==512)
- Cores[core].DMAICounter=size;
+ DMAICounter=size;
}
- Cores[core].AdmaInProgress=1;
+ AdmaInProgress=1;
}
else
{
- Cores[core].InputDataLeft=0;
- Cores[core].DMAICounter=1;
+ InputDataLeft=0;
+ DMAICounter=1;
}
- Cores[core].TADR=Cores[core].MADR+(size<<1);
+ TADR=MADR+(size<<1);
}
-void DoDMAWrite(int core,u16 *pMem,u32 size)
+void V_Core::PlainDMAWrite(u16 *pMem, u32 size)
{
// Perform an alignment check.
// Not really important. Everything should work regardless,
@@ -198,29 +177,29 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
#if 0
uptr pa = ((uptr)pMem)&7;
- uptr pm = Cores[core].TSA&0x7;
+ uptr pm = TSA&0x7;
if( pa )
{
- fprintf(stderr, "* SPU2 DMA Write > Missaligned SOURCE! Core: %d TSA: 0x%x TDA: 0x%x Size: 0x%x\n", core, Cores[core].TSA, Cores[core].TDA, size);
+ fprintf(stderr, "* SPU2 DMA Write > Missaligned SOURCE! Core: %d TSA: 0x%x TDA: 0x%x Size: 0x%x\n", core, TSA, TDA, size);
}
if( pm )
{
- fprintf(stderr, "* SPU2 DMA Write > Missaligned TARGET! Core: %d TSA: 0x%x TDA: 0x%x Size: 0x%x\n", core, Cores[core].TSA, Cores[core].TDA, size );
+ fprintf(stderr, "* SPU2 DMA Write > Missaligned TARGET! Core: %d TSA: 0x%x TDA: 0x%x Size: 0x%x\n", core, TSA, TDA, size );
}
#endif
- if(core==0)
+ if(Index==0)
DMA4LogWrite(pMem,size<<1);
else
DMA7LogWrite(pMem,size<<1);
- if(MsgDMA()) ConLog(" * SPU2: DMA%c Transfer of %d bytes to %x (%02x %x %04x).\n",(core==0)?'4':'7',size<<1,Cores[core].TSA,Cores[core].DMABits,Cores[core].AutoDMACtrl,(~Cores[core].Regs.ATTR)&0x7fff);
+ if(MsgDMA()) ConLog(" * SPU2: DMA%c Transfer of %d bytes to %x (%02x %x %04x).\n",GetDmaIndexChar(),size<<1,TSA,DMABits,AutoDMACtrl,(~Regs.ATTR)&0x7fff);
- Cores[core].TSA &= 0xfffff;
+ TSA &= 0xfffff;
- u32 buff1end = Cores[core].TSA + size;
+ u32 buff1end = TSA + size;
u32 buff2end=0;
if( buff1end > 0x100000 )
{
@@ -228,7 +207,7 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
buff1end = 0x100000;
}
- const int cacheIdxStart = Cores[core].TSA / pcm_WordsPerBlock;
+ const int cacheIdxStart = TSA / pcm_WordsPerBlock;
const int cacheIdxEnd = (buff1end+pcm_WordsPerBlock-1) / pcm_WordsPerBlock;
PcmCacheEntry* cacheLine = &pcm_cache_data[cacheIdxStart];
PcmCacheEntry& cacheEnd = pcm_cache_data[cacheIdxEnd];
@@ -240,14 +219,14 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
} while ( cacheLine != &cacheEnd );
//ConLog( " * SPU2 : Cache Clear Range! TSA=0x%x, TDA=0x%x (low8=0x%x, high8=0x%x, len=0x%x)\n",
- // Cores[core].TSA, buff1end, flagTSA, flagTDA, clearLen );
+ // TSA, buff1end, flagTSA, flagTDA, clearLen );
// First Branch needs cleared:
// It starts at TSA and goes to buff1end.
- const u32 buff1size = (buff1end-Cores[core].TSA);
- memcpy( GetMemPtr( Cores[core].TSA ), pMem, buff1size*2 );
+ const u32 buff1size = (buff1end-TSA);
+ memcpy( GetMemPtr( TSA ), pMem, buff1size*2 );
if( buff2end > 0 )
{
@@ -263,57 +242,50 @@ void DoDMAWrite(int core,u16 *pMem,u32 size)
// 0x2800? Hard to know for usre (almost no games depend on this)
memcpy( GetMemPtr( 0 ), &pMem[buff1size], buff2end*2 );
- Cores[core].TDA = (buff2end+1) & 0xfffff;
-
- if(Cores[core].IRQEnable)
- {
- // Flag interrupt?
- // If IRQA occurs between start and dest, flag it.
- // Since the buffer wraps, the conditional might seem odd, but it works.
-
- if( ( Cores[core].IRQA >= Cores[core].TSA ) ||
- ( Cores[core].IRQA < Cores[core].TDA ) )
- {
- Spdif.Info = 4 << core;
- SetIrqCall();
- }
- }
+ TDA = (buff2end+1) & 0xfffff;
}
else
{
// Buffer doesn't wrap/overflow!
// Just set the TDA and check for an IRQ...
- Cores[core].TDA = buff1end;
+ TDA = buff1end;
+ }
- if(Cores[core].IRQEnable)
+ // Flag interrupt? If IRQA occurs between start and dest, flag it.
+ // Important: Test both core IRQ settings for either DMA!
+
+ for( int i=0; i<2; i++ )
+ {
+ // Note: (start is inclusive, dest exclusive -- fixes DMC1 FMVs)
+
+ if( Cores[i].IRQEnable && (Cores[i].IRQA >= Cores[i].TSA) && (Cores[i].IRQA < Cores[i].TDA) )
{
- // Flag interrupt?
- // If IRQA occurs between start and dest, flag it.
- // (start is inclusive, dest exclusive -- fixes DMC1 and hopefully won't break
- // other games. ;)
-
- if( ( Cores[core].IRQA >= Cores[core].TSA ) &&
- ( Cores[core].IRQA < Cores[core].TDA ) )
- {
- Spdif.Info = 4 << core;
- SetIrqCall();
- }
+ Spdif.Info = 4 << i;
+ SetIrqCall();
}
}
- Cores[core].TSA=Cores[core].TDA&0xFFFF0;
- Cores[core].DMAICounter=size;
- Cores[core].TADR=Cores[core].MADR+(size<<1);
+ if(IRQEnable)
+ {
+
+ if( ( IRQA >= TSA ) && ( IRQA < TDA ) )
+ {
+ Spdif.Info = 4 << Index;
+ SetIrqCall();
+ }
+ }
+
+ TSA = TDA & 0xFFFF0;
+ DMAICounter = size;
+ TADR = MADR + (size<<1);
}
-void SPU2readDMA(int core, u16* pMem, u32 size)
+void V_Core::DoDMAread(u16* pMem, u32 size)
{
- if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+ TSA &= 0xffff8;
- Cores[core].TSA &= 0xffff8;
-
- u32 buff1end = Cores[core].TSA + size;
+ u32 buff1end = TSA + size;
u32 buff2end = 0;
if( buff1end > 0x100000 )
{
@@ -321,8 +293,8 @@ void SPU2readDMA(int core, u16* pMem, u32 size)
buff1end = 0x100000;
}
- const u32 buff1size = (buff1end-Cores[core].TSA);
- memcpy( pMem, GetMemPtr( Cores[core].TSA ), buff1size*2 );
+ const u32 buff1size = (buff1end-TSA);
+ memcpy( pMem, GetMemPtr( TSA ), buff1size*2 );
// Note on TSA's position after our copy finishes:
// IRQA should be measured by the end of the writepos+0x20. But the TDA
@@ -335,146 +307,65 @@ void SPU2readDMA(int core, u16* pMem, u32 size)
memcpy( &pMem[buff1size], GetMemPtr( 0 ), buff2end*2 );
- Cores[core].TDA = (buff2end+0x20) & 0xfffff;
-
- for( int i=0; i<2; i++ )
- {
- if(Cores[i].IRQEnable)
- {
- // Flag interrupt?
- // If IRQA occurs between start and dest, flag it.
- // Since the buffer wraps, the conditional might seem odd, but it works.
-
- if( ( Cores[i].IRQA >= Cores[core].TSA ) ||
- ( Cores[i].IRQA <= Cores[core].TDA ) )
- {
- Spdif.Info=4<= Cores[i].TSA) && (Cores[i].IRQA < Cores[i].TDA) )
{
- if(Cores[i].IRQEnable)
- {
- // Flag interrupt?
- // If IRQA occurs between start and dest, flag it:
-
- if( ( Cores[i].IRQA >= Cores[i].TSA ) &&
- ( Cores[i].IRQA < Cores[i].TDA ) )
- {
- Spdif.Info=4<
-//
-//This library is free software; you can redistribute it and/or
-//modify it under the terms of the GNU Lesser General Public
-//License as published by the Free Software Foundation; either
-//version 2.1 of the License, or (at your option) any later version.
-//
-//This library is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-//Lesser General Public License for more details.
-//
-//You should have received a copy of the GNU Lesser General Public
-//License along with this library; if not, write to the Free Software
-//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#ifndef DMA_H_INCLUDED
-#define DMA_H_INCLUDED
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
-void DMALogOpen();
-void DMA4LogWrite(void *lpData, u32 ulSize);
-void DMA7LogWrite(void *lpData, u32 ulSize);
-void DMALogClose();
+#pragma once
-extern void DmaWrite(u32 core, u16 data);
-extern u16 DmaRead(u32 core);
-
-extern void AutoDMAReadBuffer(int core, int mode);
-
-#endif // DMA_H_INCLUDED //
\ No newline at end of file
+extern void DMALogOpen();
+extern void DMA4LogWrite(void *lpData, u32 ulSize);
+extern void DMA7LogWrite(void *lpData, u32 ulSize);
+extern void DMALogClose();
diff --git a/plugins/spu2-x/src/Global.h b/plugins/spu2-x/src/Global.h
new file mode 100644
index 0000000000..f0db1b915b
--- /dev/null
+++ b/plugins/spu2-x/src/Global.h
@@ -0,0 +1,110 @@
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
+
+#ifndef _SPU2X_GLOBAL_H_
+#define _SPU2X_GLOBAL_H_
+
+struct StereoOut16;
+struct StereoOut32;
+struct StereoOutFloat;
+
+struct V_Core;
+
+namespace soundtouch
+{
+ class SoundTouch;
+}
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using std::string;
+using std::wstring;
+
+#include "Pcsx2Types.h"
+
+namespace VersionInfo
+{
+ static const u8 Release = 1;
+ static const u8 Revision = 3; // increase that with each version
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Override Win32 min/max macros with the STL's type safe and macro
+// free varieties (much safer!)
+
+#undef min
+#undef max
+
+template< typename T >
+static __forceinline void Clampify( T& src, T min, T max )
+{
+ src = std::min( std::max( src, min ), max );
+}
+
+template< typename T >
+static __forceinline T GetClamped( T src, T min, T max )
+{
+ return std::min( std::max( src, min ), max );
+}
+
+extern void SysMessage(const char *fmt, ...);
+
+//////////////////////////////////////////////////////////////
+// Dev / Debug conditionals --
+// Consts for using if() statements instead of uglier #ifdef macros.
+// Abbreviated macros for dev/debug only consoles and msgboxes.
+
+#ifdef PCSX2_DEVBUILD
+# define DevCon Console
+# define DevMsg MsgBox
+#else
+# define DevCon 0&&Console
+# define DevMsg
+#endif
+
+#ifdef PCSX2_DEBUG
+# define DbgCon Console
+#else
+# define DbgCon 0&&Console
+#endif
+
+#ifdef PCSX2_DEVBUILD
+# define SPU2_LOG
+#endif
+
+#include "Utilities/Exceptions.h"
+#include "Utilities/SafeArray.h"
+
+#include "ConvertUTF.h"
+
+#include "defs.h"
+#include "regs.h"
+
+#include "Config.h"
+#include "Debug.h"
+#include "SndOut.h"
+
+#endif
\ No newline at end of file
diff --git a/plugins/spu2-x/src/Linux/Config.cpp b/plugins/spu2-x/src/Linux/Config.cpp
index 848ce31b27..79f14a2fb4 100644
--- a/plugins/spu2-x/src/Linux/Config.cpp
+++ b/plugins/spu2-x/src/Linux/Config.cpp
@@ -1,8 +1,8 @@
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
- * Developed and maintained by the Pcsx2 Development Team.
- *
- * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
- *
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
@@ -14,95 +14,95 @@
* You should have received a copy of the GNU Lesser General Public License
* along with SPU2-X. If not, see .
*/
-
-#include "Spu2.h"
-#include "Dialogs.h"
-
-bool DebugEnabled=false;
-bool _MsgToConsole=false;
-bool _MsgKeyOnOff=false;
-bool _MsgVoiceOff=false;
-bool _MsgDMA=false;
-bool _MsgAutoDMA=false;
-bool _MsgOverruns=false;
-bool _MsgCache=false;
-
-bool _AccessLog=false;
-bool _DMALog=false;
-bool _WaveLog=false;
-
-bool _CoresDump=false;
-bool _MemDump=false;
-bool _RegDump=false;
-
-
-
-wchar_t AccessLogFileName[255];
-wchar_t WaveLogFileName[255];
-
-wchar_t DMA4LogFileName[255];
-wchar_t DMA7LogFileName[255];
-
-wchar_t CoresDumpFileName[255];
-wchar_t MemDumpFileName[255];
-wchar_t RegDumpFileName[255];
-
-
-#ifdef SPU2X_DEVBUILD
-static const int LATENCY_MAX = 3000;
-#else
-static const int LATENCY_MAX = 750;
-#endif
-
-static const int LATENCY_MIN = 40;
-
-int AutoDMAPlayRate[2] = {0,0};
-
-// MIXING
-int Interpolation = 1;
-/* values:
- 0: no interpolation (use nearest)
- 1. linear interpolation
- 2. cubic interpolation
-*/
-
-bool EffectsDisabled = false;
-
-// OUTPUT
-int SndOutLatencyMS = 160;
-bool timeStretchDisabled = false;
-
-u32 OutputModule = 0;
-
-CONFIG_DSOUNDOUT Config_DSoundOut;
-CONFIG_WAVEOUT Config_WaveOut;
-CONFIG_XAUDIO2 Config_XAudio2;
-
-// DSP
-bool dspPluginEnabled = false;
-int dspPluginModule = 0;
-wchar_t dspPlugin[256];
-
-bool StereoExpansionEnabled = false;
-
-/*****************************************************************************/
-
-void ReadSettings()
-{
-}
-
-/*****************************************************************************/
-
-void WriteSettings()
-{
-}
-
-
-void configure()
-{
- ReadSettings();
-}
-
-void MessageBox(char const*, ...)
-{
-}
+
+#include "Spu2.h"
+#include "Dialogs.h"
+
+bool DebugEnabled=false;
+bool _MsgToConsole=false;
+bool _MsgKeyOnOff=false;
+bool _MsgVoiceOff=false;
+bool _MsgDMA=false;
+bool _MsgAutoDMA=false;
+bool _MsgOverruns=false;
+bool _MsgCache=false;
+
+bool _AccessLog=false;
+bool _DMALog=false;
+bool _WaveLog=false;
+
+bool _CoresDump=false;
+bool _MemDump=false;
+bool _RegDump=false;
+
+
+
+wchar_t AccessLogFileName[255];
+wchar_t WaveLogFileName[255];
+
+wchar_t DMA4LogFileName[255];
+wchar_t DMA7LogFileName[255];
+
+wchar_t CoresDumpFileName[255];
+wchar_t MemDumpFileName[255];
+wchar_t RegDumpFileName[255];
+
+
+#ifdef PCSX2_DEVBUILD
+static const int LATENCY_MAX = 3000;
+#else
+static const int LATENCY_MAX = 750;
+#endif
+
+static const int LATENCY_MIN = 40;
+
+int AutoDMAPlayRate[2] = {0,0};
+
+// MIXING
+int Interpolation = 1;
+/* values:
+ 0: no interpolation (use nearest)
+ 1. linear interpolation
+ 2. cubic interpolation
+*/
+
+bool EffectsDisabled = false;
+
+// OUTPUT
+int SndOutLatencyMS = 160;
+bool timeStretchDisabled = false;
+
+u32 OutputModule = 0;
+
+CONFIG_DSOUNDOUT Config_DSoundOut;
+CONFIG_WAVEOUT Config_WaveOut;
+CONFIG_XAUDIO2 Config_XAudio2;
+
+// DSP
+bool dspPluginEnabled = false;
+int dspPluginModule = 0;
+wchar_t dspPlugin[256];
+
+bool StereoExpansionEnabled = false;
+
+/*****************************************************************************/
+
+void ReadSettings()
+{
+}
+
+/*****************************************************************************/
+
+void WriteSettings()
+{
+}
+
+
+void configure()
+{
+ ReadSettings();
+}
+
+void MessageBox(char const*, ...)
+{
+}
diff --git a/plugins/spu2-x/src/Linux/Config.h b/plugins/spu2-x/src/Linux/Config.h
index 2701950a5e..05a10b56d2 100644
--- a/plugins/spu2-x/src/Linux/Config.h
+++ b/plugins/spu2-x/src/Linux/Config.h
@@ -103,8 +103,6 @@ public:
protected:
static void ClampValues();
- //static bool CALLBACK DialogProc(uptr hWnd,u32 uMsg,WPARAM wParam,LPARAM lParam);
-
};
diff --git a/plugins/spu2-x/src/Linux/Linux.cpp b/plugins/spu2-x/src/Linux/Linux.cpp
index 443917f845..d10b41bc15 100644
--- a/plugins/spu2-x/src/Linux/Linux.cpp
+++ b/plugins/spu2-x/src/Linux/Linux.cpp
@@ -1,8 +1,8 @@
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
- * Developed and maintained by the Pcsx2 Development Team.
- *
- * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
- *
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
* SPU2-X is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
@@ -14,46 +14,46 @@
* You should have received a copy of the GNU Lesser General Public License
* along with SPU2-X. If not, see .
*/
-
-#include "Linux.h"
-
-void SysMessage(char *fmt, ...) {
- GtkWidget *Ok,*Txt;
- GtkWidget *Box,*Box1;
- va_list list;
- char msg[512];
-
- va_start(list, fmt);
- vsprintf(msg, fmt, list);
- va_end(list);
-
- if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
-
- MsgDlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
- gtk_window_set_title(GTK_WINDOW(MsgDlg), "SPU2null Msg");
- gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
-
- Box = gtk_vbox_new(5, 0);
- gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
- gtk_widget_show(Box);
-
- Txt = gtk_label_new(msg);
-
- gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
- gtk_widget_show(Txt);
-
- Box1 = gtk_hbutton_box_new();
- gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
- gtk_widget_show(Box1);
-
- Ok = gtk_button_new_with_label("Ok");
- gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
- gtk_container_add(GTK_CONTAINER(Box1), Ok);
- GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
- gtk_widget_show(Ok);
-
- gtk_widget_show(MsgDlg);
-
- gtk_main();
-}
+
+#include "Linux.h"
+
+void SysMessage(char *fmt, ...) {
+ GtkWidget *Ok,*Txt;
+ GtkWidget *Box,*Box1;
+ va_list list;
+ char msg[512];
+
+ va_start(list, fmt);
+ vsprintf(msg, fmt, list);
+ va_end(list);
+
+ if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
+
+ MsgDlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER);
+ gtk_window_set_title(GTK_WINDOW(MsgDlg), "SPU2null Msg");
+ gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5);
+
+ Box = gtk_vbox_new(5, 0);
+ gtk_container_add(GTK_CONTAINER(MsgDlg), Box);
+ gtk_widget_show(Box);
+
+ Txt = gtk_label_new(msg);
+
+ gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5);
+ gtk_widget_show(Txt);
+
+ Box1 = gtk_hbutton_box_new();
+ gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0);
+ gtk_widget_show(Box1);
+
+ Ok = gtk_button_new_with_label("Ok");
+ gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL);
+ gtk_container_add(GTK_CONTAINER(Box1), Ok);
+ GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT);
+ gtk_widget_show(Ok);
+
+ gtk_widget_show(MsgDlg);
+
+ gtk_main();
+}
diff --git a/plugins/spu2-x/src/Lowpass.cpp b/plugins/spu2-x/src/Lowpass.cpp
index c6d6e84fb0..1624306cd6 100644
--- a/plugins/spu2-x/src/Lowpass.cpp
+++ b/plugins/spu2-x/src/Lowpass.cpp
@@ -19,35 +19,39 @@
#include
#include
-LPF_data::LPF_data( double freq, double srate )
+template< typename FloatType > __forceinline
+LowPassFilter::LowPassFilter( FloatType freq, FloatType srate )
{
- double omega = 2.0 * freq / srate;
- static const double g = 1.0;
+ typedef FloatType FT;
+
+ FloatType omega = (FT)2.0 * freq / srate;
+ static const FloatType g = (FT)1.0;
// calculating coefficients:
- double k,p,q,a;
- double a0,a1,a2,a3,a4;
+ FloatType k,p,q,a;
+ FloatType a0,a1,a2,a3,a4;
- k=(4.0*g-3.0)/(g+1.0);
- p=1.0-0.25*k;p*=p;
+ k = ((FT)4.0*g-(FT)3.0)/(g+(FT)1.0);
+ p = (FT)1.0-(FT)0.25*k;
+ p *= p;
// LP:
- a=1.0/(tan(0.5*omega)*(1.0+p));
- p=1.0+a;
- q=1.0-a;
-
- a0=1.0/(k+p*p*p*p);
- a1=4.0*(k+p*p*p*q);
- a2=6.0*(k+p*p*q*q);
- a3=4.0*(k+p*q*q*q);
- a4= (k+q*q*q*q);
- p=a0*(k+1.0);
+ a = (FT)1.0/(tan((FT)0.5*omega)*((FT)1.0+p));
+ p = (FT)1.0+a;
+ q = (FT)1.0-a;
+ a0 = (FT)1.0/(k+p*p*p*p);
+ a1 = (FT)4.0*(k+p*p*p*q);
+ a2 = (FT)6.0*(k+p*p*q*q);
+ a3 = (FT)4.0*(k+p*q*q*q);
+ a4 = (k+q*q*q*q);
+ p = a0*(k+(FT)1.0);
+
coef[0] = p;
- coef[1] = 4.0*p;
- coef[2] = 6.0*p;
- coef[3] = 4.0*p;
+ coef[1] = (FT)4.0*p;
+ coef[2] = (FT)6.0*p;
+ coef[3] = (FT)4.0*p;
coef[4] = p;
coef[5] = -a1*a0;
coef[6] = -a2*a0;
@@ -56,9 +60,10 @@ LPF_data::LPF_data( double freq, double srate )
}
// Processes a single sample into the LPF.
-double LPF_data::sample( double inval )
+template< typename FloatType > __forceinline
+FloatType LowPassFilter::sample( FloatType inval )
{
- const double out = (coef[0]*inval) + d[0];
+ const FloatType out = (coef[0]*inval) + d[0];
d[0] = (coef[1]*inval) + (coef[5]*out) + d[1];
d[1] = (coef[2]*inval) + (coef[6]*out) + d[2];
d[2] = (coef[3]*inval) + (coef[7]*out) + d[3];
@@ -66,3 +71,23 @@ double LPF_data::sample( double inval )
return out;
}
+
+LowPassFilter32::LowPassFilter32( float freq, float srate ) :
+ impl_lpf( freq, srate )
+{
+}
+
+LowPassFilter64::LowPassFilter64( double freq, double srate ) :
+ impl_lpf( freq, srate )
+{
+}
+
+float LowPassFilter32::sample( float inval )
+{
+ return impl_lpf.sample( inval );
+}
+
+double LowPassFilter64::sample( double inval )
+{
+ return impl_lpf.sample( inval );
+}
diff --git a/plugins/spu2-x/src/Lowpass.h b/plugins/spu2-x/src/Lowpass.h
index 23dc5f8380..f1876b04c0 100644
--- a/plugins/spu2-x/src/Lowpass.h
+++ b/plugins/spu2-x/src/Lowpass.h
@@ -1,30 +1,44 @@
/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
-* Developed and maintained by the Pcsx2 Development Team.
-*
-* Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
-*
-* SPU2-X is free software: you can redistribute it and/or modify it under the terms
-* of the GNU Lesser General Public License as published by the Free Software Found-
-* ation, either version 3 of the License, or (at your option) any later version.
-*
-* SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-* PURPOSE. See the GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with SPU2-X. If not, see .
-*/
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
#pragma once
-#include "BaseTypes.h"
-
-struct LPF_data
+template< typename FloatType >
+struct LowPassFilter
{
- double coef[9];
- double d[4];
+ FloatType coef[9];
+ FloatType d[4];
- LPF_data( double freq, double srate );
- double sample( double inval );
+ LowPassFilter( FloatType freq, FloatType srate );
+ FloatType sample( FloatType inval );
};
+struct LowPassFilter32
+{
+ LowPassFilter impl_lpf;
+
+ LowPassFilter32( float freq, float srate );
+ float sample( float inval );
+};
+
+struct LowPassFilter64
+{
+ LowPassFilter impl_lpf;
+
+ LowPassFilter64( double freq, double srate );
+ double sample( double inval );
+};
diff --git a/plugins/spu2-x/src/Mixer.cpp b/plugins/spu2-x/src/Mixer.cpp
index fb41dfb818..a9e1c1bcc7 100644
--- a/plugins/spu2-x/src/Mixer.cpp
+++ b/plugins/spu2-x/src/Mixer.cpp
@@ -15,8 +15,8 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
-#include
+#include "Global.h"
+//#include
extern void spdif_update();
@@ -477,22 +477,9 @@ static s32 __forceinline __fastcall GetNoiseValues( V_Core& thiscore, uint voice
/////////////////////////////////////////////////////////////////////////////////////////
// //
-static __forceinline StereoOut32 ReadInputPV( uint core )
+__forceinline StereoOut32 V_Core::ReadInputPV()
{
- V_Core& thiscore( Cores[core] );
- u32 pitch = AutoDMAPlayRate[core];
-
- if(pitch==0) pitch=48000;
-
- thiscore.ADMAPV += pitch;
- while(thiscore.ADMAPV>=48000)
- {
- ReadInput( core, thiscore.ADMAP );
- thiscore.ADMAPV -= 48000;
- }
-
- // Apply volumes:
- return ApplyVolume( thiscore.ADMAP, thiscore.InpVol );
+ return ApplyVolume( ReadInput(), InpVol );
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -547,7 +534,7 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx )
vc.OutX = Value;
if( IsDevBuild )
- DebugCores[coreidx].Voices[voiceidx].displayPeak = max(DebugCores[coreidx].Voices[voiceidx].displayPeak,abs(vc.OutX));
+ DebugCores[coreidx].Voices[voiceidx].displayPeak = std::max(DebugCores[coreidx].Voices[voiceidx].displayPeak,abs(vc.OutX));
// Write-back of raw voice data (post ADSR applied)
@@ -567,19 +554,6 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx )
}
}
-struct VoiceMixSet
-{
- static const VoiceMixSet Empty;
- StereoOut32 Dry, Wet;
-
- VoiceMixSet() {}
- VoiceMixSet( const StereoOut32& dry, const StereoOut32& wet ) :
- Dry( dry ),
- Wet( wet )
- {
- }
-};
-
const VoiceMixSet VoiceMixSet::Empty( (StereoOut32()), (StereoOut32()) ); // Don't use SteroOut32::Empty because C++ doesn't make any dep/order checks on global initializers.
static __forceinline void MixCoreVoices( VoiceMixSet& dest, const uint coreidx )
@@ -599,61 +573,60 @@ static __forceinline void MixCoreVoices( VoiceMixSet& dest, const uint coreidx )
}
}
-static StereoOut32 __fastcall MixCore( const uint coreidx, const VoiceMixSet& inVoices, const StereoOut32& Input, const StereoOut32& Ext )
+StereoOut32 V_Core::Mix( const VoiceMixSet& inVoices, const StereoOut32& Input, const StereoOut32& Ext )
{
- V_Core& thiscore( Cores[coreidx] );
- thiscore.MasterVol.Update();
+ MasterVol.Update();
// Saturate final result to standard 16 bit range.
const VoiceMixSet Voices( clamp_mix( inVoices.Dry ), clamp_mix( inVoices.Wet ) );
// Write Mixed results To Output Area
- spu2M_WriteFast( 0x1000 + (coreidx<<12) + OutPos, Voices.Dry.Left );
- spu2M_WriteFast( 0x1200 + (coreidx<<12) + OutPos, Voices.Dry.Right );
- spu2M_WriteFast( 0x1400 + (coreidx<<12) + OutPos, Voices.Wet.Left );
- spu2M_WriteFast( 0x1600 + (coreidx<<12) + OutPos, Voices.Wet.Right );
+ spu2M_WriteFast( 0x1000 + (Index<<12) + OutPos, Voices.Dry.Left );
+ spu2M_WriteFast( 0x1200 + (Index<<12) + OutPos, Voices.Dry.Right );
+ spu2M_WriteFast( 0x1400 + (Index<<12) + OutPos, Voices.Wet.Left );
+ spu2M_WriteFast( 0x1600 + (Index<<12) + OutPos, Voices.Wet.Right );
// Write mixed results to logfile (if enabled)
- WaveDump::WriteCore( coreidx, CoreSrc_DryVoiceMix, Voices.Dry );
- WaveDump::WriteCore( coreidx, CoreSrc_WetVoiceMix, Voices.Wet );
+ WaveDump::WriteCore( Index, CoreSrc_DryVoiceMix, Voices.Dry );
+ WaveDump::WriteCore( Index, CoreSrc_WetVoiceMix, Voices.Wet );
// Mix in the Input data
StereoOut32 TD(
- Input.Left & thiscore.DryGate.InpL,
- Input.Right & thiscore.DryGate.InpR
+ Input.Left & DryGate.InpL,
+ Input.Right & DryGate.InpR
);
// Mix in the Voice data
- TD.Left += Voices.Dry.Left & thiscore.DryGate.SndL;
- TD.Right += Voices.Dry.Right & thiscore.DryGate.SndR;
+ TD.Left += Voices.Dry.Left & DryGate.SndL;
+ TD.Right += Voices.Dry.Right & DryGate.SndR;
// Mix in the External (nothing/core0) data
- TD.Left += Ext.Left & thiscore.DryGate.ExtL;
- TD.Right += Ext.Right & thiscore.DryGate.ExtR;
+ TD.Left += Ext.Left & DryGate.ExtL;
+ TD.Right += Ext.Right & DryGate.ExtR;
if( !EffectsDisabled )
{
//Reverb pointer advances regardless of the FxEnable bit...
- Reverb_AdvanceBuffer( thiscore );
+ Reverb_AdvanceBuffer();
- if( thiscore.FxEnable )
+ if( FxEnable )
{
// Mix Input, Voice, and External data:
StereoOut32 TW(
- Input.Left & thiscore.WetGate.InpL,
- Input.Right & thiscore.WetGate.InpR
+ Input.Left & WetGate.InpL,
+ Input.Right & WetGate.InpR
);
- TW.Left += Voices.Wet.Left & thiscore.WetGate.SndL;
- TW.Right += Voices.Wet.Right & thiscore.WetGate.SndR;
- TW.Left += Ext.Left & thiscore.WetGate.ExtL;
- TW.Right += Ext.Right & thiscore.WetGate.ExtR;
+ TW.Left += Voices.Wet.Left & WetGate.SndL;
+ TW.Right += Voices.Wet.Right & WetGate.SndR;
+ TW.Left += Ext.Left & WetGate.ExtL;
+ TW.Right += Ext.Right & WetGate.ExtR;
- WaveDump::WriteCore( coreidx, CoreSrc_PreReverb, TW );
+ WaveDump::WriteCore( Index, CoreSrc_PreReverb, TW );
- StereoOut32 RV( DoReverb( thiscore, TW ) );
+ StereoOut32 RV( DoReverb( TW ) );
// Volume boost after effects application. Boosting volume prior to effects
// causes slight overflows in some games, and the volume boost is required.
@@ -663,15 +636,15 @@ static StereoOut32 __fastcall MixCore( const uint coreidx, const VoiceMixSet& in
RV.Left *= 2;
RV.Right *= 2;
- WaveDump::WriteCore( coreidx, CoreSrc_PostReverb, RV );
+ WaveDump::WriteCore( Index, CoreSrc_PostReverb, RV );
// Mix Dry+Wet
- return TD + ApplyVolume( RV, thiscore.FxVol );
+ return TD + ApplyVolume( RV, FxVol );
}
else
{
- WaveDump::WriteCore( coreidx, CoreSrc_PreReverb, 0, 0 );
- WaveDump::WriteCore( coreidx, CoreSrc_PostReverb, 0, 0 );
+ WaveDump::WriteCore( Index, CoreSrc_PreReverb, 0, 0 );
+ WaveDump::WriteCore( Index, CoreSrc_PostReverb, 0, 0 );
}
}
return TD;
@@ -685,8 +658,8 @@ __forceinline void Mix()
// Note: Playmode 4 is SPDIF, which overrides other inputs.
StereoOut32 InputData[2] =
{
- (PlayMode&4) ? StereoOut32::Empty : ReadInputPV( 0 ),
- (PlayMode&8) ? StereoOut32::Empty : ReadInputPV( 1 )
+ (PlayMode&4) ? StereoOut32::Empty : Cores[0].ReadInputPV(),
+ (PlayMode&8) ? StereoOut32::Empty : Cores[1].ReadInputPV()
};
WaveDump::WriteCore( 0, CoreSrc_Input, InputData[0] );
@@ -697,7 +670,7 @@ __forceinline void Mix()
MixCoreVoices( VoiceData[0], 0 );
MixCoreVoices( VoiceData[1], 1 );
- StereoOut32 Ext( MixCore( 0, VoiceData[0], InputData[0], StereoOut32::Empty ) );
+ StereoOut32 Ext( Cores[0].Mix( VoiceData[0], InputData[0], StereoOut32::Empty ) );
if( (PlayMode & 4) || (Cores[0].Mute!=0) )
Ext = StereoOut32::Empty;
@@ -714,14 +687,14 @@ __forceinline void Mix()
WaveDump::WriteCore( 0, CoreSrc_External, Ext );
ApplyVolume( Ext, Cores[1].ExtVol );
- StereoOut32 Out( MixCore( 1, VoiceData[1], InputData[1], Ext ) );
+ StereoOut32 Out( Cores[1].Mix( VoiceData[1], InputData[1], Ext ) );
if( PlayMode & 8 )
{
// Experimental CDDA support
// The CDDA overrides all other mixer output. It's a direct feed!
- ReadInput( 1, Out );
+ Out = Cores[1].ReadInput();
//WaveLog::WriteCore( 1, "CDDA-32", OutL, OutR );
}
else
diff --git a/plugins/spu2-x/src/Mixer.h b/plugins/spu2-x/src/Mixer.h
new file mode 100644
index 0000000000..8422a17154
--- /dev/null
+++ b/plugins/spu2-x/src/Mixer.h
@@ -0,0 +1,62 @@
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
+
+
+#pragma once
+
+struct StereoOut32
+{
+ static StereoOut32 Empty;
+
+ s32 Left;
+ s32 Right;
+
+ StereoOut32() :
+ Left( 0 ),
+ Right( 0 )
+ {
+ }
+
+ StereoOut32( s32 left, s32 right ) :
+ Left( left ),
+ Right( right )
+ {
+ }
+
+ StereoOut32( const StereoOut16& src );
+ explicit StereoOut32( const StereoOutFloat& src );
+
+ StereoOut16 DownSample() const;
+
+ StereoOut32 operator+( const StereoOut32& right ) const
+ {
+ return StereoOut32(
+ Left + right.Left,
+ Right + right.Right
+ );
+ }
+
+ StereoOut32 operator/( int src ) const
+ {
+ return StereoOut32( Left / src, Right / src );
+ }
+};
+
+
+extern void Mix();
+extern s32 clamp_mix( s32 x, u8 bitshift=0 );
+extern s32 MulShr32( s32 srcval, s32 mulval );
+
+extern StereoOut32 clamp_mix( const StereoOut32& sample, u8 bitshift=0 );
diff --git a/plugins/spu2-x/src/DllInterface.cpp b/plugins/spu2-x/src/PS2E-spu2.cpp
similarity index 63%
rename from plugins/spu2-x/src/DllInterface.cpp
rename to plugins/spu2-x/src/PS2E-spu2.cpp
index 11fce3a26d..ab3f80c959 100644
--- a/plugins/spu2-x/src/DllInterface.cpp
+++ b/plugins/spu2-x/src/PS2E-spu2.cpp
@@ -15,33 +15,40 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
+#include "PS2E-spu2.h"
+#include "dma.h"
#include "Dialogs.h"
#include "RegTable.h"
#ifdef _MSC_VER
-#include "svnrev.h"
-#else
-#include
-#include
+# include "svnrev.h"
#endif
-// [Air]: Adding the spu2init boolean wasn't necessary except to help me in
-// debugging the spu2 suspend/resume behavior (when user hits escape).
-static bool spu2open=false; // has spu2open plugin interface been called?
-static bool spu2init=false; // has spu2init plugin interface been called?
-
-//static s32 logvolume[16384];
-static u32 pClocks=0;
-
-// Pcsx2 expects ASNI, not unicode, so this MUST always be char...
+// PCSX2 expects ASNI, not unicode, so this MUST always be char...
static char libraryName[256];
+
+static bool IsOpened = false;
+static bool IsInitialized = false;
+
+static u32 pClocks = 0;
+
+u32* cyclePtr = NULL;
+u32 lClocks = 0;
+
#ifdef _MSC_VER
-BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD dwReason,LPVOID lpvReserved)
+HINSTANCE hInstance;
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
if( dwReason == DLL_PROCESS_ATTACH )
hInstance = hinstDLL;
+
+ else if( dwReason == DLL_PROCESS_DETACH )
+ {
+ // TODO : perform shutdown procedure, just in case PCSX2 itself failed
+ // to for some reason..
+ }
return TRUE;
}
#endif
@@ -106,7 +113,7 @@ EXPORT_C_(char*) PS2EgetLibName()
EXPORT_C_(u32) PS2EgetLibVersion2(u32 type)
{
- return (VersionInfo::PluginApi<<16) | (VersionInfo::Release<<8) | VersionInfo::Revision;
+ return (PS2E_SPU2_VERSION<<16) | (VersionInfo::Release<<8) | VersionInfo::Revision;
}
EXPORT_C_(void) SPU2configure()
@@ -126,6 +133,87 @@ EXPORT_C_(s32) SPU2test()
return SndBuffer::Test();
}
+// --------------------------------------------------------------------------------------
+// DMA 4/7 Callbacks from Core Emulator
+// --------------------------------------------------------------------------------------
+
+u16* DMABaseAddr;
+void (* _irqcallback)();
+void (* dma4callback)();
+void (* dma7callback)();
+
+EXPORT_C_(u32) CALLBACK SPU2ReadMemAddr(int core)
+{
+ return Cores[core].MADR;
+}
+EXPORT_C_(void) CALLBACK SPU2WriteMemAddr(int core,u32 value)
+{
+ Cores[core].MADR = value;
+}
+
+EXPORT_C_(void) CALLBACK SPU2setDMABaseAddr(uptr baseaddr)
+{
+ DMABaseAddr = (u16*)baseaddr;
+}
+
+EXPORT_C_(void) CALLBACK SPU2readDMA4Mem(u16 *pMem, u32 size) // size now in 16bit units
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 readDMA4Mem size %x\n",Cycles, size<<1);
+ Cores[0].DoDMAread(pMem, size);
+}
+
+EXPORT_C_(void) CALLBACK SPU2writeDMA4Mem(u16* pMem, u32 size) // size now in 16bit units
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 writeDMA4Mem size %x at address %x\n",Cycles, size<<1, Cores[0].TSA);
+#ifdef S2R_ENABLE
+ if(!replay_mode)
+ s2r_writedma4(Cycles,pMem,size);
+#endif
+ Cores[0].DoDMAwrite(pMem,size);
+}
+
+EXPORT_C_(void) CALLBACK SPU2interruptDMA4()
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 interruptDMA4\n",Cycles);
+ Cores[0].Regs.STATX |= 0x80;
+ //Cores[0].Regs.ATTR &= ~0x30;
+}
+
+EXPORT_C_(void) CALLBACK SPU2readDMA7Mem(u16* pMem, u32 size)
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 readDMA7Mem size %x\n",Cycles, size<<1);
+ Cores[1].DoDMAread(pMem,size);
+}
+
+EXPORT_C_(void) CALLBACK SPU2writeDMA7Mem(u16* pMem, u32 size)
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 writeDMA7Mem size %x at address %x\n",Cycles, size<<1, Cores[1].TSA);
+#ifdef S2R_ENABLE
+ if(!replay_mode)
+ s2r_writedma7(Cycles,pMem,size);
+#endif
+ Cores[1].DoDMAwrite(pMem,size);
+}
+
+EXPORT_C_(void) CALLBACK SPU2interruptDMA7()
+{
+ if( cyclePtr != NULL ) TimeUpdate( *cyclePtr );
+
+ FileLog("[%10d] SPU2 interruptDMA7\n",Cycles);
+ Cores[1].Regs.STATX |= 0x80;
+ //Cores[1].Regs.ATTR &= ~0x30;
+}
+
EXPORT_C_(s32) SPU2init()
{
#define MAKESURE(a,b) \
@@ -147,13 +235,13 @@ EXPORT_C_(s32) SPU2init()
#endif
srand((unsigned)time(NULL));
- if (spu2init)
+ if (IsInitialized)
{
ConLog( " * SPU2: Already initialized - Ignoring SPU2init signal." );
return 0;
}
- spu2init=true;
+ IsInitialized = true;
spu2regs = (short*)malloc(0x010000);
_spu2mem = (short*)malloc(0x200000);
@@ -181,8 +269,8 @@ EXPORT_C_(s32) SPU2init()
}
}
- memset(spu2regs,0,0x010000);
- memset(_spu2mem,0,0x200000);
+ memset(spu2regs, 0, 0x010000);
+ memset(_spu2mem, 0, 0x200000);
Cores[0].Reset();
Cores[1].Reset();
@@ -217,7 +305,7 @@ EXPORT_C_(s32) SPU2init()
EXPORT_C_(s32) SPU2open(void *pDsp)
{
- if( spu2open ) return 0;
+ if( IsOpened ) return 0;
FileLog("[%10d] SPU2 Open\n",Cycles);
@@ -229,7 +317,7 @@ EXPORT_C_(s32) SPU2open(void *pDsp)
debugDialogOpen=1;
}*/
- spu2open = true;
+ IsOpened = true;
try
{
SndBuffer::Init();
@@ -247,7 +335,9 @@ EXPORT_C_(s32) SPU2open(void *pDsp)
EXPORT_C_(void) SPU2close()
{
- if( !spu2open ) return;
+ if( !IsOpened ) return;
+ IsOpened = false;
+
FileLog("[%10d] SPU2 Close\n",Cycles);
#ifndef __LINUX__
@@ -255,13 +345,12 @@ EXPORT_C_(void) SPU2close()
#endif
spdif_shutdown();
SndBuffer::Cleanup();
-
- spu2open = false;
}
EXPORT_C_(void) SPU2shutdown()
{
- if(!spu2init) return;
+ if(!IsInitialized) return;
+ IsInitialized = false;
ConLog( " * SPU2: Shutting down.\n" );
@@ -285,12 +374,9 @@ EXPORT_C_(void) SPU2shutdown()
DMALogClose();
- spu2init = false;
-
- SAFE_FREE(spu2regs);
- SAFE_FREE(_spu2mem);
-
- SAFE_FREE( pcm_cache_data );
+ safe_free(spu2regs);
+ safe_free(_spu2mem);
+ safe_free( pcm_cache_data );
spu2regs = NULL;
_spu2mem = NULL;
@@ -312,32 +398,8 @@ bool numpad_plus = false, numpad_plus_old = false;
EXPORT_C_(void) SPU2async(u32 cycles)
{
- if( IsDevBuild )
- {
- u32 oldClocks = lClocks;
- static u32 timer=0,time1=0,time2=0;
- timer++;
- if (timer == 1){
- time1=timeGetTime();
- }
- if (timer == 3000){
- time2 = timeGetTime()-time1 ;
- timer=0;
- }
- }
-
DspUpdate();
- if( IsDevBuild )
- {
- /*numpad_plus = (GetAsyncKeyState(VK_ADD)&0x8000)!=0;
- if(numpad_plus && !numpad_plus_old)
- {
- DoFullDump();
- }
- numpad_plus_old = numpad_plus;*/
- }
-
if(cyclePtr != NULL)
{
TimeUpdate( *cyclePtr );
@@ -366,7 +428,7 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
if(rmem==0x1f9001AC)
{
- ret = DmaRead(core);
+ ret = Cores[core].DmaRead();
}
else
{
@@ -375,7 +437,7 @@ EXPORT_C_(u16) SPU2read(u32 rmem)
if (rmem>>16 == 0x1f80)
{
- ret = SPU_ps1_read(rmem);
+ ret = Cores[0].ReadRegPS1(rmem);
}
else if( (mem&0xFFFF) >= 0x800 )
{
@@ -400,44 +462,19 @@ EXPORT_C_(void) SPU2write(u32 rmem, u16 value)
s2r_writereg(Cycles,rmem,value);
#endif
- if(rmem==0x1f9001ac)
- {
- //RegWriteLog(0,value);
- if((Cores[0].IRQEnable)&&(Cores[0].TSA==Cores[0].IRQA))
- {
- Spdif.Info=4;
- SetIrqCall();
- }
- spu2M_Write( Cores[0].TSA++, value );
- Cores[0].TSA&=0xfffff;
- }
- else if(rmem==0x1f9005ac)
- {
- //RegWriteLog(1,value);
- if((Cores[0].IRQEnable)&&(Cores[0].TSA==Cores[0].IRQA))
- {
- Spdif.Info=4;
- SetIrqCall();
- }
- spu2M_Write( Cores[1].TSA++, value );
- Cores[1].TSA&=0xfffff;
- }
+ // Note: Reverb/Effects are very sensitive to having precise update timings.
+ // If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather
+ // incorrect pitches and loop lengths.
+
+ if( cyclePtr != NULL )
+ TimeUpdate( *cyclePtr );
+
+ if (rmem>>16 == 0x1f80)
+ Cores[0].WriteRegPS1(rmem,value);
else
{
- // Note: Reverb/Effects are very sensitive to having precise update timings.
- // If the SPU2 isn't in in sync with the IOP, samples can end up playing at rather
- // incorrect pitches and loop lengths.
-
- if( cyclePtr != NULL )
- TimeUpdate( *cyclePtr );
-
- if (rmem>>16 == 0x1f80)
- SPU_ps1_write(rmem,value);
- else
- {
- SPU2writeLog( "write", rmem, value );
- SPU2_FastWrite( rmem, value );
- }
+ SPU2writeLog( "write", rmem, value );
+ SPU2_FastWrite( rmem, value );
}
}
@@ -453,3 +490,29 @@ EXPORT_C_(int) SPU2setupRecording(int start, void* pData)
return 0;
}
+
+EXPORT_C_(s32) SPU2freeze(int mode, freezeData *data)
+{
+ if( mode == FREEZE_SIZE )
+ {
+ data->size = Savestate::SizeIt();
+ return 0;
+ }
+
+ jASSUME( mode == FREEZE_LOAD || mode == FREEZE_SAVE );
+ jASSUME( data != NULL );
+
+ if( data->data == NULL ) return -1;
+ Savestate::DataBlock& spud = (Savestate::DataBlock&)*(data->data);
+
+ switch( mode )
+ {
+ case FREEZE_LOAD: return Savestate::ThawIt( spud );
+ case FREEZE_SAVE: return Savestate::FreezeIt( spud );
+
+ jNO_DEFAULT;
+ }
+
+ // technically unreachable, but kills a warning:
+ return 0;
+}
diff --git a/plugins/spu2-x/src/PS2E-spu2.h b/plugins/spu2-x/src/PS2E-spu2.h
new file mode 100644
index 0000000000..b04b7878f2
--- /dev/null
+++ b/plugins/spu2-x/src/PS2E-spu2.h
@@ -0,0 +1,92 @@
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
+
+#pragma once
+
+#include "Pcsx2Defs.h"
+#include "PS2Edefs.h"
+
+#ifdef __LINUX__
+//Until I get around to putting in Linux svn code, this is an unknown svn version.
+#define SVN_REV_UNKNOWN
+#endif
+
+#ifdef _MSC_VER
+#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK
+#else
+#define EXPORT_C_(type) extern "C" type
+#endif
+
+// We have our own versions that have the DLLExport attribute configured:
+
+EXPORT_C_(s32) SPU2init();
+EXPORT_C_(s32) SPU2open(void *pDsp);
+EXPORT_C_(void) SPU2close();
+EXPORT_C_(void) SPU2shutdown();
+EXPORT_C_(void) SPU2write(u32 mem, u16 value);
+EXPORT_C_(u16) SPU2read(u32 mem);
+EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size);
+EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size);
+EXPORT_C_(void) SPU2interruptDMA4();
+EXPORT_C_(void) SPU2readDMA7Mem(u16* pMem, u32 size);
+EXPORT_C_(void) SPU2writeDMA7Mem(u16 *pMem, u32 size);
+
+// all addresses passed by dma will be pointers to the array starting at baseaddr
+// This function is necessary to successfully save and reload the spu2 state
+EXPORT_C_(void) SPU2setDMABaseAddr(uptr baseaddr);
+
+EXPORT_C_(void) SPU2interruptDMA7();
+EXPORT_C_(u32) SPU2ReadMemAddr(int core);
+EXPORT_C_(void) SPU2WriteMemAddr(int core,u32 value);
+EXPORT_C_(void) SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
+
+// extended funcs
+// if start is 1, starts recording spu2 data, else stops
+// returns a non zero value if successful
+// for now, pData is not used
+EXPORT_C_(int) SPU2setupRecording(int start, void* pData);
+
+EXPORT_C_(void) SPU2setClockPtr(u32* ptr);
+
+EXPORT_C_(void) SPU2async(u32 cycles);
+EXPORT_C_(s32) SPU2freeze(int mode, freezeData *data);
+EXPORT_C_(void) SPU2configure();
+EXPORT_C_(void) SPU2about();
+EXPORT_C_(s32) SPU2test();
+
+#include "Spu2replay.h"
+
+extern u8 callirq;
+
+extern void (* _irqcallback)();
+extern void (* dma4callback)();
+extern void (* dma7callback)();
+
+extern double srate_pv;
+
+extern s16 *input_data;
+extern u32 input_data_ptr;
+
+extern int recording;
+extern u32 lClocks;
+extern u32* cyclePtr;
+
+extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
+extern void TimeUpdate(u32 cClocks);
+extern void SPU2_FastWrite( u32 rmem, u16 value );
+
+extern void LowPassFilterInit();
+
+//#define PCM24_S1_INTERLEAVE
diff --git a/plugins/spu2-x/src/PrecompiledHeader.cpp b/plugins/spu2-x/src/PrecompiledHeader.cpp
new file mode 100644
index 0000000000..076b1eb792
--- /dev/null
+++ b/plugins/spu2-x/src/PrecompiledHeader.cpp
@@ -0,0 +1,2 @@
+
+#include "Global.h"
\ No newline at end of file
diff --git a/plugins/spu2-x/src/ReadInput.cpp b/plugins/spu2-x/src/ReadInput.cpp
index b6ab222c86..c63055d8c4 100644
--- a/plugins/spu2-x/src/ReadInput.cpp
+++ b/plugins/spu2-x/src/ReadInput.cpp
@@ -15,172 +15,138 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
+#include "dma.h"
-void __fastcall ReadInput( uint core, StereoOut32& PData )
+// CDDA mode - Source audio data is 32 bits.
+// PS2 note: Very! few PS2 games use this mode. Some PSX games used it, however no
+// *known* PS2 game does since it was likely only available if the game was recorded to CD
+// media (ie, not available in DVD mode, which almost all PS2 games use). Plus PS2 games
+// generally prefer to use ADPCM streaming audio since they need as much storage space as
+// possible for FMVs and high-def textures.
+//
+__forceinline StereoOut32 V_Core::ReadInput_HiFi( bool isCDDA )
{
- V_Core& thiscore( Cores[core] );
+ InputPos &= ~1;
- if((thiscore.AutoDMACtrl&(core+1))==(core+1))
+#ifdef PCM24_S1_INTERLEAVE
+ StereoOut32 retval(
+ *((s32*)(ADMATempBuffer+(InputPos<<1))),
+ *((s32*)(ADMATempBuffer+(InputPos<<1)+2))
+ );
+#else
+ StereoOut32 retval(
+ (s32&)(ADMATempBuffer[InputPos]),
+ (s32&)(ADMATempBuffer[InputPos+0x200])
+ );
+#endif
+
+ if( isCDDA )
{
- s32 tl,tr;
-
- if((core==1)&&((PlayMode&8)==8))
+ //give 30 bit data (SndOut downsamples the rest of the way)
+ retval.Left >>= 2;
+ retval.Right >>= 2;
+ }
+
+ InputPos += 2;
+ //if( (InputPos==0x100) || (InputPos>=0x200) ) // CDDA mode?
+ if( InputPos >= 0x200 )
+ {
+ AdmaInProgress = 0;
+ if(InputDataLeft >= 0x200)
{
- thiscore.InputPos&=~1;
-
- // CDDA mode
- // Source audio data is 32 bits.
- // We don't yet have the capability to handle this high res input data
- // so we just downgrade it to 16 bits for now.
+ u8 k = (InputDataLeft >= InputDataProgress);
#ifdef PCM24_S1_INTERLEAVE
- *PData.Left=*(((s32*)(thiscore.ADMATempBuffer+(thiscore.InputPos<<1))));
- *PData.Right=*(((s32*)(thiscore.ADMATempBuffer+(thiscore.InputPos<<1)+2)));
+ AutoDMAReadBuffer(1);
#else
- s32 *pl=(s32*)&(thiscore.ADMATempBuffer[thiscore.InputPos]);
- s32 *pr=(s32*)&(thiscore.ADMATempBuffer[thiscore.InputPos+0x200]);
- PData.Left = *pl;
- PData.Right = *pr;
+ AutoDMAReadBuffer(0);
#endif
+ AdmaInProgress = 1;
- PData.Left >>= 2; //give 30 bit data (SndOut downsamples the rest of the way)
- PData.Right >>= 2;
+ TSA = (Index<<10) + InputPos;
- thiscore.InputPos+=2;
- if((thiscore.InputPos==0x100)||(thiscore.InputPos>=0x200)) {
- thiscore.AdmaInProgress=0;
- if(thiscore.InputDataLeft>=0x200)
- {
- u8 k=thiscore.InputDataLeft>=thiscore.InputDataProgress;
-
-#ifdef PCM24_S1_INTERLEAVE
- AutoDMAReadBuffer(core,1);
-#else
- AutoDMAReadBuffer(core,0);
-#endif
- thiscore.AdmaInProgress=1;
-
- thiscore.TSA=(core<<10)+thiscore.InputPos;
-
- if (thiscore.InputDataLeft<0x200)
- {
- FileLog("[%10d] AutoDMA%c block end.\n",Cycles, (core==0)?'4':'7');
-
- if( IsDevBuild )
- {
- if(thiscore.InputDataLeft>0)
- {
- if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
- }
- }
- thiscore.InputDataLeft=0;
- thiscore.DMAICounter=1;
- }
- }
- thiscore.InputPos&=0x1ff;
- }
-
- }
- else if((core==0)&&((PlayMode&4)==4))
- {
- thiscore.InputPos&=~1;
-
- s32 *pl=(s32*)&(thiscore.ADMATempBuffer[thiscore.InputPos]);
- s32 *pr=(s32*)&(thiscore.ADMATempBuffer[thiscore.InputPos+0x200]);
- PData.Left = *pl;
- PData.Right = *pr;
-
- thiscore.InputPos+=2;
- if(thiscore.InputPos>=0x200) {
- thiscore.AdmaInProgress=0;
- if(thiscore.InputDataLeft>=0x200)
- {
- u8 k=thiscore.InputDataLeft>=thiscore.InputDataProgress;
-
- AutoDMAReadBuffer(core,0);
-
- thiscore.AdmaInProgress=1;
-
- thiscore.TSA=(core<<10)+thiscore.InputPos;
-
- if (thiscore.InputDataLeft<0x200)
- {
- FileLog("[%10d] Spdif AutoDMA%c block end.\n",Cycles, (core==0)?'4':'7');
-
- if( IsDevBuild )
- {
- if(thiscore.InputDataLeft>0)
- {
- if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
- }
- }
- thiscore.InputDataLeft=0;
- thiscore.DMAICounter=1;
- }
- }
- thiscore.InputPos&=0x1ff;
- }
-
- }
- else
- {
- if((core==1)&&((PlayMode&2)!=0))
+ if (InputDataLeft < 0x200)
{
- tl=0;
- tr=0;
- }
- else
- {
- // Using the temporary buffer because this area gets overwritten by some other code.
- //*PData.Left = (s32)*(s16*)(spu2mem+0x2000+(core<<10)+thiscore.InputPos);
- //*PData.Right = (s32)*(s16*)(spu2mem+0x2200+(core<<10)+thiscore.InputPos);
+ FileLog("[%10d] %s AutoDMA%c block end.\n", isCDDA ? "CDDA" : "SPDIF", Cycles, GetDmaIndexChar());
- tl = (s32)thiscore.ADMATempBuffer[thiscore.InputPos];
- tr = (s32)thiscore.ADMATempBuffer[thiscore.InputPos+0x200];
-
- }
-
- PData.Left = tl;
- PData.Right = tr;
-
- thiscore.InputPos++;
- if((thiscore.InputPos==0x100)||(thiscore.InputPos>=0x200)) {
- thiscore.AdmaInProgress=0;
- if(thiscore.InputDataLeft>=0x200)
+ if( IsDevBuild )
{
- u8 k=thiscore.InputDataLeft>=thiscore.InputDataProgress;
-
- AutoDMAReadBuffer(core,0);
-
- thiscore.AdmaInProgress=1;
-
- thiscore.TSA=(core<<10)+thiscore.InputPos;
-
- if (thiscore.InputDataLeft<0x200)
+ if(InputDataLeft > 0)
{
- thiscore.AutoDMACtrl |= ~3;
-
- if( IsDevBuild )
- {
- FileLog("[%10d] AutoDMA%c block end.\n",Cycles, (core==0)?'4':'7');
- if(thiscore.InputDataLeft>0)
- {
- if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
- }
- }
-
- thiscore.InputDataLeft = 0;
- thiscore.DMAICounter = 1;
+ if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
}
}
- thiscore.InputPos&=0x1ff;
+ InputDataLeft = 0;
+ DMAICounter = 1;
}
}
+ InputPos &= 0x1ff;
+ }
+ return retval;
+}
+
+StereoOut32 V_Core::ReadInput()
+{
+ if((AutoDMACtrl&(Index+1)) != (Index+1))
+ return StereoOut32();
+
+ if( (Index==1) && ((PlayMode&8)==8) )
+ {
+ return ReadInput_HiFi( false );
+ }
+ else if( (Index==0) && ((PlayMode&4)==4) )
+ {
+ return ReadInput_HiFi( true );
}
else
{
- PData.Left = 0;
- PData.Right = 0;
+ StereoOut32 retval;
+
+ if( (Index!=1) || ((PlayMode&2)==0) )
+ {
+ // Using the temporary buffer because this area gets overwritten by some other code.
+ //*PData.Left = (s32)*(s16*)(spu2mem+0x2000+(core<<10)+InputPos);
+ //*PData.Right = (s32)*(s16*)(spu2mem+0x2200+(core<<10)+InputPos);
+
+ retval = StereoOut32(
+ (s32)ADMATempBuffer[InputPos],
+ (s32)ADMATempBuffer[InputPos+0x200]
+ );
+ }
+
+ InputPos++;
+ if( (InputPos==0x100) || (InputPos>=0x200) )
+ {
+ AdmaInProgress = 0;
+ if(InputDataLeft >= 0x200)
+ {
+ u8 k=InputDataLeft>=InputDataProgress;
+
+ AutoDMAReadBuffer(0);
+
+ AdmaInProgress = 1;
+ TSA = (Index<<10) + InputPos;
+
+ if (InputDataLeft < 0x200)
+ {
+ AutoDMACtrl |= ~3;
+
+ if( IsDevBuild )
+ {
+ FileLog("[%10d] AutoDMA%c block end.\n",Cycles, GetDmaIndexChar());
+ if(InputDataLeft>0)
+ {
+ if(MsgAutoDMA()) ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
+ }
+ }
+
+ InputDataLeft = 0;
+ DMAICounter = 1;
+ }
+ }
+ InputPos&=0x1ff;
+ }
+ return retval;
}
}
diff --git a/plugins/spu2-x/src/RegLog.cpp b/plugins/spu2-x/src/RegLog.cpp
index 7c8d58808e..26b24bdafc 100644
--- a/plugins/spu2-x/src/RegLog.cpp
+++ b/plugins/spu2-x/src/RegLog.cpp
@@ -15,7 +15,7 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
#include "RegTable.h"
const char *ParamNames[8]={"VOLL","VOLR","PITCH","ADSR1","ADSR2","ENVX","VOLXL","VOLXR"};
diff --git a/plugins/spu2-x/src/RegTable.cpp b/plugins/spu2-x/src/RegTable.cpp
index 423a9cdad8..9f01381d12 100644
--- a/plugins/spu2-x/src/RegTable.cpp
+++ b/plugins/spu2-x/src/RegTable.cpp
@@ -15,14 +15,13 @@
* along with SPU2-X. If not, see .
*/
-
-#include "Spu2.h"
+#include "Global.h"
#include "RegTable.h"
// This var is used to confirm that our lookup table is "correct"
// If the assertion in DllMain fails, it means the table has too too few entries.
// (it can't have too many because that would generate a compiler error).
-const u16 zero=0;
+const u16 zero = 0;
#define PCORE(c,p) \
U16P(Cores[c].p)
diff --git a/plugins/spu2-x/src/RegTable.h b/plugins/spu2-x/src/RegTable.h
index c531891aef..e9a94ceccc 100644
--- a/plugins/spu2-x/src/RegTable.h
+++ b/plugins/spu2-x/src/RegTable.h
@@ -19,10 +19,10 @@
#ifndef _REGTABLE_H_
#define _REGTABLE_H_
-#define U16P(x) ( (u16*)&(x) )
+#define U16P(x) ( (u16*)&(x) )
// Returns the hiword of a 32 bit integer.
-#define U16P_HI(x) ( ((u16*)&(x))+1 )
+#define U16P_HI(x) ( ((u16*)&(x))+1 )
// Yay! Global namespace pollution 101!
extern const u16 zero;
diff --git a/plugins/spu2-x/src/Reverb.cpp b/plugins/spu2-x/src/Reverb.cpp
index a2d91e2727..194dfaf935 100644
--- a/plugins/spu2-x/src/Reverb.cpp
+++ b/plugins/spu2-x/src/Reverb.cpp
@@ -15,52 +15,56 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
+#include "Lowpass.h"
-static LPF_data lowpass_left( 11000, SampleRate );
-static LPF_data lowpass_right( 11000, SampleRate );
+// Low pass filters: Change these to 32 for a speedup (benchmarks needed to see if
+// the speed gain is worth the quality drop)
-static __forceinline s32 RevbGetIndexer( V_Core& thiscore, s32 offset )
+static LowPassFilter64 lowpass_left( 11000, SampleRate );
+static LowPassFilter64 lowpass_right( 11000, SampleRate );
+
+__forceinline s32 V_Core::RevbGetIndexer( s32 offset )
{
- u32 pos = thiscore.ReverbX + offset;
+ u32 pos = ReverbX + offset;
// 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( pos > thiscore.EffectsEndA )
+ if( pos > EffectsEndA )
{
- //pos = thiscore.EffectsStartA + ((thiscore.ReverbX + offset) % (u32)thiscore.EffectsBufferSize);
- pos -= thiscore.EffectsEndA+1;
- pos += thiscore.EffectsStartA;
+ //pos = EffectsStartA + ((ReverbX + offset) % (u32)EffectsBufferSize);
+ pos -= EffectsEndA+1;
+ pos += EffectsStartA;
}
return pos;
}
-void Reverb_AdvanceBuffer( V_Core& thiscore )
+void V_Core::Reverb_AdvanceBuffer()
{
- if( (Cycles & 1) && (thiscore.EffectsBufferSize > 0) )
+ if( (Cycles & 1) && (EffectsBufferSize > 0) )
{
- //thiscore.ReverbX = RevbGetIndexer( thiscore, 1 );
- thiscore.ReverbX += 1;
+ //ReverbX = RevbGetIndexer( thiscore, 1 );
+ ReverbX += 1;
- if( thiscore.ReverbX >= (u32)thiscore.EffectsBufferSize ) thiscore.ReverbX = 0;
+ if( ReverbX >= (u32)EffectsBufferSize ) ReverbX = 0;
- //thiscore.ReverbX += 1;
- //if(thiscore.ReverbX >= (u32)thiscore.EffectsBufferSize )
- // thiscore.ReverbX %= (u32)thiscore.EffectsBufferSize;
+ //ReverbX += 1;
+ //if(ReverbX >= (u32)EffectsBufferSize )
+ // ReverbX %= (u32)EffectsBufferSize;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
-StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
+StereoOut32 V_Core::DoReverb( const StereoOut32& Input )
{
// Reverb processing occurs at 24khz, so we skip processing every other sample,
// and use the previous calculation for this core instead.
if( (Cycles&1)==0 )
{
- StereoOut32 retval( thiscore.LastEffect );
+ StereoOut32 retval( LastEffect );
// Make sure and pass input through the LPF. The result can be discarded.
// This gives the LPF a better sampling from which to kill offending frequencies.
@@ -68,15 +72,15 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
lowpass_left.sample( Input.Left / 32768.0 );
lowpass_right.sample( Input.Right / 32768.0 );
- //thiscore.LastEffect = Input;
+ //LastEffect = Input;
return retval;
}
else
{
- if( thiscore.RevBuffers.NeedsUpdated )
- thiscore.UpdateEffectsBufferSize();
+ if( RevBuffers.NeedsUpdated )
+ UpdateEffectsBufferSize();
- if( thiscore.EffectsBufferSize <= 0 )
+ if( EffectsBufferSize <= 0 )
{
// StartA is past EndA, so effects are disabled.
//ConLog( " * SPU2: Effects disabled due to leapfrogged EffectsStart." );
@@ -91,54 +95,54 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
// Advance the current reverb buffer pointer, and cache the read/write addresses we'll be
// needing for this session of reverb.
- const u32 src_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_SRC_A0 );
- const u32 src_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_SRC_A1 );
- const u32 src_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_SRC_B0 );
- const u32 src_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_SRC_B1 );
+ const u32 src_a0 = RevbGetIndexer( RevBuffers.IIR_SRC_A0 );
+ const u32 src_a1 = RevbGetIndexer( RevBuffers.IIR_SRC_A1 );
+ const u32 src_b0 = RevbGetIndexer( RevBuffers.IIR_SRC_B0 );
+ const u32 src_b1 = RevbGetIndexer( RevBuffers.IIR_SRC_B1 );
- const u32 dest_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_A0 );
- const u32 dest_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_A1 );
- const u32 dest_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_B0 );
- const u32 dest_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_B1 );
+ const u32 dest_a0 = RevbGetIndexer( RevBuffers.IIR_DEST_A0 );
+ const u32 dest_a1 = RevbGetIndexer( RevBuffers.IIR_DEST_A1 );
+ const u32 dest_b0 = RevbGetIndexer( RevBuffers.IIR_DEST_B0 );
+ const u32 dest_b1 = RevbGetIndexer( RevBuffers.IIR_DEST_B1 );
- const u32 dest2_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_A0 + 1 );
- const u32 dest2_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_A1 + 1 );
- const u32 dest2_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_B0 + 1 );
- const u32 dest2_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.IIR_DEST_B1 + 1 );
+ const u32 dest2_a0 = RevbGetIndexer( RevBuffers.IIR_DEST_A0 + 1 );
+ const u32 dest2_a1 = RevbGetIndexer( RevBuffers.IIR_DEST_A1 + 1 );
+ const u32 dest2_b0 = RevbGetIndexer( RevBuffers.IIR_DEST_B0 + 1 );
+ const u32 dest2_b1 = RevbGetIndexer( RevBuffers.IIR_DEST_B1 + 1 );
- const u32 acc_src_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_A0 );
- const u32 acc_src_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_B0 );
- const u32 acc_src_c0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_C0 );
- const u32 acc_src_d0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_D0 );
+ const u32 acc_src_a0 = RevbGetIndexer( RevBuffers.ACC_SRC_A0 );
+ const u32 acc_src_b0 = RevbGetIndexer( RevBuffers.ACC_SRC_B0 );
+ const u32 acc_src_c0 = RevbGetIndexer( RevBuffers.ACC_SRC_C0 );
+ const u32 acc_src_d0 = RevbGetIndexer( RevBuffers.ACC_SRC_D0 );
- const u32 acc_src_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_A1 );
- const u32 acc_src_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_B1 );
- const u32 acc_src_c1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_C1 );
- const u32 acc_src_d1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.ACC_SRC_D1 );
+ const u32 acc_src_a1 = RevbGetIndexer( RevBuffers.ACC_SRC_A1 );
+ const u32 acc_src_b1 = RevbGetIndexer( RevBuffers.ACC_SRC_B1 );
+ const u32 acc_src_c1 = RevbGetIndexer( RevBuffers.ACC_SRC_C1 );
+ const u32 acc_src_d1 = RevbGetIndexer( RevBuffers.ACC_SRC_D1 );
- const u32 fb_src_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.FB_SRC_A0 );
- const u32 fb_src_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.FB_SRC_A1 );
- const u32 fb_src_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.FB_SRC_B0 );
- const u32 fb_src_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.FB_SRC_B1 );
+ const u32 fb_src_a0 = RevbGetIndexer( RevBuffers.FB_SRC_A0 );
+ const u32 fb_src_a1 = RevbGetIndexer( RevBuffers.FB_SRC_A1 );
+ const u32 fb_src_b0 = RevbGetIndexer( RevBuffers.FB_SRC_B0 );
+ const u32 fb_src_b1 = RevbGetIndexer( RevBuffers.FB_SRC_B1 );
- const u32 mix_dest_a0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.MIX_DEST_A0 );
- const u32 mix_dest_a1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.MIX_DEST_A1 );
- const u32 mix_dest_b0 = RevbGetIndexer( thiscore, thiscore.RevBuffers.MIX_DEST_B0 );
- const u32 mix_dest_b1 = RevbGetIndexer( thiscore, thiscore.RevBuffers.MIX_DEST_B1 );
+ const u32 mix_dest_a0 = RevbGetIndexer( RevBuffers.MIX_DEST_A0 );
+ const u32 mix_dest_a1 = RevbGetIndexer( RevBuffers.MIX_DEST_A1 );
+ const u32 mix_dest_b0 = RevbGetIndexer( RevBuffers.MIX_DEST_B0 );
+ const u32 mix_dest_b1 = RevbGetIndexer( RevBuffers.MIX_DEST_B1 );
// -----------------------------------------
// End Buffer Pointers, Begin Reverb!
// -----------------------------------------
- //StereoOut32 INPUT_SAMPLE( thiscore.LastEffect + Input );
+ //StereoOut32 INPUT_SAMPLE( LastEffect + Input );
// Note: LowPass on the input! Very important. Some games like DDS get terrible feedback otherwise.
// Decisions, Decisions! Should we mix in the 22khz sample skipped, or not?
// First one mixes in the 22hkz sample. Second one does not.
/*StereoOut32 INPUT_SAMPLE(
- (s32)(lowpass_left.sample( (Input.Left+thiscore.LastEffect.Left) / 32768.0 ) * 32768.0),
- (s32)(lowpass_right.sample( (Input.Right+thiscore.LastEffect.Right) / 32768.0 ) * 32768.0)
+ (s32)(lowpass_left.sample( (Input.Left+LastEffect.Left) / 32768.0 ) * 32768.0),
+ (s32)(lowpass_right.sample( (Input.Right+LastEffect.Right) / 32768.0 ) * 32768.0)
);*/
StereoOut32 INPUT_SAMPLE(
@@ -146,15 +150,15 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
(s32)(lowpass_right.sample( Input.Right / 32768.0 ) * 32768.0)
);
- const s32 IIR_INPUT_A0 = ((_spu2mem[src_a0] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Left * thiscore.Revb.IN_COEF_L))>>16;
- const s32 IIR_INPUT_A1 = ((_spu2mem[src_a1] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Right * thiscore.Revb.IN_COEF_R))>>16;
- const s32 IIR_INPUT_B0 = ((_spu2mem[src_b0] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Left * thiscore.Revb.IN_COEF_L))>>16;
- const s32 IIR_INPUT_B1 = ((_spu2mem[src_b1] * thiscore.Revb.IIR_COEF) + (INPUT_SAMPLE.Right * thiscore.Revb.IN_COEF_R))>>16;
+ const s32 IIR_INPUT_A0 = ((_spu2mem[src_a0] * Revb.IIR_COEF) + (INPUT_SAMPLE.Left * Revb.IN_COEF_L))>>16;
+ const s32 IIR_INPUT_A1 = ((_spu2mem[src_a1] * Revb.IIR_COEF) + (INPUT_SAMPLE.Right * Revb.IN_COEF_R))>>16;
+ const s32 IIR_INPUT_B0 = ((_spu2mem[src_b0] * Revb.IIR_COEF) + (INPUT_SAMPLE.Left * Revb.IN_COEF_L))>>16;
+ const s32 IIR_INPUT_B1 = ((_spu2mem[src_b1] * Revb.IIR_COEF) + (INPUT_SAMPLE.Right * Revb.IN_COEF_R))>>16;
- const s32 IIR_A0 = (IIR_INPUT_A0 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_a0] * (0x7fff - thiscore.Revb.IIR_ALPHA));
- const s32 IIR_A1 = (IIR_INPUT_A1 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_a1] * (0x7fff - thiscore.Revb.IIR_ALPHA));
- const s32 IIR_B0 = (IIR_INPUT_B0 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_b0] * (0x7fff - thiscore.Revb.IIR_ALPHA));
- const s32 IIR_B1 = (IIR_INPUT_B1 * thiscore.Revb.IIR_ALPHA) + (_spu2mem[dest_b1] * (0x7fff - thiscore.Revb.IIR_ALPHA));
+ const s32 IIR_A0 = (IIR_INPUT_A0 * Revb.IIR_ALPHA) + (_spu2mem[dest_a0] * (0x7fff - Revb.IIR_ALPHA));
+ const s32 IIR_A1 = (IIR_INPUT_A1 * Revb.IIR_ALPHA) + (_spu2mem[dest_a1] * (0x7fff - Revb.IIR_ALPHA));
+ const s32 IIR_B0 = (IIR_INPUT_B0 * Revb.IIR_ALPHA) + (_spu2mem[dest_b0] * (0x7fff - Revb.IIR_ALPHA));
+ const s32 IIR_B1 = (IIR_INPUT_B1 * Revb.IIR_ALPHA) + (_spu2mem[dest_b1] * (0x7fff - Revb.IIR_ALPHA));
_spu2mem[dest2_a0] = clamp_mix( IIR_A0 >> 16 );
_spu2mem[dest2_a1] = clamp_mix( IIR_A1 >> 16 );
_spu2mem[dest2_b0] = clamp_mix( IIR_B0 >> 16 );
@@ -162,10 +166,10 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
// Faster single-mul approach to interpolation:
// (doesn't work yet -- breaks Digital Devil Saga badly)
- /*const s32 IIR_A0 = IIR_INPUT_A0 + (((_spu2mem[dest_a0]-IIR_INPUT_A0) * thiscore.Revb.IIR_ALPHA)>>16);
- const s32 IIR_A1 = IIR_INPUT_A1 + (((_spu2mem[dest_a1]-IIR_INPUT_A1) * thiscore.Revb.IIR_ALPHA)>>16);
- const s32 IIR_B0 = IIR_INPUT_B0 + (((_spu2mem[dest_b0]-IIR_INPUT_B0) * thiscore.Revb.IIR_ALPHA)>>16);
- const s32 IIR_B1 = IIR_INPUT_B1 + (((_spu2mem[dest_b1]-IIR_INPUT_B1) * thiscore.Revb.IIR_ALPHA)>>16);
+ /*const s32 IIR_A0 = IIR_INPUT_A0 + (((_spu2mem[dest_a0]-IIR_INPUT_A0) * Revb.IIR_ALPHA)>>16);
+ const s32 IIR_A1 = IIR_INPUT_A1 + (((_spu2mem[dest_a1]-IIR_INPUT_A1) * Revb.IIR_ALPHA)>>16);
+ const s32 IIR_B0 = IIR_INPUT_B0 + (((_spu2mem[dest_b0]-IIR_INPUT_B0) * Revb.IIR_ALPHA)>>16);
+ const s32 IIR_B1 = IIR_INPUT_B1 + (((_spu2mem[dest_b1]-IIR_INPUT_B1) * Revb.IIR_ALPHA)>>16);
_spu2mem[dest2_a0] = clamp_mix( IIR_A0 );
_spu2mem[dest2_a1] = clamp_mix( IIR_A1 );
@@ -173,36 +177,36 @@ StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input )
_spu2mem[dest2_b1] = clamp_mix( IIR_B1 );*/
const s32 ACC0 =
- ((_spu2mem[acc_src_a0] * thiscore.Revb.ACC_COEF_A)) +
- ((_spu2mem[acc_src_b0] * thiscore.Revb.ACC_COEF_B)) +
- ((_spu2mem[acc_src_c0] * thiscore.Revb.ACC_COEF_C)) +
- ((_spu2mem[acc_src_d0] * thiscore.Revb.ACC_COEF_D));
+ ((_spu2mem[acc_src_a0] * Revb.ACC_COEF_A)) +
+ ((_spu2mem[acc_src_b0] * Revb.ACC_COEF_B)) +
+ ((_spu2mem[acc_src_c0] * Revb.ACC_COEF_C)) +
+ ((_spu2mem[acc_src_d0] * Revb.ACC_COEF_D));
const s32 ACC1 =
- ((_spu2mem[acc_src_a1] * thiscore.Revb.ACC_COEF_A)) +
- ((_spu2mem[acc_src_b1] * thiscore.Revb.ACC_COEF_B)) +
- ((_spu2mem[acc_src_c1] * thiscore.Revb.ACC_COEF_C)) +
- ((_spu2mem[acc_src_d1] * thiscore.Revb.ACC_COEF_D));
+ ((_spu2mem[acc_src_a1] * Revb.ACC_COEF_A)) +
+ ((_spu2mem[acc_src_b1] * Revb.ACC_COEF_B)) +
+ ((_spu2mem[acc_src_c1] * Revb.ACC_COEF_C)) +
+ ((_spu2mem[acc_src_d1] * Revb.ACC_COEF_D));
- const s32 FB_A0 = (_spu2mem[fb_src_a0] * thiscore.Revb.FB_ALPHA);
- const s32 FB_A1 = (_spu2mem[fb_src_a1] * thiscore.Revb.FB_ALPHA);
+ const s32 FB_A0 = (_spu2mem[fb_src_a0] * Revb.FB_ALPHA);
+ const s32 FB_A1 = (_spu2mem[fb_src_a1] * Revb.FB_ALPHA);
- const s32 fb_xor_a0 = _spu2mem[fb_src_a0] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 );
- const s32 fb_xor_a1 = _spu2mem[fb_src_a1] * ( thiscore.Revb.FB_ALPHA ^ 0x8000 );
+ const s32 fb_xor_a0 = _spu2mem[fb_src_a0] * ( Revb.FB_ALPHA ^ 0x8000 );
+ const s32 fb_xor_a1 = _spu2mem[fb_src_a1] * ( Revb.FB_ALPHA ^ 0x8000 );
_spu2mem[mix_dest_a0] = clamp_mix( (ACC0 - FB_A0) >> 16 );
_spu2mem[mix_dest_a1] = clamp_mix( (ACC1 - FB_A1) >> 16 );
- _spu2mem[mix_dest_b0] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<16, ACC0) - fb_xor_a0 - (_spu2mem[fb_src_b0] * thiscore.Revb.FB_X)) >> 16 );
- _spu2mem[mix_dest_b1] = clamp_mix( (MulShr32(thiscore.Revb.FB_ALPHA<<16, ACC1) - fb_xor_a1 - (_spu2mem[fb_src_b1] * thiscore.Revb.FB_X)) >> 16 );
+ _spu2mem[mix_dest_b0] = clamp_mix( (MulShr32(Revb.FB_ALPHA<<16, ACC0) - fb_xor_a0 - (_spu2mem[fb_src_b0] * Revb.FB_X)) >> 16 );
+ _spu2mem[mix_dest_b1] = clamp_mix( (MulShr32(Revb.FB_ALPHA<<16, ACC1) - fb_xor_a1 - (_spu2mem[fb_src_b1] * Revb.FB_X)) >> 16 );
- thiscore.LastEffect.Left = _spu2mem[mix_dest_a0] + _spu2mem[mix_dest_b0];
- thiscore.LastEffect.Right = _spu2mem[mix_dest_a1] + _spu2mem[mix_dest_b1];
+ LastEffect.Left = _spu2mem[mix_dest_a0] + _spu2mem[mix_dest_b0];
+ LastEffect.Right = _spu2mem[mix_dest_a1] + _spu2mem[mix_dest_b1];
- clamp_mix( thiscore.LastEffect );
+ clamp_mix( LastEffect );
- //thiscore.LastEffect.Left = (s32)(lowpass_left.sample( thiscore.LastEffect.Left / 32768.0 ) * 32768.0);
- //thiscore.LastEffect.Right = (s32)(lowpass_right.sample( thiscore.LastEffect.Right / 32768.0 ) * 32768.0);
+ //LastEffect.Left = (s32)(lowpass_left.sample( LastEffect.Left / 32768.0 ) * 32768.0);
+ //LastEffect.Right = (s32)(lowpass_right.sample( LastEffect.Right / 32768.0 ) * 32768.0);
- return thiscore.LastEffect;
+ return LastEffect;
}
}
diff --git a/plugins/spu2-x/src/SaveStateSPU.cpp b/plugins/spu2-x/src/SaveStateSPU.cpp
deleted file mode 100644
index 5b19f5b59b..0000000000
--- a/plugins/spu2-x/src/SaveStateSPU.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
- * Developed and maintained by the Pcsx2 Development Team.
- *
- * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
- *
- * SPU2-X is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with SPU2-X. If not, see .
- */
-
-#include "Spu2.h"
-
-namespace Savestate {
-
-struct SPU2freezeData
-{
- u32 version;
- u8 unkregs[0x10000];
- u8 mem[0x200000];
-
- u32 id;
- V_Core Cores[2];
- V_SPDIF Spdif;
- s16 OutPos;
- s16 InputPos;
- u32 Cycles;
- u32 lClocks;
- int PlayMode;
-
- // Used as a base pointer to a series PcmCache blocks.
- PcmCacheEntry cacheData;
-};
-
-// Arbitrary ID to identify SPU2-X saves.
-static const u32 SAVE_ID = 0x1227521;
-
-// versioning for saves.
-// Increment this when changes to the savestate system are made.
-
-static const u32 SAVE_VERSION = 0x0005;
-
-static void wipe_the_cache()
-{
- memset( pcm_cache_data, 0, pcm_BlockCount * sizeof(PcmCacheEntry) );
-}
-
-
-static s16 old_state_sBuffer[pcm_DecodedSamplesPerBlock] = {0};
-
-typedef s32 __fastcall FreezeHandlerFunction( SPU2freezeData& data );
-
-s32 __fastcall FreezeIt( SPU2freezeData& spud )
-{
- spud.id = SAVE_ID;
- spud.version = SAVE_VERSION;
-
- memcpy(spud.unkregs, spu2regs, 0x010000);
- memcpy(spud.mem, _spu2mem, 0x200000);
- memcpy(spud.Cores, Cores, sizeof(Cores));
- memcpy(&spud.Spdif, &Spdif, sizeof(Spdif));
- spud.OutPos = OutPos;
- spud.InputPos = InputPos;
- spud.Cycles = Cycles;
- spud.lClocks = lClocks;
- spud.PlayMode = PlayMode;
-
- // Save our cache:
- // We could just force the user to rebuild the cache when loading
- // from stavestates, but for most games the cache is pretty
- // small and compresses well.
- //
- // Potential Alternative:
- // If the cache is not saved then it is necessary to save the
- // decoded blocks currently in use by active voices. This allows
- // voices to resume seamlessly on load.
-
- PcmCacheEntry* pcmDst = &spud.cacheData;
- int blksSaved=0;
-
- for( int bidx=0; bidx FreezeSave > Saved %d cache blocks.\n", blksSaved++ );
-
- return 0;
-}
-
-s32 __fastcall ThawIt( SPU2freezeData& spud )
-{
- if( spud.id != SAVE_ID || spud.version < SAVE_VERSION )
- {
- printf("\n*** SPU2-X Warning:\n");
- if( spud.id == SAVE_ID )
- printf("\tSavestate version is from an older version of this plugin.\n");
- else
- printf("\tThe savestate you are trying to load was not made with this plugin.\n");
-
- printf("\tAudio may not recover correctly. Save your game to memorycard, reset,\n\n");
- printf(" and then continue from there.\n\n");
-
- // Do *not* reset the cores.
- // We'll need some "hints" as to how the cores should be initialized,
- // and the only way to get that is to use the game's existing core settings
- // and hope they kinda match the settings for the savestate (IRQ enables and such).
- //
-
- //CoreReset( 0 );
- //CoreReset( 1 );
-
- // adpcm cache : Clear all the cache flags and buffers.
-
- wipe_the_cache();
- }
- else
- {
- // base stuff
- memcpy(spu2regs, spud.unkregs, 0x010000);
- memcpy(_spu2mem, spud.mem, 0x200000);
-
- memcpy(Cores, spud.Cores, sizeof(Cores));
- memcpy(&Spdif, &spud.Spdif, sizeof(Spdif));
- OutPos = spud.OutPos;
- InputPos = spud.InputPos;
- Cycles = spud.Cycles;
- lClocks = spud.lClocks;
- PlayMode = spud.PlayMode;
-
- // Load the ADPCM cache:
-
- wipe_the_cache();
-
- const PcmCacheEntry* pcmSrc = &spud.cacheData;
- int blksLoaded=0;
-
- for( int bidx=0; bidxsize = SizeIt();
- return 0;
- }
-
- jASSUME( mode == FREEZE_LOAD || mode == FREEZE_SAVE );
- jASSUME( data != NULL );
-
- if( data->data == NULL ) return -1;
- SPU2freezeData& spud = (SPU2freezeData&)*(data->data);
-
- switch( mode )
- {
- case FREEZE_LOAD: return ThawIt( spud );
- case FREEZE_SAVE: return FreezeIt( spud );
-
- jNO_DEFAULT;
- }
-
- // technically unreachable, but kills a warning:
- return 0;
-}
diff --git a/plugins/spu2-x/src/SndOut.cpp b/plugins/spu2-x/src/SndOut.cpp
index 29588ccf43..f022f212da 100644
--- a/plugins/spu2-x/src/SndOut.cpp
+++ b/plugins/spu2-x/src/SndOut.cpp
@@ -15,7 +15,7 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+#include "Global.h"
StereoOut32 StereoOut32::Empty( 0, 0 );
@@ -56,11 +56,7 @@ public:
s32 Init() { return 0; }
void Close() { }
s32 Test() const { return 0; }
-#ifdef _MSC_VER
- void Configure(HWND parent) { }
-#else
void Configure(uptr parent) { }
-#endif
bool Is51Out() const { return false; }
int GetEmptySampleCount() const { return 0; }
@@ -290,9 +286,9 @@ void SndBuffer::Cleanup()
{
mods[OutputModule]->Close();
- SAFE_DELETE_ARRAY( m_buffer );
- SAFE_DELETE_ARRAY( sndTempBuffer );
- SAFE_DELETE_ARRAY( sndTempBuffer16 );
+ safe_delete_array( m_buffer );
+ safe_delete_array( sndTempBuffer );
+ safe_delete_array( sndTempBuffer16 );
}
int SndBuffer::m_dsp_progress = 0;
@@ -375,15 +371,3 @@ s32 SndBuffer::Test()
return mods[OutputModule]->Test();
}
-
-#ifdef _MSC_VER
-void SndBuffer::Configure(HWND parent, u32 module )
-#else
-void SndBuffer::Configure(uptr parent, u32 module )
-#endif
-{
- if( mods[module] == NULL )
- return;
-
- mods[module]->Configure(parent);
-}
diff --git a/plugins/spu2-x/src/SndOut.h b/plugins/spu2-x/src/SndOut.h
index 9014323ef5..bf250ed71e 100644
--- a/plugins/spu2-x/src/SndOut.h
+++ b/plugins/spu2-x/src/SndOut.h
@@ -1,25 +1,21 @@
-//GiGaHeRz's SPU2 Driver
-//Copyright (c) 2003-2008, David Quintana
-//
-//This library is free software; you can redistribute it and/or
-//modify it under the terms of the GNU Lesser General Public
-//License as published by the Free Software Foundation; either
-//version 2.1 of the License, or (at your option) any later version.
-//
-//This library is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-//Lesser General Public License for more details.
-//
-//You should have received a copy of the GNU Lesser General Public
-//License along with this library; if not, write to the Free Software
-//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#ifndef SNDOUT_H_INCLUDE
-#define SNDOUT_H_INCLUDE
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
-#include "BaseTypes.h"
-#include "Lowpass.h"
+#pragma once
// Number of stereo samples per SndOut block.
// All drivers must work in units of this size when communicating with
@@ -35,7 +31,7 @@ static const int SndOutVolumeShift = 13;
// is too problematic. :)
static const int SampleRate = 48000;
-int FindOutputModuleById( const wchar_t* omodid );
+extern int FindOutputModuleById( const wchar_t* omodid );
struct StereoOut16
{
@@ -231,9 +227,9 @@ struct Stereo51Out16DplII
s32 Tfl=(RAccum)*255/(LAccum);
s32 Tfr=(LAccum)*255/(RAccum);
- int gMax = max(Tfl,Tfr);
- Tfl=Tfl*255/gMax;
- Tfr=Tfr*255/gMax;
+ int gMax = std::max(Tfl,Tfr);
+ Tfl = Tfl*255/gMax;
+ Tfr = Tfr*255/gMax;
if(Tfl>255) Tfl=255;
if(Tfr>255) Tfr=255;
@@ -393,12 +389,6 @@ public:
static s32 Test();
static void ClearContents();
-#ifdef _MSC_VER
- static void Configure(HWND parent, u32 module );
-#else
- static void Configure(uptr parent, u32 module );
-#endif
-
// Note: When using with 32 bit output buffers, the user of this function is responsible
// for shifting the values to where they need to be manually. The fixed point depth of
// the sample output is determined by the SndOutVolumeShift, which is the number of bits
@@ -474,11 +464,7 @@ public:
virtual s32 Test() const=0;
// Gui function: Used to open the configuration box for this driver.
-#ifdef _MSC_VER
- virtual void Configure(HWND parent)=0;
-#else
virtual void Configure(uptr parent)=0;
-#endif
// Loads settings from the INI file for this driver
virtual void ReadSettings()=0;
@@ -503,4 +489,13 @@ extern SndOutModule* XAudio2Out;
extern SndOutModule* mods[];
-#endif // SNDOUT_H_INCLUDE
+// =====================================================================================================
+
+extern void RecordStart();
+extern void RecordStop();
+extern void RecordWrite( const StereoOut16& sample );
+
+extern s32 DspLoadLibrary(wchar_t *fileName, int modNum);
+extern void DspCloseLibrary();
+extern int DspProcess(s16 *buffer, int samples);
+extern void DspUpdate(); // to let the Dsp process window messages
diff --git a/plugins/spu2-x/src/Spu2.h b/plugins/spu2-x/src/Spu2.h
deleted file mode 100644
index b3432b7695..0000000000
--- a/plugins/spu2-x/src/Spu2.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
- * Developed and maintained by the Pcsx2 Development Team.
- *
- * SPU2-X is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with SPU2-X. If not, see .
- */
-
-#pragma once
-
-#include "BaseTypes.h"
-#include "Pcsx2Defs.h"
-
-#include "Utilities/Exceptions.h"
-
-#ifdef __LINUX__
-#include
-#include
-
-//Until I get around to putting in Linux svn code, this is an unknown svn version.
-#define SVN_REV_UNKNOWN
-#endif
-
-#include "ConvertUTF.h"
-
-namespace VersionInfo
-{
- static const u8 PluginApi = PS2E_SPU2_VERSION;
- static const u8 Release = 1;
- static const u8 Revision = 2; // increase that with each version
-}
-
-#ifdef _MSC_VER
-#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK
-#else
-#define EXPORT_C_(type) extern "C" type
-#endif
-
-// We have our own versions that have the DLLExport attribute configured:
-
-EXPORT_C_(s32) SPU2init();
-EXPORT_C_(s32) SPU2open(void *pDsp);
-EXPORT_C_(void) SPU2close();
-EXPORT_C_(void) SPU2shutdown();
-EXPORT_C_(void) SPU2write(u32 mem, u16 value);
-EXPORT_C_(u16) SPU2read(u32 mem);
-EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size);
-EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size);
-EXPORT_C_(void) SPU2interruptDMA4();
-EXPORT_C_(void) SPU2readDMA7Mem(u16* pMem, u32 size);
-EXPORT_C_(void) SPU2writeDMA7Mem(u16 *pMem, u32 size);
-
-// all addresses passed by dma will be pointers to the array starting at baseaddr
-// This function is necessary to successfully save and reload the spu2 state
-EXPORT_C_(void) SPU2setDMABaseAddr(uptr baseaddr);
-
-EXPORT_C_(void) SPU2interruptDMA7();
-EXPORT_C_(u32) SPU2ReadMemAddr(int core);
-EXPORT_C_(void) SPU2WriteMemAddr(int core,u32 value);
-EXPORT_C_(void) SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
-
-// extended funcs
-// if start is 1, starts recording spu2 data, else stops
-// returns a non zero value if successful
-// for now, pData is not used
-EXPORT_C_(int) SPU2setupRecording(int start, void* pData);
-
-EXPORT_C_(void) SPU2setClockPtr(u32* ptr);
-
-EXPORT_C_(void) SPU2async(u32 cycles);
-EXPORT_C_(s32) SPU2freeze(int mode, freezeData *data);
-EXPORT_C_(void) SPU2configure();
-EXPORT_C_(void) SPU2about();
-EXPORT_C_(s32) SPU2test();
-
-
-//#define EFFECTS_DUMP
-
-//Plugin parts
-#include "Config.h"
-#include "defs.h"
-#include "regs.h"
-#include "Dma.h"
-#include "SndOut.h"
-
-#include "Spu2replay.h"
-
-#ifdef SPU2X_DEVBUILD
-#define SPU2_LOG
-#endif
-
-#include "Debug.h"
-
-//--------------------------------------------------------------------------------------
-// Helper macros
-//--------------------------------------------------------------------------------------
-#ifndef SAFE_FREE
-# define SAFE_FREE(p) { if(p) { free(p); (p)=NULL; } }
-#endif
-#ifndef SAFE_DELETE_ARRAY
-# define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
-#endif
-#ifndef SAFE_DELETE_OBJ
-# define SAFE_DELETE_OBJ(p) { if(p) { delete (p); (p)=NULL; } }
-#endif
-#ifndef SAFE_RELEASE
-# define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
-#endif
-
-// The SPU2 has a dynamic memory range which is used for several internal operations, such as
-// registers, CORE 1/2 mixing, AutoDMAs, and some other fancy stuff. We exclude this range
-// from the cache here:
-static const s32 SPU2_DYN_MEMLINE = 0x2800;
-
-// 8 short words per encoded PCM block. (as stored in SPU2 ram)
-static const int pcm_WordsPerBlock = 8;
-
-// number of cachable ADPCM blocks (any blocks above the SPU2_DYN_MEMLINE)
-static const int pcm_BlockCount = 0x100000 / pcm_WordsPerBlock;
-
-// 28 samples per decoded PCM block (as stored in our cache)
-static const int pcm_DecodedSamplesPerBlock = 28;
-
-struct PcmCacheEntry
-{
- bool Validated;
- s16 Sampledata[pcm_DecodedSamplesPerBlock];
-};
-
-extern void spdif_set51(u32 is_5_1_out);
-extern u32 spdif_init();
-extern void spdif_shutdown();
-extern void spdif_get_samples(s32 *samples); // fills the buffer with [l,r,c,lfe,sl,sr] if using 5.1 output, or [l,r] if using stereo
-
-extern short *spu2regs;
-extern short *_spu2mem;
-
-extern PcmCacheEntry* pcm_cache_data;
-
-extern s16* __fastcall GetMemPtr(u32 addr);
-extern s16 __fastcall spu2M_Read( u32 addr );
-extern void __fastcall spu2M_Write( u32 addr, s16 value );
-extern void __fastcall spu2M_Write( u32 addr, u16 value );
-
-#define spu2Rs16(mmem) (*(s16 *)((s8 *)spu2regs + ((mmem) & 0x1fff)))
-#define spu2Ru16(mmem) (*(u16 *)((s8 *)spu2regs + ((mmem) & 0x1fff)))
-
-extern u8 callirq;
-
-extern void (* _irqcallback)();
-extern void (* dma4callback)();
-extern void (* dma7callback)();
-
-extern void SetIrqCall();
-
-extern double srate_pv;
-
-extern s16 *input_data;
-extern u32 input_data_ptr;
-
-extern int PlayMode;
-extern int recording;
-
-extern u32 lClocks;
-extern u32* cyclePtr;
-
-extern void SPU2writeLog( const char* action, u32 rmem, u16 value );
-
-extern void TimeUpdate(u32 cClocks);
-extern u16 SPU_ps1_read(u32 mem);
-extern void SPU_ps1_write(u32 mem, u16 value);
-extern void SPU2_FastWrite( u32 rmem, u16 value );
-
-extern void StartVoices(int core, u32 value);
-extern void StopVoices(int core, u32 value);
-
-extern s32 DspLoadLibrary(wchar_t *fileName, int modNum);
-extern void DspCloseLibrary();
-extern int DspProcess(s16 *buffer, int samples);
-extern void DspUpdate(); // to let the Dsp process window messages
-
-extern void RecordStart();
-extern void RecordStop();
-extern void RecordWrite( const StereoOut16& sample );
-
-extern void UpdateSpdifMode();
-extern void LowPassFilterInit();
-extern void InitADSR();
-extern void CalculateADSR( V_Voice& vc );
-
-extern void __fastcall ReadInput( uint core, StereoOut32& PData );
-
-
-//////////////////////////////
-// The Mixer Section //
-//////////////////////////////
-
-extern void Mix();
-extern s32 clamp_mix( s32 x, u8 bitshift=0 );
-extern StereoOut32 clamp_mix( const StereoOut32& sample, u8 bitshift=0 );
-extern void Reverb_AdvanceBuffer( V_Core& thiscore );
-extern StereoOut32 DoReverb( V_Core& thiscore, const StereoOut32& Input );
-extern s32 MulShr32( s32 srcval, s32 mulval );
-
-//#define PCM24_S1_INTERLEAVE
diff --git a/plugins/spu2-x/src/Spu2replay.cpp b/plugins/spu2-x/src/Spu2replay.cpp
index 1809de3763..acce80dd0a 100644
--- a/plugins/spu2-x/src/Spu2replay.cpp
+++ b/plugins/spu2-x/src/Spu2replay.cpp
@@ -16,9 +16,8 @@
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-#include
-
-#include "Spu2.h"
+#include "Global.h"
+#include "PS2E-spu2.h"
FILE* s2rfile;
@@ -115,6 +114,7 @@ void dummy7()
#define Cread(a,b,c,d) if(fread(a,b,c,d).
*/
-#include "Spu2.h"
+#include "Global.h"
#include "SoundTouch/SoundTouch.h"
#include "SoundTouch/WavFile.h"
@@ -304,9 +304,7 @@ void SndBuffer::soundtouchInit()
pSoundTouch->setSetting( SETTING_USE_QUICKSEEK, 0 );
pSoundTouch->setSetting( SETTING_USE_AA_FILTER, 0 );
- pSoundTouch->setSetting( SETTING_SEQUENCE_MS, SoundtouchCfg::SequenceLenMS );
- pSoundTouch->setSetting( SETTING_SEEKWINDOW_MS, SoundtouchCfg::SeekWindowMS );
- pSoundTouch->setSetting( SETTING_OVERLAP_MS, SoundtouchCfg::OverlapMS );
+ SoundtouchCfg::ApplySettings( *pSoundTouch );
pSoundTouch->setTempo(1);
@@ -340,5 +338,5 @@ void SndBuffer::soundtouchClearContents()
void SndBuffer::soundtouchCleanup()
{
- SAFE_DELETE_OBJ( pSoundTouch );
+ safe_delete( pSoundTouch );
}
diff --git a/plugins/spu2-x/src/Wavedump_wav.cpp b/plugins/spu2-x/src/Wavedump_wav.cpp
index bc09a67b51..62f48100af 100644
--- a/plugins/spu2-x/src/Wavedump_wav.cpp
+++ b/plugins/spu2-x/src/Wavedump_wav.cpp
@@ -15,11 +15,7 @@
* along with SPU2-X. If not, see .
*/
-#include
-#include
-
-#include "Spu2.h"
-
+#include "Global.h"
#include "SoundTouch/WavFile.h"
static WavOutFile* _new_WavOutFile( const char* destfile )
@@ -52,7 +48,7 @@ namespace WaveDump
{
for( int srcidx=0; srcidx.
*/
+#include "Global.h"
#include "Dialogs.h"
-#include
#include "svnrev.h"
#include "Hyperlinks.h"
diff --git a/plugins/spu2-x/src/Windows/CfgHelpers.cpp b/plugins/spu2-x/src/Windows/CfgHelpers.cpp
index b0b48b7a91..4969db6ac1 100644
--- a/plugins/spu2-x/src/Windows/CfgHelpers.cpp
+++ b/plugins/spu2-x/src/Windows/CfgHelpers.cpp
@@ -15,8 +15,22 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
#include "Dialogs.h"
+void SysMessage(const char *fmt, ...)
+{
+ va_list list;
+ char tmp[512];
+ wchar_t wtmp[512];
+
+ va_start(list,fmt);
+ sprintf_s(tmp,fmt,list);
+ va_end(list);
+ swprintf_s(wtmp, L"%S", tmp);
+ MessageBox(0, wtmp, L"SPU2-X System Message", 0);
+}
+
//////
const TCHAR CfgFile[] = L"inis\\SPU2-X.ini";
diff --git a/plugins/spu2-x/src/Windows/Config.cpp b/plugins/spu2-x/src/Windows/Config.cpp
index b1dc43f96c..576a2bb5b6 100644
--- a/plugins/spu2-x/src/Windows/Config.cpp
+++ b/plugins/spu2-x/src/Windows/Config.cpp
@@ -15,9 +15,10 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
#include "Dialogs.h"
-#ifdef SPU2X_DEVBUILD
+#ifdef PCSX2_DEVBUILD
static const int LATENCY_MAX = 3000;
#else
static const int LATENCY_MAX = 750;
@@ -25,8 +26,6 @@ static const int LATENCY_MAX = 750;
static const int LATENCY_MIN = 40;
-int AutoDMAPlayRate[2] = {0,0};
-
// MIXING
int Interpolation = 1;
/* values:
@@ -57,9 +56,6 @@ bool StereoExpansionEnabled = false;
void ReadSettings()
{
- AutoDMAPlayRate[0] = CfgReadInt(L"MIXING",L"AutoDMA_Play_Rate_0",0);
- AutoDMAPlayRate[1] = CfgReadInt(L"MIXING",L"AutoDMA_Play_Rate_1",0);
-
Interpolation = CfgReadInt( L"MIXING",L"Interpolation", 1 );
timeStretchDisabled = CfgReadBool( L"OUTPUT", L"Disable_Timestretch", false );
@@ -107,9 +103,6 @@ void WriteSettings()
{
CfgWriteInt(L"MIXING",L"Interpolation",Interpolation);
- CfgWriteInt(L"MIXING",L"AutoDMA_Play_Rate_0",AutoDMAPlayRate[0]);
- CfgWriteInt(L"MIXING",L"AutoDMA_Play_Rate_1",AutoDMAPlayRate[1]);
-
CfgWriteBool(L"MIXING",L"Disable_Effects",EffectsDisabled);
CfgWriteStr(L"OUTPUT",L"Output_Module", mods[OutputModule]->GetIdent() );
@@ -204,9 +197,11 @@ BOOL CALLBACK ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
break;
case IDC_OUTCONF:
- SndBuffer::Configure( hWnd,
- (int)SendMessage(GetDlgItem(hWnd,IDC_OUTPUT),CB_GETCURSEL,0,0)
- );
+ {
+ const int module = (int)SendMessage(GetDlgItem(hWnd,IDC_OUTPUT),CB_GETCURSEL,0,0);
+ if( mods[module] == NULL ) break;
+ mods[module]->Configure((uptr)hWnd);
+ }
break;
case IDC_OPEN_CONFIG_DEBUG:
diff --git a/plugins/spu2-x/src/Windows/Config.h b/plugins/spu2-x/src/Windows/Config.h
deleted file mode 100644
index 031b287f0c..0000000000
--- a/plugins/spu2-x/src/Windows/Config.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
- * Developed and maintained by the Pcsx2 Development Team.
- *
- * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
- *
- * SPU2-X is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with SPU2-X. If not, see .
- */
-
-#pragma once
-
-#include
-
-extern bool DebugEnabled;
-
-extern bool _MsgToConsole;
-extern bool _MsgKeyOnOff;
-extern bool _MsgVoiceOff;
-extern bool _MsgDMA;
-extern bool _MsgAutoDMA;
-extern bool _MsgOverruns;
-extern bool _MsgCache;
-
-extern bool _AccessLog;
-extern bool _DMALog;
-extern bool _WaveLog;
-
-extern bool _CoresDump;
-extern bool _MemDump;
-extern bool _RegDump;
-
-static __forceinline bool MsgToConsole() { return _MsgToConsole & DebugEnabled; }
-
-static __forceinline bool MsgKeyOnOff() { return _MsgKeyOnOff & MsgToConsole(); }
-static __forceinline bool MsgVoiceOff() { return _MsgVoiceOff & MsgToConsole(); }
-static __forceinline bool MsgDMA() { return _MsgDMA & MsgToConsole(); }
-static __forceinline bool MsgAutoDMA() { return _MsgAutoDMA & MsgDMA(); }
-static __forceinline bool MsgOverruns() { return _MsgOverruns & MsgToConsole(); }
-static __forceinline bool MsgCache() { return _MsgCache & MsgToConsole(); }
-
-static __forceinline bool AccessLog() { return _AccessLog & DebugEnabled; }
-static __forceinline bool DMALog() { return _DMALog & DebugEnabled; }
-static __forceinline bool WaveLog() { return _WaveLog & DebugEnabled; }
-
-static __forceinline bool CoresDump() { return _CoresDump & DebugEnabled; }
-static __forceinline bool MemDump() { return _MemDump & DebugEnabled; }
-static __forceinline bool RegDump() { return _RegDump & DebugEnabled; }
-
-
-extern wchar_t AccessLogFileName[255];
-extern wchar_t WaveLogFileName[255];
-extern wchar_t DMA4LogFileName[255];
-extern wchar_t DMA7LogFileName[255];
-extern wchar_t CoresDumpFileName[255];
-extern wchar_t MemDumpFileName[255];
-extern wchar_t RegDumpFileName[255];
-
-extern int Interpolation;
-
-extern bool EffectsDisabled;
-
-extern int AutoDMAPlayRate[2];
-
-extern u32 OutputModule;
-extern int SndOutLatencyMS;
-
-extern wchar_t dspPlugin[];
-extern int dspPluginModule;
-
-extern bool dspPluginEnabled;
-extern bool timeStretchDisabled;
-extern bool StereoExpansionEnabled;
-
-class SoundtouchCfg
-{
- // Timestretch Slider Bounds, Min/Max
- static const int SequenceLen_Min = 30;
- static const int SequenceLen_Max = 90;
-
- static const int SeekWindow_Min = 10;
- static const int SeekWindow_Max = 32;
-
- static const int Overlap_Min = 3;
- static const int Overlap_Max = 15;
-
-public:
- static int SequenceLenMS;
- static int SeekWindowMS;
- static int OverlapMS;
-
- static void ReadSettings();
- static void WriteSettings();
- static void OpenDialog( HWND hWnd );
-
-protected:
- static void ClampValues();
- static BOOL CALLBACK DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
-
-};
-
-
-// *** BEGIN DRIVER-SPECIFIC CONFIGURATION ***
-// -------------------------------------------
-
-// DSOUND
-struct CONFIG_XAUDIO2
-{
- std::wstring Device;
- s8 NumBuffers;
-
- CONFIG_XAUDIO2() :
- Device(),
- NumBuffers( 2 )
- {
- }
-};
-
-// WAVEOUT
-struct CONFIG_WAVEOUT
-{
- std::wstring Device;
- s8 NumBuffers;
-
- CONFIG_WAVEOUT() :
- Device(),
- NumBuffers( 4 )
- {
- }
-};
-
-extern CONFIG_WAVEOUT Config_WaveOut;
-extern CONFIG_XAUDIO2 Config_XAudio2;
-
-//////
-
-void ReadSettings();
-void WriteSettings();
-void configure();
-void AboutBox();
diff --git a/plugins/spu2-x/src/Windows/ConfigDebug.cpp b/plugins/spu2-x/src/Windows/ConfigDebug.cpp
index 0373c225c4..ef38cd54e4 100644
--- a/plugins/spu2-x/src/Windows/ConfigDebug.cpp
+++ b/plugins/spu2-x/src/Windows/ConfigDebug.cpp
@@ -15,6 +15,7 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
#include "Dialogs.h"
diff --git a/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp b/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp
index 781ef22002..864947eba3 100644
--- a/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp
+++ b/plugins/spu2-x/src/Windows/ConfigSoundtouch.cpp
@@ -15,13 +15,33 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
#include "Dialogs.h"
-int SoundtouchCfg::SequenceLenMS = 63;
-int SoundtouchCfg::SeekWindowMS = 16;
-int SoundtouchCfg::OverlapMS = 7;
+#include "SoundTouch/SoundTouch.h"
-void SoundtouchCfg::ClampValues()
+static int SequenceLenMS = 63;
+static int SeekWindowMS = 16;
+static int OverlapMS = 7;
+
+// Timestretch Slider Bounds, Min/Max
+static const int SequenceLen_Min = 30;
+static const int SequenceLen_Max = 90;
+
+static const int SeekWindow_Min = 10;
+static const int SeekWindow_Max = 32;
+
+static const int Overlap_Min = 3;
+static const int Overlap_Max = 15;
+
+void SoundtouchCfg::ApplySettings( soundtouch::SoundTouch& sndtouch )
+{
+ sndtouch.setSetting( SETTING_SEQUENCE_MS, SequenceLenMS );
+ sndtouch.setSetting( SETTING_SEEKWINDOW_MS, SeekWindowMS );
+ sndtouch.setSetting( SETTING_OVERLAP_MS, OverlapMS );
+}
+
+static void ClampValues()
{
Clampify( SequenceLenMS, SequenceLen_Min, SequenceLen_Max );
Clampify( SeekWindowMS, SeekWindow_Min, SeekWindow_Max );
@@ -101,7 +121,7 @@ void SoundtouchCfg::OpenDialog( HWND hWnd )
ret = DialogBox( hInstance, MAKEINTRESOURCE(IDD_CONFIG_SOUNDTOUCH), hWnd, (DLGPROC)DialogProc );
if(ret==-1)
{
- MessageBoxEx(GetActiveWindow(),L"Error Opening the Soundtouch advanced dialog.",L"OMG ERROR!",MB_OK,0);
+ MessageBoxEx(GetActiveWindow(), L"Error Opening the Soundtouch advanced dialog.", L"OMG ERROR!", MB_OK, 0);
return;
}
ReadSettings();
diff --git a/plugins/spu2-x/src/Windows/Dialogs.h b/plugins/spu2-x/src/Windows/Dialogs.h
index 72065d4d03..0568591da7 100644
--- a/plugins/spu2-x/src/Windows/Dialogs.h
+++ b/plugins/spu2-x/src/Windows/Dialogs.h
@@ -17,30 +17,11 @@
#pragma once
-#ifndef _DIALOGS_H_
-#define _DIALOGS_H_
-
-#include "../Spu2.h"
-
-#include
-#include
-
-extern HINSTANCE hInstance;
-
-#define SET_CHECK(idc,value) SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,((value)==0)?BST_UNCHECKED:BST_CHECKED,0)
-#define HANDLE_CHECK(idc,hvar) case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0); break
-#define HANDLE_CHECKNB(idc,hvar)case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0)
-#define ENABLE_CONTROL(idc,value) EnableWindow(GetDlgItem(hWnd,idc),value)
-
-#define INIT_SLIDER(idc,minrange,maxrange,tickfreq,pagesize,linesize) \
- SendMessage(GetDlgItem(hWnd,idc),TBM_SETRANGEMIN,FALSE,minrange); \
- SendMessage(GetDlgItem(hWnd,idc),TBM_SETRANGEMAX,FALSE,maxrange); \
- SendMessage(GetDlgItem(hWnd,idc),TBM_SETTICFREQ,tickfreq,0); \
- SendMessage(GetDlgItem(hWnd,idc),TBM_SETPAGESIZE,0,pagesize); \
- SendMessage(GetDlgItem(hWnd,idc),TBM_SETLINESIZE,0,linesize)
-
-#define HANDLE_SCROLL_MESSAGE(idc,idcDisplay) \
- if((HWND)lParam == GetDlgItem(hWnd,idc)) return DoHandleScrollMessage( GetDlgItem(hWnd,idcDisplay), wParam, lParam )
+#ifdef _WIN32
+# include "WinConfig.h"
+#else
+# include "LnxConfig.h"
+#endif
namespace DebugConfig
{
@@ -50,24 +31,32 @@ namespace DebugConfig
extern void EnableControls( HWND hWnd );
}
-extern int SendDialogMsg( HWND hwnd, int dlgId, UINT code, WPARAM wParam, LPARAM lParam);
-extern HRESULT GUIDFromString( const char *str, LPGUID guid );
+namespace SoundtouchCfg
+{
+ extern void ReadSettings();
+ extern void WriteSettings();
+ extern void OpenDialog( HWND hWnd );
+ extern BOOL CALLBACK DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
+}
-extern void AssignSliderValue( HWND idcwnd, HWND hwndDisplay, int value );
-extern void AssignSliderValue( HWND hWnd, int idc, int editbox, int value );
-extern int GetSliderValue( HWND hWnd, int idc );
-extern BOOL DoHandleScrollMessage( HWND hwndDisplay, WPARAM wParam, LPARAM lParam );
+extern int SendDialogMsg( HWND hwnd, int dlgId, UINT code, WPARAM wParam, LPARAM lParam);
+extern HRESULT GUIDFromString( const char *str, LPGUID guid );
-bool CfgFindName( const TCHAR *Section, const TCHAR* Name);
+extern void AssignSliderValue( HWND idcwnd, HWND hwndDisplay, int value );
+extern void AssignSliderValue( HWND hWnd, int idc, int editbox, int value );
+extern int GetSliderValue( HWND hWnd, int idc );
+extern BOOL DoHandleScrollMessage( HWND hwndDisplay, WPARAM wParam, LPARAM lParam );
-void CfgWriteBool(const TCHAR* Section, const TCHAR* Name, bool Value);
-void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value);
-void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data);
+extern bool CfgFindName( const TCHAR *Section, const TCHAR* Name);
-bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default);
-void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default);
-void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default);
-int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);
+extern void CfgWriteBool(const TCHAR* Section, const TCHAR* Name, bool Value);
+extern void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value);
+extern void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const wstring& Data);
+
+extern bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default);
+extern void CfgReadStr(const TCHAR* Section, const TCHAR* Name, wstring& Data, int DataSize, const TCHAR* Default);
+extern void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default);
+extern int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default);
// Items Specific to DirectSound
@@ -83,4 +72,3 @@ struct ds_device_data
bool hasGuid;
};
-#endif
diff --git a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp
index 5c4e0da69a..bfcf05904c 100644
--- a/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp
+++ b/plugins/spu2-x/src/Windows/RealtimeDebugger.cpp
@@ -16,6 +16,7 @@
*/
+#include "Global.h"
#include "Dialogs.h"
#include "../RegTable.h"
@@ -59,7 +60,7 @@ static BOOL CALLBACK DebugProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
return TRUE;
}
-#ifdef SPU2X_DEVBUILD
+#ifdef PCSX2_DEVBUILD
int FillRectangle(HDC dc, int left, int top, int width, int height)
{
diff --git a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp
index 9d89a78aa0..4edb1131f7 100644
--- a/plugins/spu2-x/src/Windows/SndOut_DSound.cpp
+++ b/plugins/spu2-x/src/Windows/SndOut_DSound.cpp
@@ -15,6 +15,8 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
+
#define _WIN32_DCOM
#include "Dialogs.h"
@@ -103,6 +105,8 @@ private:
public:
s32 Init()
{
+ CoInitializeEx( NULL, COINIT_MULTITHREADED );
+
//
// Initialize DSound
//
@@ -180,7 +184,7 @@ public:
throw std::runtime_error( "DirectSound Error: Buffer could not be created." );
}
- if( FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) )
+ if( FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) || buffer == NULL )
throw std::runtime_error( "DirectSound Error: Interface could not be queried." );
buffer_->Release();
@@ -242,11 +246,12 @@ public:
buffer_events[i] = NULL;
}
- SAFE_RELEASE( buffer_notify );
- SAFE_RELEASE( buffer );
+ safe_release( buffer_notify );
+ safe_release( buffer );
}
- SAFE_RELEASE( dsound );
+ safe_release( dsound );
+ CoUninitialize();
}
private:
@@ -406,13 +411,13 @@ private:
static BOOL CALLBACK DSEnumCallback( LPGUID lpGuid, LPCTSTR lpcstrDescription, LPCTSTR lpcstrModule, LPVOID lpContext );
public:
- virtual void Configure(HWND parent)
+ virtual void Configure(uptr parent)
{
INT_PTR ret;
- ret=DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DSOUND),GetActiveWindow(),(DLGPROC)ConfigProc,1);
+ ret=DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DSOUND),(HWND)parent,(DLGPROC)ConfigProc,1);
if(ret==-1)
{
- MessageBoxEx(GetActiveWindow(),L"Error Opening the config dialog.",L"OMG ERROR!",MB_OK,0);
+ MessageBoxEx((HWND)parent,L"Error Opening the config dialog.",L"OMG ERROR!",MB_OK,0);
return;
}
}
diff --git a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp
index 225e0ddaac..5d4afb7711 100644
--- a/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp
+++ b/plugins/spu2-x/src/Windows/SndOut_XAudio2.cpp
@@ -15,11 +15,13 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
+
#define _WIN32_DCOM
-
#include "Dialogs.h"
-#include
+#include
+#include
namespace Exception
{
@@ -181,7 +183,7 @@ private:
killMe->FlushSourceBuffers();
EnterCriticalSection( &cs );
killMe->DestroyVoice();
- SAFE_DELETE_ARRAY( qbuffer );
+ safe_delete_array( qbuffer );
LeaveCriticalSection( &cs );
DeleteCriticalSection( &cs );
}
@@ -225,7 +227,7 @@ private:
};
- IXAudio2* pXAudio2;
+ CComPtr pXAudio2;
IXAudio2MasteringVoice* pMasteringVoice;
BaseStreamingVoice* voiceContext;
@@ -314,7 +316,7 @@ public:
catch( Exception::XAudio2Error& ex )
{
SysMessage( ex.CMessage() );
- SAFE_RELEASE( pXAudio2 );
+ pXAudio2.Release();
CoUninitialize();
return -1;
}
@@ -333,7 +335,7 @@ public:
// But doing no cleanup at all causes XA2 under XP to crash. So after much trial
// and error we found a happy compromise as follows:
- SAFE_DELETE_OBJ( voiceContext );
+ safe_delete( voiceContext );
voiceContext = NULL;
@@ -342,12 +344,11 @@ public:
pMasteringVoice = NULL;
- SAFE_RELEASE( pXAudio2 );
-
+ pXAudio2.Release();
CoUninitialize();
}
- virtual void Configure(HWND parent)
+ virtual void Configure(uptr parent)
{
}
diff --git a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp
index eb0f07ca1c..378c0871de 100644
--- a/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp
+++ b/plugins/spu2-x/src/Windows/SndOut_waveOut.cpp
@@ -15,8 +15,8 @@
* along with SPU2-X. If not, see .
*/
+#include "Global.h"
#include "Dialogs.h"
-#include
class WaveOutModule: public SndOutModule
@@ -197,7 +197,7 @@ public:
}
waveOutClose(hwodevice);
- SAFE_DELETE_ARRAY( qbuffer );
+ safe_delete_array( qbuffer );
}
private:
@@ -271,13 +271,13 @@ private:
}
public:
- virtual void Configure(HWND parent)
+ virtual void Configure(uptr parent)
{
INT_PTR ret;
- ret=DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_WAVEOUT),GetActiveWindow(),(DLGPROC)ConfigProc,1);
+ ret=DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_WAVEOUT), (HWND)parent, (DLGPROC)ConfigProc,1);
if(ret==-1)
{
- MessageBoxEx(GetActiveWindow(), L"Error Opening the config dialog.", L"OMG ERROR!", MB_OK, 0);
+ MessageBoxEx((HWND)parent, L"Error Opening the config dialog.", L"OMG ERROR!", MB_OK, 0);
return;
}
}
diff --git a/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj b/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj
index a83e1e8ba9..fe52c0d5ad 100644
--- a/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj
+++ b/plugins/spu2-x/src/Windows/Spu2-X_vs2008.vcproj
@@ -5,6 +5,7 @@
Name="SPU2-X"
ProjectGUID="{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}"
RootNamespace="spu2x"
+ TargetFrameworkVersion="0"
>
@@ -129,10 +133,10 @@
/>
@@ -295,9 +300,10 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
@@ -488,11 +551,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -812,25 +1081,141 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -843,43 +1228,17 @@
>
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
.
*/
+#include "Global.h"
#include "Dialogs.h"
int SendDialogMsg( HWND hwnd, int dlgId, UINT code, WPARAM wParam, LPARAM lParam)
diff --git a/plugins/spu2-x/src/Windows/WinConfig.h b/plugins/spu2-x/src/Windows/WinConfig.h
new file mode 100644
index 0000000000..c768ecd0ae
--- /dev/null
+++ b/plugins/spu2-x/src/Windows/WinConfig.h
@@ -0,0 +1,61 @@
+
+#pragma once
+
+# define WINVER 0x0501
+# define _WIN32_WINNT 0x0501
+
+#include
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+
+extern HINSTANCE hInstance;
+
+#define SET_CHECK(idc,value) SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,((value)==0)?BST_UNCHECKED:BST_CHECKED,0)
+#define HANDLE_CHECK(idc,hvar) case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0); break
+#define HANDLE_CHECKNB(idc,hvar)case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0)
+#define ENABLE_CONTROL(idc,value) EnableWindow(GetDlgItem(hWnd,idc),value)
+
+#define INIT_SLIDER(idc,minrange,maxrange,tickfreq,pagesize,linesize) \
+ SendMessage(GetDlgItem(hWnd,idc),TBM_SETRANGEMIN,FALSE,minrange); \
+ SendMessage(GetDlgItem(hWnd,idc),TBM_SETRANGEMAX,FALSE,maxrange); \
+ SendMessage(GetDlgItem(hWnd,idc),TBM_SETTICFREQ,tickfreq,0); \
+ SendMessage(GetDlgItem(hWnd,idc),TBM_SETPAGESIZE,0,pagesize); \
+ SendMessage(GetDlgItem(hWnd,idc),TBM_SETLINESIZE,0,linesize)
+
+#define HANDLE_SCROLL_MESSAGE(idc,idcDisplay) \
+ if((HWND)lParam == GetDlgItem(hWnd,idc)) return DoHandleScrollMessage( GetDlgItem(hWnd,idcDisplay), wParam, lParam )
+
+
+// *** BEGIN DRIVER-SPECIFIC CONFIGURATION ***
+// -------------------------------------------
+
+struct CONFIG_XAUDIO2
+{
+ std::wstring Device;
+ s8 NumBuffers;
+
+ CONFIG_XAUDIO2() :
+ Device(),
+ NumBuffers( 2 )
+ {
+ }
+};
+
+struct CONFIG_WAVEOUT
+{
+ std::wstring Device;
+ s8 NumBuffers;
+
+ CONFIG_WAVEOUT() :
+ Device(),
+ NumBuffers( 4 )
+ {
+ }
+};
+
+extern CONFIG_WAVEOUT Config_WaveOut;
+extern CONFIG_XAUDIO2 Config_XAudio2;
diff --git a/plugins/spu2-x/src/Windows/dsp.cpp b/plugins/spu2-x/src/Windows/dsp.cpp
index 442a5c919c..0171d36b68 100644
--- a/plugins/spu2-x/src/Windows/dsp.cpp
+++ b/plugins/spu2-x/src/Windows/dsp.cpp
@@ -15,7 +15,15 @@
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-#include "../spu2.h"
+
+#include "Global.h"
+
+# define WINVER 0x0501
+# define _WIN32_WINNT 0x0501
+
+#include
+#include
+
extern "C" {
#include "dsp.h"
diff --git a/plugins/spu2-x/src/defs.h b/plugins/spu2-x/src/defs.h
index fdbbc8eaf5..7df50a66ec 100644
--- a/plugins/spu2-x/src/defs.h
+++ b/plugins/spu2-x/src/defs.h
@@ -17,12 +17,27 @@
#pragma once
+#include "Mixer.h"
+
+// --------------------------------------------------------------------------------------
+// SPU2 Memory Indexers
+// --------------------------------------------------------------------------------------
+
+#define spu2Rs16(mmem) (*(s16 *)((s8 *)spu2regs + ((mmem) & 0x1fff)))
+#define spu2Ru16(mmem) (*(u16 *)((s8 *)spu2regs + ((mmem) & 0x1fff)))
+
+extern s16* __fastcall GetMemPtr(u32 addr);
+extern s16 __fastcall spu2M_Read( u32 addr );
+extern void __fastcall spu2M_Write( u32 addr, s16 value );
+extern void __fastcall spu2M_Write( u32 addr, u16 value );
+
+
struct V_VolumeLR
{
static V_VolumeLR Max;
- s32 Left;
- s32 Right;
+ s32 Left;
+ s32 Right;
V_VolumeLR() {}
V_VolumeLR( s32 both ) :
@@ -39,10 +54,10 @@ struct V_VolumeSlide
// Holds the "original" value of the volume for this voice, prior to slides.
// (ie, the volume as written to the register)
- s16 Reg_VOL;
- s32 Value;
- s8 Increment;
- s8 Mode;
+ s16 Reg_VOL;
+ s32 Value;
+ s8 Increment;
+ s8 Mode;
public:
V_VolumeSlide() {}
@@ -57,7 +72,6 @@ public:
void Update();
void RegSet( u16 src ); // used to set the volume from a register source (16 bit signed)
void DebugDump( FILE* dump, const char* title, const char* nameLR );
-
};
struct V_VolumeSlideLR
@@ -304,135 +318,235 @@ struct V_VoiceGates
s16 WetR; // 'AND Gate' for Effect Output for Right Channel
};
-union V_CoreGates
+struct V_CoreGates
{
- struct
+ union
{
- u64 lo;
- u64 hi;
- } v128;
+ u128 v128;
- struct
- {
- s16 InpL; // Sound Data Input to Direct Output (Left)
- s16 InpR; // Sound Data Input to Direct Output (Right)
- s16 SndL; // Voice Data to Direct Output (Left)
- s16 SndR; // Voice Data to Direct Output (Right)
- s16 ExtL; // External Input to Direct Output (Left)
- s16 ExtR; // External Input to Direct Output (Right)
+ struct
+ {
+ s16 InpL; // Sound Data Input to Direct Output (Left)
+ s16 InpR; // Sound Data Input to Direct Output (Right)
+ s16 SndL; // Voice Data to Direct Output (Left)
+ s16 SndR; // Voice Data to Direct Output (Right)
+ s16 ExtL; // External Input to Direct Output (Left)
+ s16 ExtR; // External Input to Direct Output (Right)
+ };
};
+
+};
+
+struct VoiceMixSet
+{
+ static const VoiceMixSet Empty;
+ StereoOut32 Dry, Wet;
+
+ VoiceMixSet() {}
+ VoiceMixSet( const StereoOut32& dry, const StereoOut32& wet ) :
+ Dry( dry ),
+ Wet( wet )
+ {
+ }
};
struct V_Core
{
static const uint NumVoices = 24;
+ int Index; // Core index identifier.
+
// Voice Gates -- These are SSE-related values, and must always be
// first to ensure 16 byte alignment
- V_VoiceGates VoiceGates[NumVoices];
- V_CoreGates DryGate;
- V_CoreGates WetGate;
+ V_VoiceGates VoiceGates[NumVoices];
+ V_CoreGates DryGate;
+ V_CoreGates WetGate;
- V_VolumeSlideLR MasterVol;// Master Volume
- V_VolumeLR ExtVol; // Volume for External Data Input
- V_VolumeLR InpVol; // Volume for Sound Data Input
- V_VolumeLR FxVol; // Volume for Output from Effects
+ V_VolumeSlideLR MasterVol; // Master Volume
+ V_VolumeLR ExtVol; // Volume for External Data Input
+ V_VolumeLR InpVol; // Volume for Sound Data Input
+ V_VolumeLR FxVol; // Volume for Output from Effects
- V_Voice Voices[NumVoices];
+ V_Voice Voices[NumVoices];
-// Interrupt Address
- u32 IRQA;
-// DMA Transfer Start Address
- u32 TSA;
-// DMA Transfer Data Address (Internal...)
- u32 TDA;
+ u32 IRQA; // Interrupt Address
+ u32 TSA; // DMA Transfer Start Address
+ u32 TDA; // DMA Transfer Data Address (Internal...)
-// Interrupt Enable
- s8 IRQEnable;
-// DMA related?
- s8 DMABits;
-// Effect Enable
- s8 FxEnable;
-// Noise Clock
- s8 NoiseClk;
-// AutoDMA Status
- u16 AutoDMACtrl;
-// DMA Interrupt Counter
- s32 DMAICounter;
-// Mute
- s8 Mute;
-// Input Buffer
- u32 InputDataLeft;
- u32 InputPos;
- u32 InputDataProgress;
- u8 AdmaInProgress;
+ s8 IRQEnable; // Interrupt Enable
+ s8 DMABits; // DMA related?
+ s8 FxEnable; // Effect Enable
+ s8 NoiseClk; // Noise Clock
+ u16 AutoDMACtrl; // AutoDMA Status
+ s32 DMAICounter; // DMA Interrupt Counter
+ s8 Mute; // Mute
+ u32 InputDataLeft; // Input Buffer
+ u32 InputPos;
+ u32 InputDataProgress;
+ u8 AdmaInProgress;
-// Reverb
- V_Reverb Revb;
- V_ReverbBuffers RevBuffers; // buffer pointers for reverb, pre-calculated and pre-clipped.
- u32 EffectsStartA;
- u32 EffectsEndA;
- u32 ReverbX;
+ V_Reverb Revb; // Reverb Registers
+ V_ReverbBuffers RevBuffers; // buffer pointers for reverb, pre-calculated and pre-clipped.
+ u32 EffectsStartA;
+ u32 EffectsEndA;
+ u32 ReverbX;
// Current size 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;
+ s32 EffectsBufferSize;
-// Registers
- V_CoreRegs Regs;
+ V_CoreRegs Regs; // Registers
// Last samples to pass through the effects processor.
// Used because the effects processor works at 24khz and just pulls
// from this for the odd Ts.
- StereoOut32 LastEffect;
+ StereoOut32 LastEffect;
- u8 InitDelay;
+ u8 InitDelay;
+ u8 CoreEnabled;
- u8 CoreEnabled;
+ u8 AttrBit0;
+ u8 AttrBit4;
+ u8 AttrBit5;
- u8 AttrBit0;
- u8 AttrBit4;
- u8 AttrBit5;
+ u16* DMAPtr;
+ u32 MADR;
+ u32 TADR;
- u16*DMAPtr;
- u32 MADR;
- u32 TADR;
+ // HACK -- This is a temp buffer which is (or isn't?) used to circumvent some memory
+ // corruption that originates elsewhere in the plugin. >_< The actual ADMA buffer
+ // is an area mapped to SPU2 main memory.
+ s16 ADMATempBuffer[0x1000];
- s16 ADMATempBuffer[0x1000];
+// ----------------------------------------------------------------------------------
+// V_Core Methods
+// ----------------------------------------------------------------------------------
- u32 ADMAPV;
- StereoOut32 ADMAP;
+ V_Core() : Index( -1 ) {} // uninitialized constructor
+ V_Core( int idx ); // our badass constructor
+ virtual ~V_Core() throw();
- void Reset();
- void UpdateEffectsBufferSize();
+ void Reset();
+ void UpdateEffectsBufferSize();
- V_Core(); // our badass constructor
- s32 EffectsBufferIndexer( s32 offset ) const;
- void UpdateFeedbackBuffersA();
- void UpdateFeedbackBuffersB();
+ s32 EffectsBufferIndexer( s32 offset ) const;
+ void UpdateFeedbackBuffersA();
+ void UpdateFeedbackBuffersB();
+
+ void WriteRegPS1( u32 mem, u16 value );
+ u16 ReadRegPS1( u32 mem );
+
+// --------------------------------------------------------------------------------------
+// Mixer Section
+// --------------------------------------------------------------------------------------
+
+ StereoOut32 Mix( const VoiceMixSet& inVoices, const StereoOut32& Input, const StereoOut32& Ext );
+ void Reverb_AdvanceBuffer();
+ StereoOut32 DoReverb( const StereoOut32& Input );
+ s32 RevbGetIndexer( s32 offset );
+
+ StereoOut32 ReadInput();
+ StereoOut32 ReadInputPV();
+ StereoOut32 ReadInput_HiFi( bool isCDDA );
+
+// --------------------------------------------------------------------------
+// DMA Section
+// --------------------------------------------------------------------------
+
+ // Returns the index of the DMA channel (4 for Core 0, or 7 for Core 1)
+ int GetDmaIndex() const
+ {
+ return (Index == 0) ? 4 : 7;
+ }
+
+ // returns either '4' or '7'
+ char GetDmaIndexChar() const
+ {
+ return 0x30 + GetDmaIndex();
+ }
+
+ __forceinline u16 DmaRead()
+ {
+ const u16 ret = (u16)spu2M_Read(TDA);
+ ++TDA; TDA &= 0xfffff;
+ return ret;
+ }
+
+ __forceinline void DmaWrite(u16 value)
+ {
+ spu2M_Write( TSA, value );
+ ++TSA; TSA &= 0xfffff;
+ }
+
+ void LogAutoDMA( FILE* fp );
+
+ void DoDMAwrite(u16* pMem, u32 size);
+ void DoDMAread(u16* pMem, u32 size);
+
+ void AutoDMAReadBuffer(int mode);
+ void StartADMAWrite(u16 *pMem, u32 sz);
+ void PlainDMAWrite(u16 *pMem, u32 sz);
};
-extern V_Core Cores[2];
-extern V_SPDIF Spdif;
+extern V_Core Cores[2];
+extern V_SPDIF Spdif;
// Output Buffer Writing Position (the same for all data);
-extern s16 OutPos;
+extern s16 OutPos;
// Input Buffer Reading Position (the same for all data);
-extern s16 InputPos;
+extern s16 InputPos;
// SPU Mixing Cycles ("Ticks mixed" counter)
-extern u32 Cycles;
+extern u32 Cycles;
-#ifdef __LINUX__
+extern short* spu2regs;
+extern short* _spu2mem;
+extern int PlayMode;
-#include
-#include
+extern void SetIrqCall();
+extern void StartVoices(int core, u32 value);
+extern void StopVoices(int core, u32 value);
+extern void InitADSR();
+extern void CalculateADSR( V_Voice& vc );
-static __forceinline u32 timeGetTime()
+extern void spdif_set51(u32 is_5_1_out);
+extern u32 spdif_init();
+extern void spdif_shutdown();
+extern void spdif_get_samples(s32 *samples); // fills the buffer with [l,r,c,lfe,sl,sr] if using 5.1 output, or [l,r] if using stereo
+extern void UpdateSpdifMode();
+
+namespace Savestate
{
- struct timeb t;
- ftime(&t);
- return (u32)(t.time*1000+t.millitm);
+ struct DataBlock;
+
+ extern s32 __fastcall FreezeIt( DataBlock& spud );
+ extern s32 __fastcall ThawIt( DataBlock& spud );
+ extern s32 __fastcall SizeIt();
}
-#endif
+
+// --------------------------------------------------------------------------------------
+// ADPCM Decoder Cache
+// --------------------------------------------------------------------------------------
+
+// The SPU2 has a dynamic memory range which is used for several internal operations, such as
+// registers, CORE 1/2 mixing, AutoDMAs, and some other fancy stuff. We exclude this range
+// from the cache here:
+static const s32 SPU2_DYN_MEMLINE = 0x2800;
+
+// 8 short words per encoded PCM block. (as stored in SPU2 ram)
+static const int pcm_WordsPerBlock = 8;
+
+// number of cachable ADPCM blocks (any blocks above the SPU2_DYN_MEMLINE)
+static const int pcm_BlockCount = 0x100000 / pcm_WordsPerBlock;
+
+// 28 samples per decoded PCM block (as stored in our cache)
+static const int pcm_DecodedSamplesPerBlock = 28;
+
+struct PcmCacheEntry
+{
+ bool Validated;
+ s16 Sampledata[pcm_DecodedSamplesPerBlock];
+};
+
+extern PcmCacheEntry* pcm_cache_data;
diff --git a/plugins/spu2-x/src/regs.h b/plugins/spu2-x/src/regs.h
index 10a789118f..7b1f92c7aa 100644
--- a/plugins/spu2-x/src/regs.h
+++ b/plugins/spu2-x/src/regs.h
@@ -147,21 +147,21 @@ Core attributes (SD_C)
*********************************************************************/
-#define SPDIF_OUT_OFF 0x0000 //no spdif output
-#define SPDIF_OUT_PCM 0x0020 //encode spdif from spu2 pcm output
-#define SPDIF_OUT_BYPASS 0x0100 //bypass spu2 processing
+#define SPDIF_OUT_OFF 0x0000 // no spdif output
+#define SPDIF_OUT_PCM 0x0020 // encode spdif from spu2 pcm output
+#define SPDIF_OUT_BYPASS 0x0100 // bypass spu2 processing
-#define SPDIF_MODE_BYPASS_BITSTREAM 0x0002 //bypass mode for digital bitstream data
-#define SPDIF_MODE_BYPASS_PCM 0x0000 //bypass mode for pcm data (using analog output)
+#define SPDIF_MODE_BYPASS_BITSTREAM 0x0002 // bypass mode for digital bitstream data
+#define SPDIF_MODE_BYPASS_PCM 0x0000 // bypass mode for pcm data (using analog output)
-#define SPDIF_MODE_MEDIA_CD 0x0800 //source media is a CD
-#define SPDIF_MODE_MEDIA_DVD 0x0000 //source media is a DVD
+#define SPDIF_MODE_MEDIA_CD 0x0800 // source media is a CD
+#define SPDIF_MODE_MEDIA_DVD 0x0000 // source media is a DVD
-#define SPDIF_MEDIA_CDVD 0x0200
-#define SPDIF_MEDIA_400 0x0000
+#define SPDIF_MEDIA_CDVD 0x0200
+#define SPDIF_MEDIA_400 0x0000
-#define SPDIF_PROTECT_NORMAL 0x0000 // spdif stream is not protected
-#define SPDIF_PROTECT_PROHIBIT 0x8000 // spdif stream can't be copied
+#define SPDIF_PROTECT_NORMAL 0x0000 // spdif stream is not protected
+#define SPDIF_PROTECT_PROHIBIT 0x8000 // spdif stream can't be copied
/********************************************************************/
diff --git a/plugins/spu2-x/src/spu2freeze.cpp b/plugins/spu2-x/src/spu2freeze.cpp
new file mode 100644
index 0000000000..e35e3825a9
--- /dev/null
+++ b/plugins/spu2-x/src/spu2freeze.cpp
@@ -0,0 +1,146 @@
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2
+ * Developed and maintained by the Pcsx2 Development Team.
+ *
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz]
+ *
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with SPU2-X. If not, see .
+ */
+
+#include "Global.h"
+#include "PS2E-spu2.h" // hopefully temporary, until I resolve lClocks depdendency
+
+namespace Savestate
+{
+ // Arbitrary ID to identify SPU2-X saves.
+ static const u32 SAVE_ID = 0x1227521;
+
+ // versioning for saves.
+ // Increment this when changes to the savestate system are made.
+ static const u32 SAVE_VERSION = 0x0005;
+
+ static void wipe_the_cache()
+ {
+ memset( pcm_cache_data, 0, pcm_BlockCount * sizeof(PcmCacheEntry) );
+ }
+
+ static s16 old_state_sBuffer[pcm_DecodedSamplesPerBlock] = {0};
+}
+
+struct Savestate::DataBlock
+{
+ u32 spu2id; // SPU2-X state identifier lets ZeroGS/PeopsSPU2 know this isn't their state)
+ u8 unkregs[0x10000]; // SPU2 raw register memory
+ u8 mem[0x200000]; // SPU2 raw sample memory
+
+ u32 version; // SPU2-X version identifier
+ V_Core Cores[2];
+ V_SPDIF Spdif;
+ s16 OutPos;
+ s16 InputPos;
+ u32 Cycles;
+ u32 lClocks;
+ int PlayMode;
+};
+
+s32 __fastcall Savestate::FreezeIt( DataBlock& spud )
+{
+ spud.spu2id = SAVE_ID;
+ spud.version = SAVE_VERSION;
+
+ memcpy(spud.unkregs, spu2regs, sizeof(spud.unkregs));
+ memcpy(spud.mem, _spu2mem, sizeof(spud.mem));
+ memcpy(spud.Cores, Cores, sizeof(Cores));
+ memcpy(&spud.Spdif, &Spdif, sizeof(Spdif));
+
+ spud.OutPos = OutPos;
+ spud.InputPos = InputPos;
+ spud.Cycles = Cycles;
+ spud.lClocks = lClocks;
+ spud.PlayMode = PlayMode;
+
+ // note: Don't save the cache. PCSX2 doesn't offer a safe method of predicting
+ // the required size of the savestate prior to saving, plus this is just too
+ // "implementation specific" for the intended spec of a savestate. Let's just
+ // force the user to rebuild their cache instead.
+
+ return 0;
+}
+
+s32 __fastcall Savestate::ThawIt( DataBlock& spud )
+{
+ if( spud.spu2id != SAVE_ID || spud.version < SAVE_VERSION )
+ {
+ fprintf(stderr, "\n*** SPU2-X Warning:\n");
+ if( spud.spu2id == SAVE_ID )
+ fprintf(stderr, "\tSavestate version is from an older version of this plugin.\n");
+ else
+ fprintf(stderr, "\tThe savestate you are trying to load was not made with this plugin.\n");
+
+ fprintf(stderr,
+ "\tAudio may not recover correctly. Save your game to memorycard, reset,\n\n"
+ "\tand then continue from there.\n\n"
+ );
+
+ // Do *not* reset the cores.
+ // We'll need some "hints" as to how the cores should be initialized, and the
+ // only way to get that is to use the game's existing core settings and hope
+ // they kinda match the settings for the savestate (IRQ enables and such).
+
+ // adpcm cache : Clear all the cache flags and buffers.
+
+ wipe_the_cache();
+ }
+ else
+ {
+ SndBuffer::ClearContents();
+
+ // base stuff
+ memcpy(spu2regs, spud.unkregs, sizeof(spud.unkregs));
+ memcpy(_spu2mem, spud.mem, sizeof(spud.mem));
+
+ memcpy(Cores, spud.Cores, sizeof(Cores));
+ memcpy(&Spdif, &spud.Spdif, sizeof(Spdif));
+
+ OutPos = spud.OutPos;
+ InputPos = spud.InputPos;
+ Cycles = spud.Cycles;
+ lClocks = spud.lClocks;
+ PlayMode = spud.PlayMode;
+
+ wipe_the_cache();
+
+ // Go through the V_Voice structs and recalculate SBuffer pointer from
+ // the NextA setting.
+
+ for( int c=0; c<2; c++ )
+ {
+ for( int v=0; v<24; v++ )
+ {
+ const int cacheIdx = Cores[c].Voices[v].NextA / pcm_WordsPerBlock;
+ Cores[c].Voices[v].SBuffer = pcm_cache_data[cacheIdx].Sampledata;
+ }
+ }
+
+ // HACKFIX!! DMAPtr can be invalid after a savestate load, so force it to NULL and
+ // ignore it on any pending ADMA writes. (the DMAPtr concept used to work in old VM
+ // editions of PCSX2 with fixed addressing, but new PCSX2s have dynamic memory
+ // addressing).
+
+ Cores[0].DMAPtr = Cores[1].DMAPtr = NULL;
+ }
+ return 0;
+}
+
+s32 __fastcall Savestate::SizeIt()
+{
+ return sizeof(DataBlock);
+}
diff --git a/plugins/spu2-x/src/Spu2.cpp b/plugins/spu2-x/src/spu2sys.cpp
similarity index 81%
rename from plugins/spu2-x/src/Spu2.cpp
rename to plugins/spu2-x/src/spu2sys.cpp
index ffe65eae89..9798ed1fc0 100644
--- a/plugins/spu2-x/src/Spu2.cpp
+++ b/plugins/spu2-x/src/spu2sys.cpp
@@ -15,50 +15,31 @@
* along with SPU2-X. If not, see .
*/
-#include "Spu2.h"
+// ======================================================================================
+// spu2sys.cpp -- Emulation module for the SPU2 'virtual machine'
+// ======================================================================================
+// This module contains (most!) stuff which is directly related to SPU2 emulation.
+// Contents should be cross-platform compatible whenever possible.
+
+
+#include "Global.h"
#include "RegTable.h"
+#include "dma.h"
-#ifdef __LINUX__
-#include "Linux.h"
-#endif
-
-void StartVoices(int core, u32 value);
-void StopVoices(int core, u32 value);
-
-void InitADSR();
-
-#ifdef _MSC_VER
-DWORD CALLBACK TimeThread(PVOID /* unused param */);
-#endif
-
-void (* _irqcallback)();
-void (* dma4callback)();
-void (* dma7callback)();
+#include "PS2E-spu2.h" // needed until I figure out a nice solution for irqcallback dependencies.
short *spu2regs;
short *_spu2mem;
-u8 callirq;
+V_CoreDebug DebugCores[2];
+V_Core Cores[2];
+V_SPDIF Spdif;
-V_CoreDebug DebugCores[2];
-V_Core Cores[2];
-V_SPDIF Spdif;
+s16 OutPos;
+s16 InputPos;
+u32 Cycles;
-s16 OutPos;
-s16 InputPos;
-u32 Cycles;
-
-u32* cyclePtr = NULL;
-u32 lClocks = 0;
-
-int PlayMode;
-
-#ifdef _MSC_VER
-HINSTANCE hInstance;
-CRITICAL_SECTION threadSync;
-HANDLE hThreadFunc;
-u32 ThreadFuncID;
-#endif
+int PlayMode;
bool has_to_call_irq=false;
@@ -67,33 +48,6 @@ void SetIrqCall()
has_to_call_irq=true;
}
-#ifndef __LINUX__
-void SysMessage(const char *fmt, ...)
-{
- va_list list;
- char tmp[512];
- wchar_t wtmp[512];
-
- va_start(list,fmt);
- sprintf_s(tmp,fmt,list);
- va_end(list);
- swprintf_s(wtmp, L"%S", tmp);
- MessageBox(0, wtmp, L"SPU2-X System Message", 0);
-}
-#else
-void SysMessage(const char *fmt, ...)
-{
- va_list list;
- char tmp[512];
- wchar_t wtmp[512];
-
- va_start(list,fmt);
- sprintf(tmp,fmt,list);
- va_end(list);
- printf("%s", tmp);
-}
-#endif
-
__forceinline s16 * __fastcall GetMemPtr(u32 addr)
{
#ifndef DEBUG_FAST
@@ -111,9 +65,7 @@ __forceinline s16 __fastcall spu2M_Read( u32 addr )
// writes a signed value to the SPU2 ram
// Invalidates the ADPCM cache in the process.
-// Optimization note: don't use __forceinline because the footprint of this
-// function is a little too heavy now. Better to let the compiler decide.
-__inline void __fastcall spu2M_Write( u32 addr, s16 value )
+__forceinline void __fastcall spu2M_Write( u32 addr, s16 value )
{
// Make sure the cache is invalidated:
// (note to self : addr address WORDs, not bytes)
@@ -135,50 +87,55 @@ __inline void __fastcall spu2M_Write( u32 addr, u16 value )
spu2M_Write( addr, (s16)value );
}
-V_VolumeLR V_VolumeLR::Max( 0x7FFFFFFF );
-V_VolumeSlideLR V_VolumeSlideLR::Max( 0x3FFF, 0x7FFFFFFF );
+V_VolumeLR V_VolumeLR::Max( 0x7FFFFFFF );
+V_VolumeSlideLR V_VolumeSlideLR::Max( 0x3FFF, 0x7FFFFFFF );
-V_Core::V_Core()
+V_Core::V_Core( int coreidx ) : Index( coreidx )
+ //LogFile_AutoDMA( NULL )
{
+ /*char fname[128];
+ sprintf( fname, "logs/adma%d.raw", GetDmaIndex() );
+ LogFile_AutoDMA = fopen( fname, "wb" );*/
+}
+
+V_Core::~V_Core() throw()
+{
+ // Can't use this yet because we dumb V_Core into savestates >_<
+ /*if( LogFile_AutoDMA != NULL )
+ {
+ fclose( LogFile_AutoDMA );
+ LogFile_AutoDMA = NULL;
+ }*/
}
void V_Core::Reset()
{
memset( this, 0, sizeof(V_Core) );
- const int c = (this == Cores) ? 0 : 1;
+ const int c = Index;
- Regs.STATX=0;
- Regs.ATTR=0;
- ExtVol = V_VolumeLR::Max;
- InpVol = V_VolumeLR::Max;
- FxVol = V_VolumeLR::Max;
+ Regs.STATX = 0;
+ Regs.ATTR = 0;
+ ExtVol = V_VolumeLR::Max;
+ InpVol = V_VolumeLR::Max;
+ FxVol = V_VolumeLR::Max;
- MasterVol = V_VolumeSlideLR::Max;
+ MasterVol = V_VolumeSlideLR::Max;
- DryGate.ExtL = -1;
- DryGate.ExtR = -1;
- WetGate.ExtL = -1;
- WetGate.ExtR = -1;
- DryGate.InpL = -1;
- DryGate.InpR = -1;
- WetGate.InpR = -1;
- WetGate.InpL = -1;
- DryGate.SndL = -1;
- DryGate.SndR = -1;
- WetGate.SndL = -1;
- WetGate.SndR = -1;
+ memset( &DryGate, -1, sizeof(DryGate) );
+ memset( &WetGate, -1, sizeof(WetGate) );
- Regs.MMIX = 0xFFCF;
- Regs.VMIXL = 0xFFFFFF;
- Regs.VMIXR = 0xFFFFFF;
- Regs.VMIXEL = 0xFFFFFF;
- Regs.VMIXER = 0xFFFFFF;
- EffectsStartA= 0xEFFF8 + 0x10000*c;
- EffectsEndA = 0xEFFFF + 0x10000*c;
- FxEnable=0;
- IRQA=0xFFFF0;
- IRQEnable=1;
+ Regs.MMIX = 0xFFCF;
+ Regs.VMIXL = 0xFFFFFF;
+ Regs.VMIXR = 0xFFFFFF;
+ Regs.VMIXEL = 0xFFFFFF;
+ Regs.VMIXER = 0xFFFFFF;
+ EffectsStartA = 0xEFFF8 + (0x10000*c);
+ EffectsEndA = 0xEFFFF + (0x10000*c);
+
+ FxEnable = 0;
+ IRQA = 0xFFFF0;
+ IRQEnable = 1;
for( uint v=0; v=0x1c00)&&(reg<0x1d80))
{
@@ -530,42 +489,42 @@ void SPU_ps1_write(u32 mem, u16 value)
switch(vval)
{
case 0: //VOLL (Volume L)
- Cores[0].Voices[voice].Volume.Left.Mode = 0;
- Cores[0].Voices[voice].Volume.Left.RegSet( value << 1 );
- Cores[0].Voices[voice].Volume.Left.Reg_VOL = value;
+ Voices[voice].Volume.Left.Mode = 0;
+ Voices[voice].Volume.Left.RegSet( value << 1 );
+ Voices[voice].Volume.Left.Reg_VOL = value;
break;
case 1: //VOLR (Volume R)
- Cores[0].Voices[voice].Volume.Right.Mode = 0;
- Cores[0].Voices[voice].Volume.Right.RegSet( value << 1 );
- Cores[0].Voices[voice].Volume.Right.Reg_VOL = value;
+ Voices[voice].Volume.Right.Mode = 0;
+ Voices[voice].Volume.Right.RegSet( value << 1 );
+ Voices[voice].Volume.Right.Reg_VOL = value;
break;
- case 2: Cores[0].Voices[voice].Pitch = value; break;
- case 3: Cores[0].Voices[voice].StartA = (u32)value<<8; break;
+ case 2: Voices[voice].Pitch = value; break;
+ case 3: Voices[voice].StartA = (u32)value<<8; break;
case 4: // ADSR1 (Envelope)
- Cores[0].Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
- Cores[0].Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
- Cores[0].Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
- Cores[0].Voices[voice].ADSR.SustainLevel = (value & 0xF);
- Cores[0].Voices[voice].ADSR.Reg_ADSR1 = value;
+ Voices[voice].ADSR.AttackMode = (value & 0x8000)>>15;
+ Voices[voice].ADSR.AttackRate = (value & 0x7F00)>>8;
+ Voices[voice].ADSR.DecayRate = (value & 0xF0)>>4;
+ Voices[voice].ADSR.SustainLevel = (value & 0xF);
+ Voices[voice].ADSR.Reg_ADSR1 = value;
break;
case 5: // ADSR2 (Envelope)
- Cores[0].Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
- Cores[0].Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
- Cores[0].Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
- Cores[0].Voices[voice].ADSR.ReleaseRate = (value & 0x1F);
- Cores[0].Voices[voice].ADSR.Reg_ADSR2 = value;
+ Voices[voice].ADSR.SustainMode = (value & 0xE000)>>13;
+ Voices[voice].ADSR.SustainRate = (value & 0x1FC0)>>6;
+ Voices[voice].ADSR.ReleaseMode = (value & 0x20)>>5;
+ Voices[voice].ADSR.ReleaseRate = (value & 0x1F);
+ Voices[voice].ADSR.Reg_ADSR2 = value;
break;
case 6:
- Cores[0].Voices[voice].ADSR.Value = ((s32)value<<16) | value;
+ Voices[voice].ADSR.Value = ((s32)value<<16) | value;
ConLog( "* SPU2: Mysterious ADSR Volume Set to 0x%x", value );
break;
- case 7: Cores[0].Voices[voice].LoopStartA = (u32)value <<8; break;
+ case 7: Voices[voice].LoopStartA = (u32)value <<8; break;
jNO_DEFAULT;
}
@@ -574,21 +533,21 @@ void SPU_ps1_write(u32 mem, u16 value)
else switch(reg)
{
case 0x1d80:// Mainvolume left
- Cores[0].MasterVol.Left.Mode = 0;
- Cores[0].MasterVol.Left.RegSet( value );
+ MasterVol.Left.Mode = 0;
+ MasterVol.Left.RegSet( value );
break;
case 0x1d82:// Mainvolume right
- Cores[0].MasterVol.Right.Mode = 0;
- Cores[0].MasterVol.Right.RegSet( value );
+ MasterVol.Right.Mode = 0;
+ MasterVol.Right.RegSet( value );
break;
case 0x1d84:// Reverberation depth left
- Cores[0].FxVol.Left = GetVol32( value );
+ FxVol.Left = GetVol32( value );
break;
case 0x1d86:// Reverberation depth right
- Cores[0].FxVol.Right = GetVol32( value );
+ FxVol.Right = GetVol32( value );
break;
case 0x1d88:// Voice ON (0-15)
@@ -652,11 +611,11 @@ void SPU_ps1_write(u32 mem, u16 value)
break;
case 0x1da4:
- Cores[0].IRQA=(u32)value<<8;
+ IRQA = (u32)value<<8;
break;
case 0x1da6:
- Cores[0].TSA=(u32)value<<8;
+ TSA = (u32)value<<8;
break;
case 0x1daa:
@@ -668,7 +627,7 @@ void SPU_ps1_write(u32 mem, u16 value)
break;
case 0x1da8:// Spu Write to Memory
- DmaWrite(0,value);
+ DmaWrite(value);
show=false;
break;
}
@@ -678,8 +637,10 @@ void SPU_ps1_write(u32 mem, u16 value)
spu2Ru16(mem)=value;
}
-u16 SPU_ps1_read(u32 mem)
+u16 V_Core::ReadRegPS1(u32 mem)
{
+ jASSUME( Index == 0 ); // Valid on Core 0 only!
+
bool show=true;
u16 value = spu2Ru16(mem);
@@ -693,60 +654,60 @@ u16 SPU_ps1_read(u32 mem)
switch(vval)
{
case 0: //VOLL (Volume L)
- //value=Cores[0].Voices[voice].VolumeL.Mode;
- //value=Cores[0].Voices[voice].VolumeL.Value;
- value = Cores[0].Voices[voice].Volume.Left.Reg_VOL;
+ //value=Voices[voice].VolumeL.Mode;
+ //value=Voices[voice].VolumeL.Value;
+ value = Voices[voice].Volume.Left.Reg_VOL;
break;
case 1: //VOLR (Volume R)
- //value=Cores[0].Voices[voice].VolumeR.Mode;
- //value=Cores[0].Voices[voice].VolumeR.Value;
- value = Cores[0].Voices[voice].Volume.Right.Reg_VOL;
+ //value=Voices[voice].VolumeR.Mode;
+ //value=Voices[voice].VolumeR.Value;
+ value = Voices[voice].Volume.Right.Reg_VOL;
break;
- case 2: value = Cores[0].Voices[voice].Pitch; break;
- case 3: value = Cores[0].Voices[voice].StartA; break;
- case 4: value = Cores[0].Voices[voice].ADSR.Reg_ADSR1; break;
- case 5: value = Cores[0].Voices[voice].ADSR.Reg_ADSR2; break;
- case 6: value = Cores[0].Voices[voice].ADSR.Value >> 16; break;
- case 7: value = Cores[0].Voices[voice].LoopStartA; break;
+ case 2: value = Voices[voice].Pitch; break;
+ case 3: value = Voices[voice].StartA; break;
+ case 4: value = Voices[voice].ADSR.Reg_ADSR1; break;
+ case 5: value = Voices[voice].ADSR.Reg_ADSR2; break;
+ case 6: value = Voices[voice].ADSR.Value >> 16; break;
+ case 7: value = Voices[voice].LoopStartA; break;
jNO_DEFAULT;
}
}
else switch(reg)
{
- case 0x1d80: value = Cores[0].MasterVol.Left.Value >> 16; break;
- case 0x1d82: value = Cores[0].MasterVol.Right.Value >> 16; break;
- case 0x1d84: value = Cores[0].FxVol.Left >> 16; break;
- case 0x1d86: value = Cores[0].FxVol.Right >> 16; break;
+ case 0x1d80: value = MasterVol.Left.Value >> 16; break;
+ case 0x1d82: value = MasterVol.Right.Value >> 16; break;
+ case 0x1d84: value = FxVol.Left >> 16; break;
+ case 0x1d86: value = FxVol.Right >> 16; break;
case 0x1d88: value = 0; break;
case 0x1d8a: value = 0; break;
case 0x1d8c: value = 0; break;
case 0x1d8e: value = 0; break;
- case 0x1d90: value = Cores[0].Regs.PMON&0xFFFF; break;
- case 0x1d92: value = Cores[0].Regs.PMON>>16; break;
+ case 0x1d90: value = Regs.PMON&0xFFFF; break;
+ case 0x1d92: value = Regs.PMON>>16; break;
- case 0x1d94: value = Cores[0].Regs.NON&0xFFFF; break;
- case 0x1d96: value = Cores[0].Regs.NON>>16; break;
+ case 0x1d94: value = Regs.NON&0xFFFF; break;
+ case 0x1d96: value = Regs.NON>>16; break;
- case 0x1d98: value = Cores[0].Regs.VMIXEL&0xFFFF; break;
- case 0x1d9a: value = Cores[0].Regs.VMIXEL>>16; break;
- case 0x1d9c: value = Cores[0].Regs.VMIXL&0xFFFF; break;
- case 0x1d9e: value = Cores[0].Regs.VMIXL>>16; break;
+ case 0x1d98: value = Regs.VMIXEL&0xFFFF; break;
+ case 0x1d9a: value = Regs.VMIXEL>>16; break;
+ case 0x1d9c: value = Regs.VMIXL&0xFFFF; break;
+ case 0x1d9e: value = Regs.VMIXL>>16; break;
case 0x1da2:
- if( value != Cores[0].EffectsStartA>>3 )
+ if( value != EffectsStartA>>3 )
{
- value = Cores[0].EffectsStartA>>3;
- Cores[0].UpdateEffectsBufferSize();
- Cores[0].ReverbX = 0;
+ value = EffectsStartA>>3;
+ UpdateEffectsBufferSize();
+ ReverbX = 0;
}
break;
- case 0x1da4: value = Cores[0].IRQA>>3; break;
- case 0x1da6: value = Cores[0].TSA>>3; break;
+ case 0x1da4: value = IRQA>>3; break;
+ case 0x1da6: value = TSA>>3; break;
case 0x1daa:
value = SPU2read(REG_C_ATTR);
@@ -755,7 +716,7 @@ u16 SPU_ps1_read(u32 mem)
value = 0; //SPU2read(REG_P_STATX)<<3;
break;
case 0x1da8:
- value = DmaRead(0);
+ value = DmaRead();
show=false;
break;
}
@@ -930,6 +891,30 @@ void SPU2_FastWrite( u32 rmem, u16 value )
V_Core& thiscore = Cores[core];
switch(omem)
{
+ case 0x1ac:
+ // ----------------------------------------------------------------------------
+ // 0x1ac / 0x5ac : direct-write to DMA address : special register (undocumented)
+ // ----------------------------------------------------------------------------
+ // On the GS, DMAs are actually pushed through a hardware register. Chances are the
+ // SPU works the same way, and "technically" *all* DMA data actually passes through
+ // the HW registers at 0x1ac (core0) and 0x5ac (core1). We handle normal DMAs in
+ // optimized block copy fashion elsewhere, but some games will write this register
+ // directly, so handle those here:
+
+ // Performance Note: If a game uses this extensively, it *will* be slow. I plan to
+ // fix that using a proper paged LUT someday.
+
+ for( int i=0; i<2; i++ )
+ {
+ if(Cores[i].IRQEnable && (Cores[i].IRQA == Cores[i].TSA))
+ {
+ Spdif.Info = 4 << i;
+ SetIrqCall();
+ }
+ }
+ thiscore.DmaWrite( value );
+ break;
+
case REG_C_ATTR:
{
int irqe = thiscore.IRQEnable;