git-svn-id: http://svn.purei.org/purei/trunk@358 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2008-08-08 21:52:31 +00:00
parent dd971b2500
commit dd30744575
5 changed files with 152 additions and 12 deletions

View File

@ -6,7 +6,8 @@
using namespace Framework;
using namespace Psx;
int main(int argc, char** argv)
//int main(int argc, char** argv)
int WINAPI WinMain(HINSTANCE, HINSTANCE, char*, int)
{
CPsxVm virtualMachine;

View File

@ -135,6 +135,7 @@ void CSpu::Render(int16* samples, unsigned int sampleCount, unsigned int sampleR
{
reader.SetParams(m_ram + (channel.address * 8), m_ram + (channel.repeat * 8));
channel.status = ATTACK;
channel.adsrVolume = 0;
}
reader.SetPitch(channel.pitch);
reader.GetSamples(bufferTemp, ticks, sampleRate);
@ -143,11 +144,13 @@ void CSpu::Render(int16* samples, unsigned int sampleCount, unsigned int sampleR
for(unsigned int j = 0; j < ticks; j++)
{
if(channel.status == STOPPED) break;
if(channel.status == RELEASE)
{
channel.status = STOPPED;
}
UpdateAdsr(channel);
int32 inputSample = static_cast<int32>(bufferTemp[j]);
//Mix adsrVolume
{
int64 result = (static_cast<int64>(inputSample) * static_cast<int64>(channel.adsrVolume)) / static_cast<int64>(MAX_ADSR_VOLUME);
inputSample = static_cast<int32>(result);
}
struct SampleMixer
{
void operator() (int32 inputSample, const CHANNEL_VOLUME& volume, int16*& output) const
@ -386,6 +389,111 @@ void CSpu::DisassembleWrite(uint32 address, uint16 value)
}
}
uint32 CSpu::GetAdsrDelta(unsigned int index) const
{
return m_adsrLogTable[index + 32];
}
void CSpu::UpdateAdsr(CHANNEL& channel)
{
static unsigned int logIndex[8] = { 0, 4, 6, 8, 9, 10, 11, 12 };
int64 currentAdsrLevel = channel.adsrVolume;
if(channel.status == ATTACK)
{
if(channel.adsrLevel.attackMode == 0)
{
//Linear mode
currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x10);
}
else
{
if(currentAdsrLevel < 0x60000000)
{
currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x10);
}
else
{
currentAdsrLevel += GetAdsrDelta((channel.adsrLevel.attackRate ^ 0x7F) - 0x18);
}
}
//Terminasion condition
if(currentAdsrLevel >= MAX_ADSR_VOLUME)
{
channel.status = DECAY;
}
}
else if(channel.status == DECAY)
{
unsigned int decayType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrLevel.decayRate ^ 0x1F)) - 0x18 + logIndex[decayType]);
//Terminasion condition
if(((currentAdsrLevel >> 27) & 0xF) <= channel.adsrLevel.sustainLevel)
{
channel.status = SUSTAIN;
}
}
else if(channel.status == SUSTAIN)
{
if(channel.adsrRate.sustainDirection == 0)
{
//Increment
if(channel.adsrRate.sustainMode == 0)
{
currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x10);
}
else
{
if(currentAdsrLevel < 0x60000000)
{
currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x10);
}
else
{
currentAdsrLevel += GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x18);
}
}
}
else
{
//Decrement
if(channel.adsrRate.sustainMode == 0)
{
//Linear
currentAdsrLevel -= GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x0F);
}
else
{
unsigned int sustainType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
currentAdsrLevel -= GetAdsrDelta((channel.adsrRate.sustainRate ^ 0x7F) - 0x1B + logIndex[sustainType]);
}
}
}
else if(channel.status == RELEASE)
{
if(channel.adsrRate.releaseMode == 0)
{
//Linear
currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrRate.releaseRate ^ 0x1F)) - 0x0C);
}
else
{
unsigned int releaseType = (static_cast<uint32>(currentAdsrLevel) >> 28) & 0x7;
currentAdsrLevel -= GetAdsrDelta((4 * (channel.adsrRate.releaseRate ^ 0x1F)) - 0x18 + logIndex[releaseType]);
}
if(currentAdsrLevel <= 0)
{
channel.status = STOPPED;
}
}
currentAdsrLevel = min<int64>(currentAdsrLevel, MAX_ADSR_VOLUME);
currentAdsrLevel = max<int64>(currentAdsrLevel, 0);
channel.adsrVolume = static_cast<uint32>(currentAdsrLevel);
}
///////////////////////////////////////////////////////
// CSampleReader
///////////////////////////////////////////////////////
CSpu::CSampleReader::CSampleReader() :
m_nextSample(NULL)

View File

@ -64,7 +64,7 @@ public:
uint16 address;
ADSR_LEVEL adsrLevel;
ADSR_RATE adsrRate;
int32 adsrVolume;
uint32 adsrVolume;
uint16 repeat;
uint16 status;
};
@ -225,12 +225,20 @@ private:
RAMSIZE = 0x80000
};
enum
{
MAX_ADSR_VOLUME = 0x7FFFFFFF,
};
void SendKeyOn(uint32);
void SendKeyOff(uint32);
void DisassembleRead(uint32);
void DisassembleWrite(uint32, uint16);
void UpdateAdsr(CHANNEL&);
uint32 GetAdsrDelta(unsigned int) const;
uint32 m_bufferAddr;
uint16 m_ctrl;
uint16 m_status0;

View File

@ -17,13 +17,14 @@ CSpuRegView::~CSpuRegView()
void CSpuRegView::Render()
{
string text;
char channelStatus[CSpu::MAX_CHANNEL + 1];
//Header
text += " VLEFT VRIGH PITCH ADDRE ADSRL ADSRR ADSRV REPEA\r\n";
text += "\r\n";
//Channel detail
for(unsigned int i = 0; i < 24; i++)
for(unsigned int i = 0; i < CSpu::MAX_CHANNEL; i++)
{
CSpu::CHANNEL& channel(m_spu.GetChannel(i));
uint32 address = CSpu::CH0_BASE + (i * 0x10);
@ -39,11 +40,33 @@ void CSpuRegView::Render()
channel.adsrVolume >> 16,
channel.repeat);
text += temp;
char status = '0';
switch(channel.status)
{
case CSpu::ATTACK:
case CSpu::KEY_ON:
status = 'A';
break;
case CSpu::DECAY:
status = 'D';
break;
case CSpu::SUSTAIN:
status = 'S';
break;
case CSpu::RELEASE:
status = 'R';
break;
}
channelStatus[i] = status;
}
channelStatus[CSpu::MAX_CHANNEL] = 0;
text += "\r\n";
char temp[256];
sprintf(temp, "CH_ON: 0x%0.8X VO_ON 0x%0.8X\r\n", m_spu.GetChannelOn(), m_spu.GetVoiceOn());
sprintf(temp, "CH_ON: 0x%0.8X CH_STAT: %s\r\n", m_spu.GetChannelOn(), channelStatus);
text += temp;
SetDisplayText(text.c_str());

View File

@ -41,7 +41,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer\Source"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_MSVC"
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_MSVC"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -65,7 +65,7 @@
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\libs\Win32&quot;;C:\Components\boost_1_35_0\stage\lib"
GenerateDebugInformation="true"
SubSystem="1"
SubSystem="2"
TargetMachine="1"
/>
<Tool
@ -119,7 +119,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer\Source"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_MSVC"
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_MSVC"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
@ -141,7 +141,7 @@
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\libs\Win32&quot;;C:\Components\boost_1_35_0\stage\lib"
GenerateDebugInformation="true"
SubSystem="1"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"