Simplify savestate code so it's all automagical.

If you can't beat 'em, join 'em?
This commit is contained in:
Unknown W. Brackets 2013-02-04 01:31:02 -08:00
parent 8f10c7f161
commit a4032c5170
9 changed files with 108 additions and 165 deletions

View file

@ -416,32 +416,9 @@ void MetaFileSystem::DoState(PointerWrap &p)
p.Do(current); p.Do(current);
// Save/load per-thread current directory map // Save/load per-thread current directory map
u32 n = (u32) currentDir.size(); p.Do(currentDir);
p.Do(n);
if (p.mode == p.MODE_READ)
{
std::string dir;
currentDir.clear();
for (u32 i = 0; i < n; ++i)
{
int threadID;
p.Do(threadID);
p.Do(dir);
currentDir[threadID] = dir; int n = (u32) fileSystems.size();
}
}
else
{
currentDir_t::iterator i = currentDir.begin(), end = currentDir.end();
for (; i != end; ++i)
{
p.Do(i->first);
p.Do(i->second);
}
}
n = (u32) fileSystems.size();
p.Do(n); p.Do(n);
if (n != fileSystems.size()) if (n != fileSystems.size())
{ {

View file

@ -79,27 +79,12 @@ void __AtracInit()
} }
void __AtracDoState(PointerWrap &p) { void __AtracDoState(PointerWrap &p) {
int n = (int) atracMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) { if (p.mode == p.MODE_READ) {
for (auto it = atracMap.begin(), end = atracMap.end(); it != end; ++it) { for (auto it = atracMap.begin(), end = atracMap.end(); it != end; ++it) {
delete it->second; delete it->second;
} }
atracMap.clear();
for (int i = 0; i < n; ++i) {
int key;
p.Do(key);
Atrac *atrac = new Atrac;
atrac->DoState(p);
atracMap[key] = atrac;
}
} else {
for (auto it = atracMap.begin(), end = atracMap.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
} }
p.Do(atracMap);
p.DoMarker("sceAtrac"); p.DoMarker("sceAtrac");
} }

View file

@ -28,7 +28,11 @@
const int PSP_MBX_ERROR_DUPLICATE_MSG = 0x800201C9; const int PSP_MBX_ERROR_DUPLICATE_MSG = 0x800201C9;
typedef std::pair<SceUID, u32> MbxWaitingThread; struct MbxWaitingThread
{
SceUID first;
u32 second;
};
void __KernelMbxTimeout(u64 userdata, int cyclesLate); void __KernelMbxTimeout(u64 userdata, int cyclesLate);
static int mbxWaitTimer = -1; static int mbxWaitTimer = -1;
@ -59,14 +63,18 @@ struct Mbx : public KernelObject
{ {
if (__KernelGetThreadPrio(id) < __KernelGetThreadPrio((*it).first)) if (__KernelGetThreadPrio(id) < __KernelGetThreadPrio((*it).first))
{ {
waitingThreads.insert(it, std::make_pair(id, addr)); MbxWaitingThread waiting = {id, addr};
waitingThreads.insert(it, waiting);
inserted = true; inserted = true;
break; break;
} }
} }
} }
if (!inserted) if (!inserted)
waitingThreads.push_back(std::make_pair(id, addr)); {
MbxWaitingThread waiting = {id, addr};
waitingThreads.push_back(waiting);
}
} }
inline void AddInitialMessage(u32 ptr) inline void AddInitialMessage(u32 ptr)
@ -157,7 +165,7 @@ struct Mbx : public KernelObject
virtual void DoState(PointerWrap &p) virtual void DoState(PointerWrap &p)
{ {
p.Do(nmb); p.Do(nmb);
MbxWaitingThread mwt(0,0); MbxWaitingThread mwt = {0};
p.Do(waitingThreads, mwt); p.Do(waitingThreads, mwt);
p.DoMarker("Mbx"); p.DoMarker("Mbx");
} }

View file

@ -198,27 +198,11 @@ public:
} }
void DoState(PointerWrap &p) { void DoState(PointerWrap &p) {
// Gotta delete the calls.
int n = (int) calls_.size();
p.Do(n);
if (p.mode == p.MODE_READ) { if (p.mode == p.MODE_READ) {
clear(); clear();
for (int i = 0; i < n; ++i) {
int k;
p.Do(k);
MipsCall *call = new MipsCall();
call->DoState(p);
calls_[k] = call;
}
} else {
std::map<int, MipsCall *>::iterator it, end;
for (it = calls_.begin(), end = calls_.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
} }
p.Do(calls_);
p.Do(idGen_); p.Do(idGen_);
p.DoMarker("MipsCallManager"); p.DoMarker("MipsCallManager");
} }
@ -631,28 +615,7 @@ void __KernelThreadingDoState(PointerWrap &p)
p.Do(dispatchEnabled); p.Do(dispatchEnabled);
p.Do(curModule); p.Do(curModule);
int n = (int) threadReadyQueue.size(); p.Do(threadReadyQueue);
p.Do(n);
if (p.mode == p.MODE_READ)
{
threadReadyQueue.clear();
for (int i = 0; i < n; ++i)
{
u32 prio;
p.Do(prio);
ThreadList threads;
p.Do(threads, dv);
threadReadyQueue[prio] = threads;
}
}
else
{
for (auto it = threadReadyQueue.begin(), end = threadReadyQueue.end(); it != end; ++it)
{
p.Do(it->first);
p.Do(it->second, dv);
}
}
p.Do(eventScheduledWakeup); p.Do(eventScheduledWakeup);
CoreTiming::RestoreRegisterEvent(eventScheduledWakeup, "ScheduledWakeup", &hleScheduledWakeup); CoreTiming::RestoreRegisterEvent(eventScheduledWakeup, "ScheduledWakeup", &hleScheduledWakeup);

View file

@ -182,7 +182,7 @@ struct MpegContext {
p.Do(ignoreAvc); p.Do(ignoreAvc);
p.Do(isAnalyzed); p.Do(isAnalyzed);
p.Do<StreamInfo>(streamMap); p.Do<StreamInfo>(streamMap);
mediaengine->DoState(p); p.DoClass(mediaengine);
p.DoMarker("MpegContext"); p.DoMarker("MpegContext");
} }
@ -369,31 +369,15 @@ void __MpegDoState(PointerWrap &p) {
p.Do(actionPostPut); p.Do(actionPostPut);
__KernelRestoreActionType(actionPostPut, PostPutAction::Create); __KernelRestoreActionType(actionPostPut, PostPutAction::Create);
int n = (int) mpegMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) { if (p.mode == p.MODE_READ) {
std::map<u32, MpegContext *>::iterator it, end; std::map<u32, MpegContext *>::iterator it, end;
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) { for (auto it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
delete it->second->mediaengine; delete it->second->mediaengine;
delete it->second; delete it->second;
} }
mpegMap.clear(); mpegMap.clear();
for (int i = 0; i < n; ++i) {
u32 key;
p.Do(key);
MpegContext *ctx = new MpegContext;
ctx->mediaengine = new MediaEngine;
ctx->DoState(p);
mpegMap[key] = ctx;
}
} else {
std::map<u32, MpegContext *>::iterator it, end;
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
} }
p.Do(mpegMap);
p.DoMarker("sceMpeg"); p.DoMarker("sceMpeg");
} }

View file

@ -103,6 +103,8 @@ typedef std::map<int, PsmfStream *> PsmfStreamMap;
class Psmf { class Psmf {
public: public:
// For savestates only.
Psmf() {}
Psmf(u32 data); Psmf(u32 data);
~Psmf(); ~Psmf();
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
@ -142,6 +144,8 @@ public:
class PsmfPlayer { class PsmfPlayer {
public: public:
// For savestates only.
PsmfPlayer() {}
PsmfPlayer(u32 data); PsmfPlayer(u32 data);
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
@ -164,6 +168,10 @@ public:
class PsmfStream { class PsmfStream {
public: public:
// Used for save states.
PsmfStream() {
}
PsmfStream(int type, int channel) { PsmfStream(int type, int channel) {
this->type = type; this->type = type;
this->channel = channel; this->channel = channel;
@ -245,10 +253,6 @@ Psmf::~Psmf() {
} }
PsmfPlayer::PsmfPlayer(u32 data) { PsmfPlayer::PsmfPlayer(u32 data) {
// Used for savestates.
if (data == 0) {
return;
}
videoCodec = Memory::Read_U32(data); videoCodec = Memory::Read_U32(data);
videoStreamNum = Memory::Read_U32(data + 4); videoStreamNum = Memory::Read_U32(data + 4);
audioCodec = Memory::Read_U32(data + 8); audioCodec = Memory::Read_U32(data + 8);
@ -282,23 +286,7 @@ void Psmf::DoState(PointerWrap &p) {
p.Do(audioChannels); p.Do(audioChannels);
p.Do(audioFrequency); p.Do(audioFrequency);
int n = (int) streamMap.size(); p.Do(streamMap);
p.Do(n);
if (p.mode == p.MODE_READ) {
// Already empty, if we're reading this is brand new.
for (int i = 0; i < n; ++i) {
int key;
p.Do(key);
PsmfStream *stream = new PsmfStream(0, 0);
stream->DoState(p);
streamMap[key] = stream;
}
} else {
for (auto it = streamMap.begin(), end = streamMap.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
}
p.DoMarker("Psmf"); p.DoMarker("Psmf");
} }
@ -350,58 +338,28 @@ void __PsmfInit()
void __PsmfDoState(PointerWrap &p) void __PsmfDoState(PointerWrap &p)
{ {
int n = (int) psmfMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) { if (p.mode == p.MODE_READ) {
std::map<u32, Psmf *>::iterator it, end; std::map<u32, Psmf *>::iterator it, end;
for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) { for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) {
delete it->second; delete it->second;
} }
psmfMap.clear(); psmfMap.clear();
for (int i = 0; i < n; ++i) {
u32 key;
p.Do(key);
Psmf *psmf = new Psmf(0);
psmf->DoState(p);
psmfMap[key] = psmf;
}
} else {
std::map<u32, Psmf *>::iterator it, end;
for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
} }
p.Do(psmfMap);
p.DoMarker("scePsmf"); p.DoMarker("scePsmf");
} }
void __PsmfPlayerDoState(PointerWrap &p) void __PsmfPlayerDoState(PointerWrap &p)
{ {
int n = (int) psmfPlayerMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) { if (p.mode == p.MODE_READ) {
std::map<u32, PsmfPlayer *>::iterator it, end; std::map<u32, PsmfPlayer *>::iterator it, end;
for (it = psmfPlayerMap.begin(), end = psmfPlayerMap.end(); it != end; ++it) { for (it = psmfPlayerMap.begin(), end = psmfPlayerMap.end(); it != end; ++it) {
delete it->second; delete it->second;
} }
psmfMap.clear(); psmfMap.clear();
for (int i = 0; i < n; ++i) {
u32 key;
p.Do(key);
PsmfPlayer *psmfplayer = new PsmfPlayer(0);
psmfplayer->DoState(p);
psmfPlayerMap[key] = psmfplayer;
}
} else {
std::map<u32, PsmfPlayer *>::iterator it, end;
for (it = psmfPlayerMap.begin(), end = psmfPlayerMap.end(); it != end; ++it) {
p.Do(it->first);
it->second->DoState(p);
}
} }
p.Do(psmfPlayerMap);
// TODO: Actually load this from a map. // TODO: Actually load this from a map.
psmfPlayerStatus = PSMF_PLAYER_STATUS_NONE; psmfPlayerStatus = PSMF_PLAYER_STATUS_NONE;

View file

@ -112,6 +112,25 @@ void VagDecoder::GetSamples(s16 *outSamples, int numSamples) {
} }
} }
void VagDecoder::DoState(PointerWrap &p)
{
p.DoArray(samples, ARRAY_SIZE(samples));
p.Do(curSample);
p.Do(data_);
p.Do(read_);
p.Do(curBlock_);
p.Do(loopStartBlock_);
p.Do(numBlocks_);
p.Do(s_1);
p.Do(s_2);
p.Do(loopEnabled_);
p.Do(loopAtNextBlock_);
p.Do(end_);
}
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/sceSasCore.java // http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/sceSasCore.java
int simpleRate(int n) { int simpleRate(int n) {
@ -418,6 +437,40 @@ void SasVoice::ChangedParams(bool changedVag) {
// TODO: restart VAG somehow // TODO: restart VAG somehow
} }
void SasVoice::DoState(PointerWrap &p)
{
p.Do(playing);
p.Do(paused);
p.Do(on);
p.Do(type);
p.Do(vagAddr);
p.Do(vagSize);
p.Do(pcmAddr);
p.Do(pcmSize);
p.Do(sampleRate);
p.Do(sampleFrac);
p.Do(pitch);
p.Do(loop);
p.Do(noiseFreq);
p.Do(volumeLeft);
p.Do(volumeRight);
p.Do(volumeLeftSend);
p.Do(volumeRightSend);
p.Do(effectLeft);
p.Do(effectRight);
p.DoArray(resampleHist, ARRAY_SIZE(resampleHist));
p.DoMarker("SasVoice");
envelope.DoState(p);
vag.DoState(p);
}
// This is horribly stolen from JPCSP. // This is horribly stolen from JPCSP.
// Need to find a real solution. // Need to find a real solution.
static const short expCurve[] = { static const short expCurve[] = {
@ -583,3 +636,19 @@ void ADSREnvelope::KeyOff() {
SetState(STATE_RELEASE); SetState(STATE_RELEASE);
height_ = sustainLevel; height_ = sustainLevel;
} }
void ADSREnvelope::DoState(PointerWrap &p) {
p.Do(attackRate);
p.Do(decayRate);
p.Do(sustainRate);
p.Do(releaseRate);
p.Do(attackType);
p.Do(decayType);
p.Do(sustainType);
p.Do(sustainLevel);
p.Do(releaseType);
p.Do(state_);
p.Do(steps_);
p.Do(height_);
p.DoMarker("ADSREnvelope");
}

View file

@ -83,6 +83,8 @@ public:
void DecodeBlock(u8 *&readp); void DecodeBlock(u8 *&readp);
bool End() const { return end_; } bool End() const { return end_; }
void DoState(PointerWrap &p);
private: private:
int samples[28]; int samples[28];
int curSample; int curSample;
@ -132,6 +134,8 @@ public:
int sustainLevel; int sustainLevel;
int releaseType; int releaseType;
void DoState(PointerWrap &p);
private: private:
enum ADSRState { enum ADSRState {
STATE_ATTACK, STATE_ATTACK,
@ -175,6 +179,8 @@ struct SasVoice
void KeyOff(); void KeyOff();
void ChangedParams(bool changedVag); void ChangedParams(bool changedVag);
void DoState(PointerWrap &p);
bool playing; bool playing;
bool paused; // a voice can be playing AND paused. In that case, it won't play. bool paused; // a voice can be playing AND paused. In that case, it won't play.
bool on; // key-on, key-off. bool on; // key-on, key-off.

View file

@ -326,14 +326,7 @@ u32 BlockAllocator::GetTotalFreeBytes()
void BlockAllocator::DoState(PointerWrap &p) void BlockAllocator::DoState(PointerWrap &p)
{ {
Block b(0, 0, false); Block b(0, 0, false);
p.Do(blocks, b);
u32 list_size = (u32)blocks.size();
p.Do(list_size);
blocks.resize(list_size, b);
for (auto it = blocks.begin(), end = blocks.end(); it != end; ++it)
it->DoState(p);
p.Do(rangeStart_); p.Do(rangeStart_);
p.Do(rangeSize_); p.Do(rangeSize_);
p.Do(grain_); p.Do(grain_);