mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Automatically delete pointers when savestating.
This commit is contained in:
parent
82a8450758
commit
112c1e9e23
8 changed files with 133 additions and 60 deletions
|
@ -109,14 +109,30 @@ public:
|
|||
(*ptr) += size;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::map<unsigned int, T> &x)
|
||||
template<class K, class T>
|
||||
void Do(std::map<K, T *> &x)
|
||||
{
|
||||
Do<unsigned int, T>(x);
|
||||
if (mode == MODE_READ)
|
||||
{
|
||||
for (auto it = x.begin(), end = x.end(); it != end; ++it)
|
||||
{
|
||||
if (it->second != NULL)
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
T *dv = NULL;
|
||||
DoMap(x, dv);
|
||||
}
|
||||
|
||||
template<class K, class T>
|
||||
void Do(std::map<K, T> &x)
|
||||
{
|
||||
T dv;
|
||||
DoMap(x, dv);
|
||||
}
|
||||
|
||||
template<class K, class T>
|
||||
void DoMap(std::map<K, T> &x, T &default_val)
|
||||
{
|
||||
unsigned int number = (unsigned int)x.size();
|
||||
Do(number);
|
||||
|
@ -128,7 +144,7 @@ public:
|
|||
{
|
||||
K first = 0;
|
||||
Do(first);
|
||||
T second;
|
||||
T second = default_val;
|
||||
Do(second);
|
||||
x[first] = second;
|
||||
--number;
|
||||
|
@ -152,8 +168,30 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template<class K, class T>
|
||||
void Do(std::multimap<K, T *> &x)
|
||||
{
|
||||
if (mode == MODE_READ)
|
||||
{
|
||||
for (auto it = x.begin(), end = x.end(); it != end; ++it)
|
||||
{
|
||||
if (it->second != NULL)
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
T *dv = NULL;
|
||||
DoMultimap(x, dv);
|
||||
}
|
||||
|
||||
template<class K, class T>
|
||||
void Do(std::multimap<K, T> &x)
|
||||
{
|
||||
T dv;
|
||||
DoMultimap(x, dv);
|
||||
}
|
||||
|
||||
template<class K, class T>
|
||||
void DoMultimap(std::multimap<K, T> &x, T &default_val)
|
||||
{
|
||||
unsigned int number = (unsigned int)x.size();
|
||||
Do(number);
|
||||
|
@ -165,7 +203,7 @@ public:
|
|||
{
|
||||
K first;
|
||||
Do(first);
|
||||
T second;
|
||||
T second = default_val;
|
||||
Do(second);
|
||||
x.insert(std::make_pair(first, second));
|
||||
--number;
|
||||
|
@ -190,15 +228,28 @@ public:
|
|||
}
|
||||
|
||||
// Store vectors.
|
||||
template<class T>
|
||||
void Do(std::vector<T *> &x)
|
||||
{
|
||||
T *dv = NULL;
|
||||
DoVector(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::vector<T> &x)
|
||||
{
|
||||
T dv;
|
||||
Do(x, dv);
|
||||
DoVector(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::vector<T> &x, T &default_val)
|
||||
{
|
||||
DoVector(x, default_val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DoVector(std::vector<T> &x, T &default_val)
|
||||
{
|
||||
u32 vec_size = (u32)x.size();
|
||||
Do(vec_size);
|
||||
|
@ -208,27 +259,54 @@ public:
|
|||
}
|
||||
|
||||
// Store deques.
|
||||
template<class T>
|
||||
void Do(std::deque<T *> &x)
|
||||
{
|
||||
T *dv = NULL;
|
||||
DoDeque(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::deque<T> &x)
|
||||
{
|
||||
T dv;
|
||||
DoDeque(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DoDeque(std::deque<T> &x, T &default_val)
|
||||
{
|
||||
u32 deq_size = (u32)x.size();
|
||||
Do(deq_size);
|
||||
x.resize(deq_size);
|
||||
x.resize(deq_size, default_val);
|
||||
u32 i;
|
||||
for(i = 0; i < deq_size; i++)
|
||||
DoVoid(&x[i],sizeof(T));
|
||||
Do(x[i]);
|
||||
}
|
||||
|
||||
// Store STL lists.
|
||||
template<class T>
|
||||
void Do(std::list<T> &x)
|
||||
void Do(std::list<T *> &x)
|
||||
{
|
||||
T dv;
|
||||
T *dv = NULL;
|
||||
Do(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::list<T> &x)
|
||||
{
|
||||
T dv;
|
||||
DoList(x, dv);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Do(std::list<T> &x, T &default_val)
|
||||
{
|
||||
DoList(x, default_val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DoList(std::list<T> &x, T &default_val)
|
||||
{
|
||||
u32 list_size = (u32)x.size();
|
||||
Do(list_size);
|
||||
|
@ -240,8 +318,28 @@ public:
|
|||
}
|
||||
|
||||
// Store STL sets.
|
||||
template <class T>
|
||||
void Do(std::set<T *> &x)
|
||||
{
|
||||
if (mode == MODE_READ)
|
||||
{
|
||||
for (auto it = x.begin(), end = x.end(); it != end; ++it)
|
||||
{
|
||||
if (*it != NULL)
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
DoSet(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Do(std::set<T> &x)
|
||||
{
|
||||
DoSet(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void DoSet(std::set<T> &x)
|
||||
{
|
||||
unsigned int number = (unsigned int)x.size();
|
||||
Do(number);
|
||||
|
@ -311,7 +409,11 @@ public:
|
|||
template<class T>
|
||||
void DoClass(T *&x) {
|
||||
if (mode == MODE_READ)
|
||||
{
|
||||
if (x != NULL)
|
||||
delete x;
|
||||
x = new T();
|
||||
}
|
||||
x->DoState(*this);
|
||||
}
|
||||
|
||||
|
|
|
@ -418,9 +418,9 @@ void MetaFileSystem::DoState(PointerWrap &p)
|
|||
// Save/load per-thread current directory map
|
||||
p.Do(currentDir);
|
||||
|
||||
int n = (u32) fileSystems.size();
|
||||
u32 n = (u32) fileSystems.size();
|
||||
p.Do(n);
|
||||
if (n != fileSystems.size())
|
||||
if (n != (u32) fileSystems.size())
|
||||
{
|
||||
ERROR_LOG(FILESYS, "Savestate failure: number of filesystems doesn't match.");
|
||||
return;
|
||||
|
|
|
@ -79,11 +79,6 @@ void __AtracInit()
|
|||
}
|
||||
|
||||
void __AtracDoState(PointerWrap &p) {
|
||||
if (p.mode == p.MODE_READ) {
|
||||
for (auto it = atracMap.begin(), end = atracMap.end(); it != end; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
p.Do(atracMap);
|
||||
|
||||
p.DoMarker("sceAtrac");
|
||||
|
|
|
@ -230,13 +230,7 @@ void __InterruptsDoState(PointerWrap &p)
|
|||
|
||||
intState.DoState(p);
|
||||
PendingInterrupt pi(0, 0);
|
||||
|
||||
u32 list_size = (u32)pendingInterrupts.size();
|
||||
p.Do(list_size);
|
||||
pendingInterrupts.resize(list_size, pi);
|
||||
for (auto it = pendingInterrupts.begin(), end = pendingInterrupts.end(); it != end; ++it)
|
||||
it->DoState(p);
|
||||
|
||||
p.Do(pendingInterrupts, pi);
|
||||
p.Do(interruptsEnabled);
|
||||
p.Do(inInterrupt);
|
||||
p.DoMarker("sceKernelInterrupt");
|
||||
|
|
|
@ -198,10 +198,6 @@ public:
|
|||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
// Gotta delete the calls.
|
||||
if (p.mode == p.MODE_READ) {
|
||||
clear();
|
||||
}
|
||||
p.Do(calls_);
|
||||
p.Do(idGen_);
|
||||
p.DoMarker("MipsCallManager");
|
||||
|
|
|
@ -95,6 +95,13 @@ struct AvcContext {
|
|||
};
|
||||
|
||||
struct Mp3Context {
|
||||
Mp3Context() : mediaengine(NULL) {}
|
||||
~Mp3Context() {
|
||||
if (mediaengine != NULL) {
|
||||
delete mediaengine;
|
||||
}
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
p.Do(mp3StreamStart);
|
||||
p.Do(mp3StreamEnd);
|
||||
|
@ -114,7 +121,7 @@ struct Mp3Context {
|
|||
p.Do(mp3Channels);
|
||||
p.Do(mp3SamplingRate);
|
||||
p.Do(mp3Version);
|
||||
mediaengine->DoState(p);
|
||||
p.DoClass(mediaengine);
|
||||
p.DoMarker("Mp3Context");
|
||||
}
|
||||
|
||||
|
@ -153,6 +160,13 @@ typedef std::map<u32, StreamInfo> StreamInfoMap;
|
|||
|
||||
// Internal structure
|
||||
struct MpegContext {
|
||||
MpegContext() : mediaengine(NULL) {}
|
||||
~MpegContext() {
|
||||
if (mediaengine != NULL) {
|
||||
delete mediaengine;
|
||||
}
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
p.Do(defaultFrameWidth);
|
||||
p.Do(videoFrameCount);
|
||||
|
@ -181,7 +195,7 @@ struct MpegContext {
|
|||
p.Do(ignorePcm);
|
||||
p.Do(ignoreAvc);
|
||||
p.Do(isAnalyzed);
|
||||
p.Do<StreamInfo>(streamMap);
|
||||
p.Do<u32, StreamInfo>(streamMap);
|
||||
p.DoClass(mediaengine);
|
||||
p.DoMarker("MpegContext");
|
||||
}
|
||||
|
@ -369,14 +383,6 @@ void __MpegDoState(PointerWrap &p) {
|
|||
p.Do(actionPostPut);
|
||||
__KernelRestoreActionType(actionPostPut, PostPutAction::Create);
|
||||
|
||||
if (p.mode == p.MODE_READ) {
|
||||
std::map<u32, MpegContext *>::iterator it, end;
|
||||
for (auto it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
|
||||
delete it->second->mediaengine;
|
||||
delete it->second;
|
||||
}
|
||||
mpegMap.clear();
|
||||
}
|
||||
p.Do(mpegMap);
|
||||
|
||||
p.DoMarker("sceMpeg");
|
||||
|
@ -385,7 +391,6 @@ void __MpegDoState(PointerWrap &p) {
|
|||
void __MpegShutdown() {
|
||||
std::map<u32, MpegContext *>::iterator it, end;
|
||||
for (it = mpegMap.begin(), end = mpegMap.end(); it != end; ++it) {
|
||||
delete it->second->mediaengine;
|
||||
delete it->second;
|
||||
}
|
||||
mpegMap.clear();
|
||||
|
@ -480,7 +485,6 @@ int sceMpegDelete(u32 mpeg)
|
|||
|
||||
DEBUG_LOG(HLE, "sceMpegDelete(%08x)", mpeg);
|
||||
|
||||
delete ctx->mediaengine;
|
||||
delete ctx;
|
||||
mpegMap.erase(Memory::Read_U32(mpeg));
|
||||
|
||||
|
@ -549,8 +553,6 @@ u32 sceMpegQueryStreamSize(u32 bufferAddr, u32 sizeAddr)
|
|||
|
||||
AnalyzeMpeg(bufferAddr, &temp);
|
||||
|
||||
delete temp.mediaengine;
|
||||
|
||||
if (temp.mpegMagic != PSMF_MAGIC) {
|
||||
ERROR_LOG(HLE, "sceMpegQueryStreamOffset: Bad PSMF magic");
|
||||
return ERROR_MPEG_INVALID_VALUE;
|
||||
|
|
|
@ -338,13 +338,6 @@ void __PsmfInit()
|
|||
|
||||
void __PsmfDoState(PointerWrap &p)
|
||||
{
|
||||
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();
|
||||
}
|
||||
p.Do(psmfMap);
|
||||
|
||||
p.DoMarker("scePsmf");
|
||||
|
@ -352,13 +345,6 @@ void __PsmfDoState(PointerWrap &p)
|
|||
|
||||
void __PsmfPlayerDoState(PointerWrap &p)
|
||||
{
|
||||
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();
|
||||
}
|
||||
p.Do(psmfPlayerMap);
|
||||
|
||||
// TODO: Actually load this from a map.
|
||||
|
|
|
@ -44,16 +44,14 @@ enum {
|
|||
|
||||
// TODO - allow more than one, associating each with one Core pointer (passed in to all the functions)
|
||||
// No known games use more than one instance of Sas though.
|
||||
SasInstance *sas;
|
||||
static SasInstance *sas = NULL;
|
||||
|
||||
void __SasInit() {
|
||||
sas = new SasInstance();
|
||||
}
|
||||
|
||||
void __SasDoState(PointerWrap &p) {
|
||||
if (sas != NULL) {
|
||||
sas->DoState(p);
|
||||
}
|
||||
p.DoClass(sas);
|
||||
p.DoMarker("sceSas");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue