diff --git a/Common/ChunkFile.h b/Common/ChunkFile.h index c6dd5d6de0..f6e3f0a0ce 100644 --- a/Common/ChunkFile.h +++ b/Common/ChunkFile.h @@ -158,7 +158,8 @@ public: u32 vec_size = (u32)x.size(); Do(vec_size); x.resize(vec_size); - DoArray(&x[0], vec_size); + if (vec_size > 0) + DoArray(&x[0], vec_size); } // Store deques. diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 31b9bbb0ad..504d28fb5b 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -550,7 +550,7 @@ void Event_DoState(PointerWrap &p, BaseEvent *ev) void DoState(PointerWrap &p) { - size_t n = event_types.size(); + int n = (int) event_types.size(); p.Do(n); // These (should) be filled in later by the modules. event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 51dbcc7979..e57be86eb2 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -546,3 +546,8 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { return myVector; } +void DirectoryFileSystem::DoState(PointerWrap &p) { + if (!entries.empty()) { + ERROR_LOG(FILESYS, "FIXME: Open files during savestate, could go badly."); + } +} diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index e3f4bf0acc..6cb334fc53 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -53,6 +53,7 @@ public: DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath); ~DirectoryFileSystem(); + void DoState(PointerWrap &p); std::vector GetDirListing(std::string path); u32 OpenFile(std::string filename, FileAccess access); void CloseFile(u32 handle); diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index d14854803e..4d8670effd 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -90,6 +90,7 @@ class IFileSystem public: virtual ~IFileSystem() {} + virtual void DoState(PointerWrap &p) = 0; virtual std::vector GetDirListing(std::string path) = 0; virtual u32 OpenFile(std::string filename, FileAccess access) = 0; virtual void CloseFile(u32 handle) = 0; @@ -108,6 +109,7 @@ public: class EmptyFileSystem : public IFileSystem { public: + virtual void DoState(PointerWrap &p) {} std::vector GetDirListing(std::string path) {std::vector vec; return vec;} u32 OpenFile(std::string filename, FileAccess access) {return 0;} void CloseFile(u32 handle) {} diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index a7e7bf01f6..712a10e953 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -131,6 +131,7 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic entireISO.size = _blockDevice->GetNumBlocks() * _blockDevice->GetBlockSize(); entireISO.isBlockSectorMode = true; entireISO.flags = 0; + entireISO.parent = NULL; if (!memcmp(desc.cd001, "CD001", 5)) { @@ -142,6 +143,7 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic } treeroot = new TreeEntry; + treeroot->parent = NULL; u32 rootSector = desc.root.firstDataSectorLE; u32 rootSize = desc.root.dataLengthLE; @@ -211,6 +213,7 @@ nextblock: e->isDirectory = !isFile; e->flags = dir.flags; e->isBlockSectorMode = false; + e->parent = root; // Let's not excessively spam the log - I commented this line out. //DEBUG_LOG(FILESYS, "%s: %s %08x %08x %i", e->isDirectory?"D":"F", name, dir.firstDataSectorLE, e->startingPosition, e->startingPosition); @@ -540,3 +543,70 @@ std::vector ISOFileSystem::GetDirListing(std::string path) } return myVector; } + +std::string ISOFileSystem::EntryFullPath(TreeEntry *e) +{ + size_t fullLen = 0; + TreeEntry *cur = e; + while (cur != NULL && cur != treeroot) + { + // For the "/". + fullLen += 1 + cur->name.size(); + cur = cur->parent; + } + + std::string path; + path.resize(fullLen); + + cur = e; + while (cur != NULL && cur != treeroot) + { + path.replace(fullLen - cur->name.size(), cur->name.size(), cur->name); + path.replace(fullLen - cur->name.size() - 1, 1, "/"); + fullLen -= 1 + cur->name.size(); + cur = cur->parent; + } + + return path; +} + +void ISOFileSystem::DoState(PointerWrap &p) +{ + int n = (int) entries.size(); + p.Do(n); + + if (p.mode == p.MODE_READ) + { + entries.clear(); + for (int i = 0; i < n; ++i) + { + u32 fd; + p.Do(fd); + std::string path; + p.Do(path); + OpenFileEntry of; + of.file = path.empty() ? NULL : GetFromPath(path); + p.Do(of.seekPos); + p.Do(of.isRawSector); + p.Do(of.sectorStart); + p.Do(of.openSize); + entries[fd] = of; + } + } + else + { + for (EntryMap::iterator it = entries.begin(), end = entries.end(); it != end; ++it) + { + p.Do(it->first); + std::string path = ""; + if (it->second.file != NULL) + path = EntryFullPath(it->second.file); + p.Do(path); + p.Do(it->second.seekPos); + p.Do(it->second.isRawSector); + p.Do(it->second.sectorStart); + p.Do(it->second.openSize); + } + } + p.DoMarker("ISOFileSystem"); +} diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 61f30016f1..96e88e0710 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -42,8 +42,9 @@ class ISOFileSystem : public IFileSystem u32 startingPosition; s64 size; bool isDirectory; - bool isBlockSectorMode; // "umd:" mode: all sizes and offsets are in 2048 byte chunks + bool isBlockSectorMode; // "umd:" mode: all sizes and offsets are in 2048 byte chunks + TreeEntry *parent; std::vector children; }; @@ -67,10 +68,12 @@ class ISOFileSystem : public IFileSystem void ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root); TreeEntry *GetFromPath(std::string path); + std::string EntryFullPath(TreeEntry *e); public: ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice); ~ISOFileSystem(); + void DoState(PointerWrap &p); std::vector GetDirListing(std::string path); u32 OpenFile(std::string filename, FileAccess access); void CloseFile(u32 handle); diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index ed18b31a07..58ae33fae1 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -367,3 +367,22 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type) return 0; } +void MetaFileSystem::DoState(PointerWrap &p) +{ + p.Do(current); + p.Do(currentDirectory); + + int n = (int) fileSystems.size(); + p.Do(n); + if (n != fileSystems.size()) + { + ERROR_LOG(FILESYS, "Savestate failure: number of filesystems doesn't match."); + return; + } + + for (int i = 0; i < n; ++i) + fileSystems[i].system->DoState(p); + + p.DoMarker("MetaFileSystem"); +} + diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index b0b63d9b97..7fd0a96db2 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -36,6 +36,8 @@ public: u32 GetNewHandle() {return current++;} void FreeHandle(u32 handle) {} + virtual void DoState(PointerWrap &p); + IFileSystem *GetHandleOwner(u32 handle); bool MapFilePath(const std::string &inpath, std::string &outpath, IFileSystem **system); diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index f58a2aca4f..7d5c426c49 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -58,6 +58,12 @@ void HLEInit() RegisterAllModules(); } +void HLEDoState(PointerWrap &p) +{ + p.Do(unresolvedSyscalls); + p.DoMarker("HLE"); +} + void HLEShutdown() { hleAfterSyscall = HLE_AFTER_NOTHING; diff --git a/Core/HLE/HLE.h b/Core/HLE/HLE.h index 09d5fc75cd..8ff39c328c 100644 --- a/Core/HLE/HLE.h +++ b/Core/HLE/HLE.h @@ -87,6 +87,7 @@ void hleRunInterrupts(); void hleDebugBreak(); void HLEInit(); +void HLEDoState(PointerWrap &p); void HLEShutdown(); u32 GetNibByName(const char *module, const char *function); u32 GetSyscallOp(const char *module, u32 nib); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 801b4bf917..70af694f7b 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -853,8 +853,10 @@ public: p.Do(name); // TODO: Is this the right way for it to wake up? - size_t count = listing.size(); - for (size_t i = 0; i < count; ++i) { + int count = listing.size(); + p.Do(count); + listing.resize(count); + for (int i = 0; i < count; ++i) { listing[i].DoState(p); } p.DoMarker("DirListing"); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index ecb1bef957..7c8c9d2544 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -168,13 +168,13 @@ public: return; } - size_t n = subIntrHandlers.size(); + int n = (int) subIntrHandlers.size(); p.Do(n); if (p.mode == p.MODE_READ) { clear(); - for (size_t i = 0; i < n; ++i) + for (int i = 0; i < n; ++i) { int subIntrNum; p.Do(subIntrNum); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 9cfecf7874..7732c558ce 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -222,12 +222,12 @@ public: void DoState(PointerWrap &p) { - size_t n = (int) calls_.size(); + int n = (int) calls_.size(); p.Do(n); if (p.mode == p.MODE_READ) { clear(); - for (size_t i = 0; i < n; ++i) { + for (int i = 0; i < n; ++i) { int k; p.Do(k); MipsCall *call = new MipsCall(); diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 69ba1a517c..35f91ce900 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -21,10 +21,12 @@ #include "SaveState.h" #include "Core.h" #include "CoreTiming.h" +#include "HLE/HLE.h" #include "HLE/sceKernel.h" #include "HW/MemoryStick.h" #include "MemMap.h" #include "MIPS/MIPS.h" +#include "System.h" namespace SaveState { @@ -72,8 +74,9 @@ namespace SaveState Memory::DoState(p); MemoryStick_DoState(p); currentMIPS->DoState(p); + pspFileSystem.DoState(p); + HLEDoState(p); __KernelDoState(p); - // TODO: filesystem, HLE? } void Enqueue(SaveState::Operation op)