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);
// Save/load per-thread current directory map
u32 n = (u32) currentDir.size();
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);
p.Do(currentDir);
currentDir[threadID] = dir;
}
}
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();
int n = (u32) fileSystems.size();
p.Do(n);
if (n != fileSystems.size())
{

View file

@ -79,27 +79,12 @@ void __AtracInit()
}
void __AtracDoState(PointerWrap &p) {
int n = (int) atracMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) {
for (auto it = atracMap.begin(), end = atracMap.end(); it != end; ++it) {
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");
}

View file

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

View file

@ -198,27 +198,11 @@ public:
}
void DoState(PointerWrap &p) {
int n = (int) calls_.size();
p.Do(n);
// Gotta delete the calls.
if (p.mode == p.MODE_READ) {
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.DoMarker("MipsCallManager");
}
@ -631,28 +615,7 @@ void __KernelThreadingDoState(PointerWrap &p)
p.Do(dispatchEnabled);
p.Do(curModule);
int n = (int) threadReadyQueue.size();
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(threadReadyQueue);
p.Do(eventScheduledWakeup);
CoreTiming::RestoreRegisterEvent(eventScheduledWakeup, "ScheduledWakeup", &hleScheduledWakeup);

View file

@ -182,7 +182,7 @@ struct MpegContext {
p.Do(ignoreAvc);
p.Do(isAnalyzed);
p.Do<StreamInfo>(streamMap);
mediaengine->DoState(p);
p.DoClass(mediaengine);
p.DoMarker("MpegContext");
}
@ -369,31 +369,15 @@ void __MpegDoState(PointerWrap &p) {
p.Do(actionPostPut);
__KernelRestoreActionType(actionPostPut, PostPutAction::Create);
int n = (int) mpegMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) {
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;
}
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");
}

View file

@ -103,6 +103,8 @@ typedef std::map<int, PsmfStream *> PsmfStreamMap;
class Psmf {
public:
// For savestates only.
Psmf() {}
Psmf(u32 data);
~Psmf();
void DoState(PointerWrap &p);
@ -142,6 +144,8 @@ public:
class PsmfPlayer {
public:
// For savestates only.
PsmfPlayer() {}
PsmfPlayer(u32 data);
void DoState(PointerWrap &p);
@ -164,6 +168,10 @@ public:
class PsmfStream {
public:
// Used for save states.
PsmfStream() {
}
PsmfStream(int type, int channel) {
this->type = type;
this->channel = channel;
@ -245,10 +253,6 @@ Psmf::~Psmf() {
}
PsmfPlayer::PsmfPlayer(u32 data) {
// Used for savestates.
if (data == 0) {
return;
}
videoCodec = Memory::Read_U32(data);
videoStreamNum = Memory::Read_U32(data + 4);
audioCodec = Memory::Read_U32(data + 8);
@ -282,23 +286,7 @@ void Psmf::DoState(PointerWrap &p) {
p.Do(audioChannels);
p.Do(audioFrequency);
int n = (int) streamMap.size();
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.Do(streamMap);
p.DoMarker("Psmf");
}
@ -350,58 +338,28 @@ void __PsmfInit()
void __PsmfDoState(PointerWrap &p)
{
int n = (int) psmfMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) {
std::map<u32, Psmf *>::iterator it, end;
for (it = psmfMap.begin(), end = psmfMap.end(); it != end; ++it) {
delete it->second;
}
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");
}
void __PsmfPlayerDoState(PointerWrap &p)
{
int n = (int) psmfPlayerMap.size();
p.Do(n);
if (p.mode == p.MODE_READ) {
std::map<u32, PsmfPlayer *>::iterator it, end;
for (it = psmfPlayerMap.begin(), end = psmfPlayerMap.end(); it != end; ++it) {
delete it->second;
}
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.
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
int simpleRate(int n) {
@ -418,6 +437,40 @@ void SasVoice::ChangedParams(bool changedVag) {
// 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.
// Need to find a real solution.
static const short expCurve[] = {
@ -583,3 +636,19 @@ void ADSREnvelope::KeyOff() {
SetState(STATE_RELEASE);
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);
bool End() const { return end_; }
void DoState(PointerWrap &p);
private:
int samples[28];
int curSample;
@ -132,6 +134,8 @@ public:
int sustainLevel;
int releaseType;
void DoState(PointerWrap &p);
private:
enum ADSRState {
STATE_ATTACK,
@ -175,6 +179,8 @@ struct SasVoice
void KeyOff();
void ChangedParams(bool changedVag);
void DoState(PointerWrap &p);
bool playing;
bool paused; // a voice can be playing AND paused. In that case, it won't play.
bool on; // key-on, key-off.

View file

@ -326,14 +326,7 @@ u32 BlockAllocator::GetTotalFreeBytes()
void BlockAllocator::DoState(PointerWrap &p)
{
Block b(0, 0, false);
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(blocks, b);
p.Do(rangeStart_);
p.Do(rangeSize_);
p.Do(grain_);