Revamp SPU saved states.

This commit is contained in:
Jean-Philip Desjardins 2023-12-08 14:49:27 -05:00
parent f65f6f240b
commit 691a44d9d8
4 changed files with 111 additions and 111 deletions

View file

@ -5,7 +5,8 @@
#include <algorithm> #include <algorithm>
#include "string_format.h" #include "string_format.h"
#include "../Log.h" #include "../Log.h"
#include "../states/RegisterStateFile.h" #include "../states/RegisterStateCollectionFile.h"
#include "../states/RegisterStateUtils.h"
#include "Iop_SpuBase.h" #include "Iop_SpuBase.h"
using namespace Iop; using namespace Iop;
@ -16,6 +17,8 @@ using namespace Iop;
#define LOG_NAME ("iop_spubase") #define LOG_NAME ("iop_spubase")
#define STATE_PATH_FORMAT ("iop_spu/spu_%d.xml") #define STATE_PATH_FORMAT ("iop_spu/spu_%d.xml")
#define STATE_REGS ("GlobalRegs")
#define STATE_REGS_CTRL ("CTRL") #define STATE_REGS_CTRL ("CTRL")
#define STATE_REGS_IRQADDR ("IRQADDR") #define STATE_REGS_IRQADDR ("IRQADDR")
#define STATE_REGS_TRANSFERADDR ("TRANSFERADDR") #define STATE_REGS_TRANSFERADDR ("TRANSFERADDR")
@ -28,7 +31,7 @@ using namespace Iop;
#define STATE_REGS_REVERBCURRADDR ("REVERBCURRADDR") #define STATE_REGS_REVERBCURRADDR ("REVERBCURRADDR")
#define STATE_REGS_REVERB_FORMAT ("REVERB%d") #define STATE_REGS_REVERB_FORMAT ("REVERB%d")
#define STATE_CHANNEL_REGS_PREFIX ("CHANNEL%02d_") #define STATE_CHANNEL_REGS_FORMAT ("Channel%02dRegs")
#define STATE_CHANNEL_REGS_VOLUMELEFT ("VOLUMELEFT") #define STATE_CHANNEL_REGS_VOLUMELEFT ("VOLUMELEFT")
#define STATE_CHANNEL_REGS_VOLUMERIGHT ("VOLUMERIGHT") #define STATE_CHANNEL_REGS_VOLUMERIGHT ("VOLUMERIGHT")
#define STATE_CHANNEL_REGS_VOLUMELEFTABS ("VOLUMELEFTABS") #define STATE_CHANNEL_REGS_VOLUMELEFTABS ("VOLUMELEFTABS")
@ -56,7 +59,7 @@ using namespace Iop;
#define STATE_SAMPLEREADER_REGS_ENDFLAG ("EndFlag") #define STATE_SAMPLEREADER_REGS_ENDFLAG ("EndFlag")
#define STATE_SAMPLEREADER_REGS_IRQPENDING ("IrqPending") #define STATE_SAMPLEREADER_REGS_IRQPENDING ("IrqPending")
#define STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT ("DidChangeRepeat") #define STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT ("DidChangeRepeat")
#define STATE_SAMPLEREADER_REGS_BUFFER_FORMAT ("%sBuffer%d") #define STATE_SAMPLEREADER_REGS_BUFFER_FORMAT ("Buffer%d")
// clang-format off // clang-format off
bool CSpuBase::g_reverbParamIsAddress[REVERB_PARAM_COUNT] = bool CSpuBase::g_reverbParamIsAddress[REVERB_PARAM_COUNT] =
@ -212,93 +215,94 @@ void CSpuBase::Reset()
void CSpuBase::LoadState(Framework::CZipArchiveReader& archive) void CSpuBase::LoadState(Framework::CZipArchiveReader& archive)
{ {
auto path = string_format(STATE_PATH_FORMAT, m_spuNumber); auto path = string_format(STATE_PATH_FORMAT, m_spuNumber);
auto stateCollectionFile = CRegisterStateCollectionFile(*archive.BeginReadFile(path.c_str()));
auto registerFile = CRegisterStateFile(*archive.BeginReadFile(path.c_str()));
m_ctrl = registerFile.GetRegister32(STATE_REGS_CTRL);
m_irqAddr = registerFile.GetRegister32(STATE_REGS_IRQADDR);
m_transferMode = registerFile.GetRegister32(STATE_REGS_TRANSFERMODE);
m_transferAddr = registerFile.GetRegister32(STATE_REGS_TRANSFERADDR);
m_core0OutputOffset = registerFile.GetRegister32(STATE_REGS_CORE0OUTPUTOFFSET);
m_channelOn.f = registerFile.GetRegister32(STATE_REGS_CHANNELON);
m_channelReverb.f = registerFile.GetRegister32(STATE_REGS_CHANNELREVERB);
m_reverbWorkAddrStart = registerFile.GetRegister32(STATE_REGS_REVERBWORKADDRSTART);
m_reverbWorkAddrEnd = registerFile.GetRegister32(STATE_REGS_REVERBWORKADDREND);
m_reverbCurrAddr = registerFile.GetRegister32(STATE_REGS_REVERBCURRADDR);
static const uint32 reverbRegisterCount = sizeof(m_reverb) / (sizeof(uint128));
for(uint32 i = 0; i < reverbRegisterCount; i++)
{ {
auto reverbRegisterName = string_format(STATE_REGS_REVERB_FORMAT, i); const auto& state = stateCollectionFile.GetRegisterState(STATE_REGS);
reinterpret_cast<uint128*>(m_reverb)[i] = registerFile.GetRegister128(reverbRegisterName.c_str()); m_ctrl = state.GetRegister32(STATE_REGS_CTRL);
m_irqAddr = state.GetRegister32(STATE_REGS_IRQADDR);
m_transferMode = state.GetRegister32(STATE_REGS_TRANSFERMODE);
m_transferAddr = state.GetRegister32(STATE_REGS_TRANSFERADDR);
m_core0OutputOffset = state.GetRegister32(STATE_REGS_CORE0OUTPUTOFFSET);
m_channelOn.f = state.GetRegister32(STATE_REGS_CHANNELON);
m_channelReverb.f = state.GetRegister32(STATE_REGS_CHANNELREVERB);
m_reverbWorkAddrStart = state.GetRegister32(STATE_REGS_REVERBWORKADDRSTART);
m_reverbWorkAddrEnd = state.GetRegister32(STATE_REGS_REVERBWORKADDREND);
m_reverbCurrAddr = state.GetRegister32(STATE_REGS_REVERBCURRADDR);
RegisterStateUtils::ReadArray(state, m_reverb, STATE_REGS_REVERB_FORMAT);
} }
for(unsigned int i = 0; i < MAX_CHANNEL; i++) for(unsigned int i = 0; i < MAX_CHANNEL; i++)
{ {
auto& channel = m_channel[i]; auto& channel = m_channel[i];
auto& reader = m_reader[i]; auto& reader = m_reader[i];
auto channelPrefix = string_format(STATE_CHANNEL_REGS_PREFIX, i);
channel.volumeLeft <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFT).c_str()); auto channelRegsName = string_format(STATE_CHANNEL_REGS_FORMAT, i);
channel.volumeRight <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHT).c_str()); const auto& channelState = stateCollectionFile.GetRegisterState(channelRegsName.c_str());
channel.volumeLeftAbs = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFTABS).c_str());
channel.volumeRightAbs = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHTABS).c_str()); channel.volumeLeft <<= channelState.GetRegister32(STATE_CHANNEL_REGS_VOLUMELEFT);
channel.status = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_STATUS).c_str()); channel.volumeRight <<= channelState.GetRegister32(STATE_CHANNEL_REGS_VOLUMERIGHT);
channel.pitch = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_PITCH).c_str()); channel.volumeLeftAbs = channelState.GetRegister32(STATE_CHANNEL_REGS_VOLUMELEFTABS);
channel.adsrLevel <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRLEVEL).c_str()); channel.volumeRightAbs = channelState.GetRegister32(STATE_CHANNEL_REGS_VOLUMERIGHTABS);
channel.adsrRate <<= registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRRATE).c_str()); channel.status = channelState.GetRegister32(STATE_CHANNEL_REGS_STATUS);
channel.adsrVolume = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRVOLUME).c_str()); channel.pitch = channelState.GetRegister32(STATE_CHANNEL_REGS_PITCH);
channel.address = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADDRESS).c_str()); channel.adsrLevel <<= channelState.GetRegister32(STATE_CHANNEL_REGS_ADSRLEVEL);
channel.repeat = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEAT).c_str()); channel.adsrRate <<= channelState.GetRegister32(STATE_CHANNEL_REGS_ADSRRATE);
channel.repeatSet = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEATSET).c_str()) != 0; channel.adsrVolume = channelState.GetRegister32(STATE_CHANNEL_REGS_ADSRVOLUME);
channel.current = registerFile.GetRegister32((channelPrefix + STATE_CHANNEL_REGS_CURRENT).c_str()); channel.address = channelState.GetRegister32(STATE_CHANNEL_REGS_ADDRESS);
reader.LoadState(registerFile, channelPrefix); channel.repeat = channelState.GetRegister32(STATE_CHANNEL_REGS_REPEAT);
channel.repeatSet = channelState.GetRegister32(STATE_CHANNEL_REGS_REPEATSET) != 0;
channel.current = channelState.GetRegister32(STATE_CHANNEL_REGS_CURRENT);
reader.LoadState(channelState);
} }
} }
void CSpuBase::SaveState(Framework::CZipArchiveWriter& archive) void CSpuBase::SaveState(Framework::CZipArchiveWriter& archive)
{ {
auto path = string_format(STATE_PATH_FORMAT, m_spuNumber); auto path = string_format(STATE_PATH_FORMAT, m_spuNumber);
auto stateCollectionFile = std::make_unique<CRegisterStateCollectionFile>(path.c_str());
auto registerFile = std::make_unique<CRegisterStateFile>(path.c_str());
registerFile->SetRegister32(STATE_REGS_CTRL, m_ctrl);
registerFile->SetRegister32(STATE_REGS_IRQADDR, m_irqAddr);
registerFile->SetRegister32(STATE_REGS_TRANSFERMODE, m_transferMode);
registerFile->SetRegister32(STATE_REGS_TRANSFERADDR, m_transferAddr);
registerFile->SetRegister32(STATE_REGS_CORE0OUTPUTOFFSET, m_core0OutputOffset);
registerFile->SetRegister32(STATE_REGS_CHANNELON, m_channelOn.f);
registerFile->SetRegister32(STATE_REGS_CHANNELREVERB, m_channelReverb.f);
registerFile->SetRegister32(STATE_REGS_REVERBWORKADDRSTART, m_reverbWorkAddrStart);
registerFile->SetRegister32(STATE_REGS_REVERBWORKADDREND, m_reverbWorkAddrEnd);
registerFile->SetRegister32(STATE_REGS_REVERBCURRADDR, m_reverbCurrAddr);
static const uint32 reverbRegisterCount = sizeof(m_reverb) / (sizeof(uint128));
for(uint32 i = 0; i < reverbRegisterCount; i++)
{ {
auto reverbRegisterName = string_format(STATE_REGS_REVERB_FORMAT, i); CRegisterState state;
registerFile->SetRegister128(reverbRegisterName.c_str(), reinterpret_cast<const uint128*>(m_reverb)[i]); state.SetRegister32(STATE_REGS_CTRL, m_ctrl);
state.SetRegister32(STATE_REGS_IRQADDR, m_irqAddr);
state.SetRegister32(STATE_REGS_TRANSFERMODE, m_transferMode);
state.SetRegister32(STATE_REGS_TRANSFERADDR, m_transferAddr);
state.SetRegister32(STATE_REGS_CORE0OUTPUTOFFSET, m_core0OutputOffset);
state.SetRegister32(STATE_REGS_CHANNELON, m_channelOn.f);
state.SetRegister32(STATE_REGS_CHANNELREVERB, m_channelReverb.f);
state.SetRegister32(STATE_REGS_REVERBWORKADDRSTART, m_reverbWorkAddrStart);
state.SetRegister32(STATE_REGS_REVERBWORKADDREND, m_reverbWorkAddrEnd);
state.SetRegister32(STATE_REGS_REVERBCURRADDR, m_reverbCurrAddr);
RegisterStateUtils::WriteArray(state, m_reverb, STATE_REGS_REVERB_FORMAT);
stateCollectionFile->InsertRegisterState(STATE_REGS, std::move(state));
} }
for(unsigned int i = 0; i < MAX_CHANNEL; i++) for(unsigned int i = 0; i < MAX_CHANNEL; i++)
{ {
const auto& channel = m_channel[i]; const auto& channel = m_channel[i];
const auto& reader = m_reader[i]; const auto& reader = m_reader[i];
auto channelPrefix = string_format(STATE_CHANNEL_REGS_PREFIX, i); CRegisterState channelState;
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFT).c_str(), channel.volumeLeft); channelState.SetRegister32(STATE_CHANNEL_REGS_VOLUMELEFT, channel.volumeLeft);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHT).c_str(), channel.volumeRight); channelState.SetRegister32(STATE_CHANNEL_REGS_VOLUMERIGHT, channel.volumeRight);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMELEFTABS).c_str(), channel.volumeLeftAbs); channelState.SetRegister32(STATE_CHANNEL_REGS_VOLUMELEFTABS, channel.volumeLeftAbs);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_VOLUMERIGHTABS).c_str(), channel.volumeRightAbs); channelState.SetRegister32(STATE_CHANNEL_REGS_VOLUMERIGHTABS, channel.volumeRightAbs);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_STATUS).c_str(), channel.status); channelState.SetRegister32(STATE_CHANNEL_REGS_STATUS, channel.status);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_PITCH).c_str(), channel.pitch); channelState.SetRegister32(STATE_CHANNEL_REGS_PITCH, channel.pitch);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRLEVEL).c_str(), channel.adsrLevel); channelState.SetRegister32(STATE_CHANNEL_REGS_ADSRLEVEL, channel.adsrLevel);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRRATE).c_str(), channel.adsrRate); channelState.SetRegister32(STATE_CHANNEL_REGS_ADSRRATE, channel.adsrRate);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADSRVOLUME).c_str(), channel.adsrVolume); channelState.SetRegister32(STATE_CHANNEL_REGS_ADSRVOLUME, channel.adsrVolume);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_ADDRESS).c_str(), channel.address); channelState.SetRegister32(STATE_CHANNEL_REGS_ADDRESS, channel.address);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEAT).c_str(), channel.repeat); channelState.SetRegister32(STATE_CHANNEL_REGS_REPEAT, channel.repeat);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_REPEATSET).c_str(), channel.repeatSet); channelState.SetRegister32(STATE_CHANNEL_REGS_REPEATSET, channel.repeatSet);
registerFile->SetRegister32((channelPrefix + STATE_CHANNEL_REGS_CURRENT).c_str(), channel.current); channelState.SetRegister32(STATE_CHANNEL_REGS_CURRENT, channel.current);
reader.SaveState(registerFile.get(), channelPrefix); reader.SaveState(channelState);
auto channelRegsName = string_format(STATE_CHANNEL_REGS_FORMAT, i);
stateCollectionFile->InsertRegisterState(channelRegsName.c_str(), std::move(channelState));
} }
archive.InsertFile(std::move(registerFile)); archive.InsertFile(std::move(stateCollectionFile));
} }
bool CSpuBase::IsEnabled() const bool CSpuBase::IsEnabled() const
@ -1168,54 +1172,42 @@ void CSpuBase::CSampleReader::SetDestinationSamplingRate(uint32 samplingRate)
UpdateSampleStep(); UpdateSampleStep();
} }
void CSpuBase::CSampleReader::LoadState(const CRegisterStateFile& registerFile, const std::string& channelPrefix) void CSpuBase::CSampleReader::LoadState(const CRegisterState& channelState)
{ {
m_srcSampleIdx = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX).c_str()); m_srcSampleIdx = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX);
m_srcSamplingRate = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE).c_str()); m_srcSamplingRate = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE);
m_nextSampleAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR).c_str()); m_nextSampleAddr = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR);
m_repeatAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_REPEATADDR).c_str()); m_repeatAddr = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_REPEATADDR);
m_irqAddr = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQADDR).c_str()); m_irqAddr = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_IRQADDR);
m_pitch = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_PITCH).c_str()); m_pitch = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_PITCH);
m_s1 = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S1).c_str()); m_s1 = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_S1);
m_s2 = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S2).c_str()); m_s2 = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_S2);
m_done = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DONE).c_str()) != 0; m_done = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_DONE) != 0;
m_nextValid = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTVALID).c_str()) != 0; m_nextValid = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_NEXTVALID) != 0;
m_endFlag = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_ENDFLAG).c_str()) != 0; m_endFlag = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_ENDFLAG) != 0;
m_irqPending = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQPENDING).c_str()) != 0; m_irqPending = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_IRQPENDING) != 0;
m_didChangeRepeat = registerFile.GetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT).c_str()) != 0; m_didChangeRepeat = channelState.GetRegister32(STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT) != 0;
RegisterStateUtils::ReadArray(channelState, m_buffer, STATE_SAMPLEREADER_REGS_BUFFER_FORMAT);
static const uint32 bufferRegisterCount = sizeof(m_buffer) / (sizeof(uint128));
for(uint32 i = 0; i < bufferRegisterCount; i++)
{
auto bufferRegisterName = string_format(STATE_SAMPLEREADER_REGS_BUFFER_FORMAT, channelPrefix.c_str(), i);
reinterpret_cast<uint128*>(m_buffer)[i] = registerFile.GetRegister128(bufferRegisterName.c_str());
}
UpdateSampleStep(); UpdateSampleStep();
} }
void CSpuBase::CSampleReader::SaveState(CRegisterStateFile* registerFile, const std::string& channelPrefix) const void CSpuBase::CSampleReader::SaveState(CRegisterState& channelState) const
{ {
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX).c_str(), m_srcSampleIdx); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_SRCSAMPLEIDX, m_srcSampleIdx);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE).c_str(), m_srcSamplingRate); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_SRCSAMPLINGRATE, m_srcSamplingRate);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR).c_str(), m_nextSampleAddr); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_NEXTSAMPLEADDR, m_nextSampleAddr);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_REPEATADDR).c_str(), m_repeatAddr); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_REPEATADDR, m_repeatAddr);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQADDR).c_str(), m_irqAddr); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_IRQADDR, m_irqAddr);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_PITCH).c_str(), m_pitch); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_PITCH, m_pitch);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S1).c_str(), m_s1); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_S1, m_s1);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_S2).c_str(), m_s2); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_S2, m_s2);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DONE).c_str(), m_done); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_DONE, m_done);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_NEXTVALID).c_str(), m_nextValid); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_NEXTVALID, m_nextValid);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_ENDFLAG).c_str(), m_endFlag); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_ENDFLAG, m_endFlag);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_IRQPENDING).c_str(), m_irqPending); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_IRQPENDING, m_irqPending);
registerFile->SetRegister32((channelPrefix + STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT).c_str(), m_didChangeRepeat); channelState.SetRegister32(STATE_SAMPLEREADER_REGS_DIDCHANGEREPEAT, m_didChangeRepeat);
RegisterStateUtils::WriteArray(channelState, m_buffer, STATE_SAMPLEREADER_REGS_BUFFER_FORMAT);
static const uint32 bufferRegisterCount = sizeof(m_buffer) / (sizeof(uint128));
for(uint32 i = 0; i < bufferRegisterCount; i++)
{
auto bufferRegisterName = string_format(STATE_SAMPLEREADER_REGS_BUFFER_FORMAT, channelPrefix.c_str(), i);
registerFile->SetRegister128(bufferRegisterName.c_str(), reinterpret_cast<const uint128*>(m_buffer)[i]);
}
} }
void CSpuBase::CSampleReader::SetParams(uint32 address, uint32 repeat) void CSpuBase::CSampleReader::SetParams(uint32 address, uint32 repeat)

View file

@ -7,7 +7,7 @@
#include "zip/ZipArchiveWriter.h" #include "zip/ZipArchiveWriter.h"
#include "zip/ZipArchiveReader.h" #include "zip/ZipArchiveReader.h"
class CRegisterStateFile; class CRegisterState;
namespace Iop namespace Iop
{ {
@ -279,8 +279,8 @@ namespace Iop
void SetSampleCache(CSpuSampleCache*); void SetSampleCache(CSpuSampleCache*);
void SetDestinationSamplingRate(uint32); void SetDestinationSamplingRate(uint32);
void LoadState(const CRegisterStateFile&, const std::string&); void LoadState(const CRegisterState&);
void SaveState(CRegisterStateFile*, const std::string&) const; void SaveState(CRegisterState&) const;
void SetParamsRead(uint32, uint32); void SetParamsRead(uint32, uint32);
void SetParamsNoRead(uint32, uint32); void SetParamsNoRead(uint32, uint32);

View file

@ -31,6 +31,12 @@ CRegisterStateCollectionFile::RegisterStateIterator CRegisterStateCollectionFile
return std::end(m_registerStates); return std::end(m_registerStates);
} }
const CRegisterState& CRegisterStateCollectionFile::GetRegisterState(const char* name)
{
assert(m_registerStates.find(name) != std::end(m_registerStates));
return m_registerStates[name];
}
void CRegisterStateCollectionFile::InsertRegisterState(const char* name, CRegisterState registerState) void CRegisterStateCollectionFile::InsertRegisterState(const char* name, CRegisterState registerState)
{ {
m_registerStates[name] = std::move(registerState); m_registerStates[name] = std::move(registerState);

View file

@ -14,7 +14,9 @@ public:
CRegisterStateCollectionFile(Framework::CStream&); CRegisterStateCollectionFile(Framework::CStream&);
virtual ~CRegisterStateCollectionFile() = default; virtual ~CRegisterStateCollectionFile() = default;
const CRegisterState& GetRegisterState(const char*);
void InsertRegisterState(const char*, CRegisterState); void InsertRegisterState(const char*, CRegisterState);
void Read(Framework::CStream&); void Read(Framework::CStream&);
void Write(Framework::CStream&) override; void Write(Framework::CStream&) override;