mirror of
https://github.com/libretro/Play-.git
synced 2025-01-26 03:04:20 +00:00
PsfPlayer: Added basic reverb support in PSP/SasCore emulation.
git-svn-id: http://svn.purei.org/purei/trunk@670 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
47df31b626
commit
6d1c9aeb67
@ -89,42 +89,6 @@ static const char* g_generalRegisterName[MAX_GENERAL_REG_NAME] =
|
||||
"IN_COEF_R"
|
||||
};
|
||||
|
||||
static bool g_reverbParamIsAddress[CSpuBase::REVERB_PARAM_COUNT] =
|
||||
{
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
};
|
||||
|
||||
CSpu::CSpu(CSpuBase& base) :
|
||||
m_base(base)
|
||||
{
|
||||
@ -192,7 +156,7 @@ void CSpu::WriteRegister(uint32 address, uint16 value)
|
||||
{
|
||||
uint32 registerId = (address - REVERB_START) / 2;
|
||||
uint32 result = value;
|
||||
if(g_reverbParamIsAddress[registerId])
|
||||
if(CSpuBase::g_reverbParamIsAddress[registerId])
|
||||
{
|
||||
result *= 8;
|
||||
}
|
||||
|
@ -9,6 +9,42 @@ using namespace std;
|
||||
#define INIT_SAMPLE_RATE (44100)
|
||||
#define LOG_NAME ("iop_spubase")
|
||||
|
||||
bool CSpuBase::g_reverbParamIsAddress[REVERB_PARAM_COUNT] =
|
||||
{
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
};
|
||||
|
||||
CSpuBase::CSpuBase(uint8* ram, uint32 ramSize) :
|
||||
m_ram(ram),
|
||||
m_ramSize(ramSize),
|
||||
|
@ -176,7 +176,6 @@ namespace Iop
|
||||
void SetChannelOnHi(uint16);
|
||||
|
||||
UNION32_16 GetChannelReverb() const;
|
||||
void SetChannelReverb(uint16, uint16);
|
||||
void SetChannelReverbLo(uint16);
|
||||
void SetChannelReverbHi(uint16);
|
||||
|
||||
@ -194,7 +193,9 @@ namespace Iop
|
||||
|
||||
void Render(int16*, unsigned int, unsigned int);
|
||||
|
||||
private:
|
||||
static bool g_reverbParamIsAddress[REVERB_PARAM_COUNT];
|
||||
|
||||
private:
|
||||
class CSampleReader
|
||||
{
|
||||
public:
|
||||
|
@ -106,6 +106,10 @@ CBios::MODULEFUNCTION CBios::g_SasCoreFunctions[] =
|
||||
{ 0x07F58C24, "sasGetAllEnvelope" },
|
||||
{ 0xA3589D81, "sasCore" },
|
||||
{ 0x42778A9F, "sasInit" },
|
||||
{ 0x33D4AB37, "sasSetEffectType" },
|
||||
{ 0x267A6DD2, "sasSetEffectParam" },
|
||||
{ 0xD5A229C9, "sasSetEffectVolume" },
|
||||
{ 0xF983B186, "sasSetEffect" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,30 @@
|
||||
|
||||
using namespace Psp;
|
||||
|
||||
#define SPURAM_ALLOC_BASEADDRESS (0x40000)
|
||||
|
||||
CSasCore::REVERBINFO CSasCore::g_ReverbStudioC =
|
||||
{
|
||||
0x6FE0,
|
||||
{
|
||||
0x00E3, 0x00A9, 0x6F60, 0x4FA8, 0xBCE0, 0x4510, 0xBEF0, 0xA680,
|
||||
0x5680, 0x52C0, 0x0DFB, 0x0B58, 0x0D09, 0x0A3C, 0x0BD9, 0x0973,
|
||||
0x0B59, 0x08DA, 0x08D9, 0x05E9, 0x07EC, 0x04B0, 0x06EF, 0x03D2,
|
||||
0x05EA, 0x031D, 0x031C, 0x0238, 0x0154, 0x00AA, 0x8000, 0x8000,
|
||||
}
|
||||
};
|
||||
|
||||
CSasCore::REVERBINFO CSasCore::g_ReverbSpace =
|
||||
{
|
||||
0xF6C0,
|
||||
{
|
||||
0x033D, 0x0231, 0x7E00, 0x5000, 0xB400, 0xB000, 0x4C00, 0xB000,
|
||||
0x6000, 0x5400, 0x1ED6, 0x1A31, 0x1D14, 0x183B, 0x1BC2, 0x16B2,
|
||||
0x1A32, 0x15EF, 0x15EE, 0x1055, 0x1334, 0x0F2D, 0x11F6, 0x0C5D,
|
||||
0x1056, 0x0AE1, 0x0AE0, 0x07A2, 0x0464, 0x0232, 0x8000, 0x8000,
|
||||
}
|
||||
};
|
||||
|
||||
CSasCore::CSasCore(uint8* ram)
|
||||
: m_spuRam(NULL)
|
||||
, m_spuRamSize(0)
|
||||
@ -68,7 +92,7 @@ uint32 CSasCore::AllocMemory(uint32 size)
|
||||
{
|
||||
assert(m_spuRamSize != 0);
|
||||
|
||||
const uint32 startAddress = 0x1000;
|
||||
const uint32 startAddress = SPURAM_ALLOC_BASEADDRESS;
|
||||
uint32 currentAddress = startAddress;
|
||||
MemBlockList::iterator blockIterator(m_blocks.begin());
|
||||
while(blockIterator != m_blocks.end())
|
||||
@ -123,6 +147,26 @@ void CSasCore::VerifyAllocationMap()
|
||||
|
||||
#endif
|
||||
|
||||
void CSasCore::SetupReverb(const REVERBINFO& reverbInfo)
|
||||
{
|
||||
for(unsigned int spuIdx = 0; spuIdx < 2; spuIdx++)
|
||||
{
|
||||
uint32 endAddress = 0x20000 + (spuIdx * 0x20000);
|
||||
uint32 startAddress = endAddress - reverbInfo.workAreaSize;
|
||||
m_spu[spuIdx]->SetReverbWorkAddressStart(startAddress);
|
||||
m_spu[spuIdx]->SetReverbWorkAddressEnd(endAddress - 1);
|
||||
for(unsigned int i = 0; i < Iop::CSpuBase::REVERB_PARAM_COUNT; i++)
|
||||
{
|
||||
uint32 param = reverbInfo.params[i];
|
||||
if(Iop::CSpuBase::g_reverbParamIsAddress[i])
|
||||
{
|
||||
param *= 8;
|
||||
}
|
||||
m_spu[spuIdx]->SetReverbParam(i, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CSasCore::Init(uint32 contextAddr, uint32 grain, uint32 unknown2, uint32 unknown3, uint32 frequency)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
@ -341,6 +385,60 @@ uint32 CSasCore::GetEndFlag(uint32 contextAddr)
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32 CSasCore::SetEffectType(uint32 contextAddr, uint32 effectType)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
CLog::GetInstance().Print(LOGNAME, "SetEffectType(contextAddr = 0x%0.8X, effectType = 0x%0.8X);\r\n",
|
||||
contextAddr, effectType);
|
||||
#endif
|
||||
switch(effectType)
|
||||
{
|
||||
case REVERB_STUDIOC:
|
||||
SetupReverb(g_ReverbStudioC);
|
||||
break;
|
||||
case REVERB_SPACE:
|
||||
SetupReverb(g_ReverbSpace);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CSasCore::SetEffectParam(uint32 contextAddr, uint32 dt, uint32 fb)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
CLog::GetInstance().Print(LOGNAME, "SetEffectParam(contextAddr = 0x%0.8X, dt = 0x%0.2X, fb = 0x%0.2X);\r\n",
|
||||
contextAddr, dt, fb);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CSasCore::SetEffectVolume(uint32 contextAddr, uint32 volumeLeft, uint32 volumeRight)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
CLog::GetInstance().Print(LOGNAME, "SetEffectVolume(contextAddr = 0x%0.8X, left = 0x%0.2X, right = 0x%0.2X);\r\n",
|
||||
contextAddr, volumeLeft, volumeRight);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CSasCore::SetEffect(uint32 contextAddr, uint32 drySwitch, uint32 wetSwitch)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
CLog::GetInstance().Print(LOGNAME, "SetEffect(contextAddr = 0x%0.8X, dry = %d, wet = %d);\r\n",
|
||||
contextAddr, drySwitch, wetSwitch);
|
||||
#endif
|
||||
if(drySwitch)
|
||||
{
|
||||
for(unsigned int spuIdx = 0; spuIdx < 2; spuIdx++)
|
||||
{
|
||||
m_spu[spuIdx]->SetControl(Iop::CSpuBase::CONTROL_REVERB);
|
||||
m_spu[spuIdx]->SetChannelReverbLo(0xFFFF);
|
||||
m_spu[spuIdx]->SetChannelReverbHi(0xFFFF);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSasCore::Invoke(uint32 methodId, CMIPS& context)
|
||||
{
|
||||
switch(methodId)
|
||||
@ -411,6 +509,29 @@ void CSasCore::Invoke(uint32 methodId, CMIPS& context)
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = GetEndFlag(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0);
|
||||
break;
|
||||
case 0x33D4AB37:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SetEffectType(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0);
|
||||
break;
|
||||
case 0x267A6DD2:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SetEffectParam(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
context.m_State.nGPR[CMIPS::A2].nV0);
|
||||
break;
|
||||
case 0xD5A229C9:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SetEffectVolume(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
context.m_State.nGPR[CMIPS::A2].nV0);
|
||||
break;
|
||||
case 0xF983B186:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SetEffect(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
context.m_State.nGPR[CMIPS::A2].nV0);
|
||||
break;
|
||||
default:
|
||||
CLog::GetInstance().Print(LOGNAME, "Unknown function called 0x%0.8X\r\n", methodId);
|
||||
break;
|
||||
|
@ -18,6 +18,26 @@ namespace Psp
|
||||
void SetSpuInfo(Iop::CSpuBase*, Iop::CSpuBase*, uint8*, uint32);
|
||||
|
||||
private:
|
||||
enum REVERBTYPES
|
||||
{
|
||||
REVERB_OFF = -1,
|
||||
REVERB_ROOM = 0,
|
||||
REVERB_STUDIOA = 1,
|
||||
REVERB_STUDIOB = 2,
|
||||
REVERB_STUDIOC = 3,
|
||||
REVERB_HALL = 4,
|
||||
REVERB_SPACE = 5,
|
||||
REVERB_ECHO = 6,
|
||||
REVERB_DELAY = 7,
|
||||
REVERB_PIPE = 8
|
||||
};
|
||||
|
||||
struct REVERBINFO
|
||||
{
|
||||
uint32 workAreaSize;
|
||||
uint16 params[Iop::CSpuBase::REVERB_PARAM_COUNT];
|
||||
};
|
||||
|
||||
struct SPUMEMBLOCK
|
||||
{
|
||||
uint32 address;
|
||||
@ -37,12 +57,17 @@ namespace Psp
|
||||
uint32 GetPauseFlag(uint32);
|
||||
uint32 GetEndFlag(uint32);
|
||||
uint32 GetAllEnvelope(uint32, uint32);
|
||||
uint32 SetEffectType(uint32, uint32);
|
||||
uint32 SetEffectParam(uint32, uint32, uint32);
|
||||
uint32 SetEffectVolume(uint32, uint32, uint32);
|
||||
uint32 SetEffect(uint32, uint32, uint32);
|
||||
|
||||
uint32 AllocMemory(uint32);
|
||||
void FreeMemory(uint32);
|
||||
#ifdef _DEBUG
|
||||
void VerifyAllocationMap();
|
||||
#endif
|
||||
void SetupReverb(const REVERBINFO&);
|
||||
|
||||
Iop::CSpuBase::CHANNEL* GetSpuChannel(uint32);
|
||||
|
||||
@ -53,6 +78,9 @@ namespace Psp
|
||||
uint32 m_grain;
|
||||
|
||||
MemBlockList m_blocks;
|
||||
|
||||
static REVERBINFO g_ReverbStudioC;
|
||||
static REVERBINFO g_ReverbSpace;
|
||||
};
|
||||
|
||||
typedef std::tr1::shared_ptr<CSasCore> SasCoreModulePtr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user