Simplify savestate code so it's all automagical.
If you can't beat 'em, join 'em?
This commit is contained in:
parent
8f10c7f161
commit
a4032c5170
9 changed files with 108 additions and 165 deletions
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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_);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue