From 0f9d27ae12e3aaf51004903ced1067b619147ae6 Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sun, 16 Jul 2023 12:56:32 -0400 Subject: [PATCH 1/9] Parity with ChrisNonyminus:Cemu:savestates; Add SS menu; Move SS func to CafeSystem --- src/Cafe/CafeSystem.cpp | 95 +++++++++++++++ src/Cafe/CafeSystem.h | 6 + src/Cafe/Filesystem/fsc.cpp | 58 ++++++++++ src/Cafe/Filesystem/fsc.h | 8 ++ src/Cafe/Filesystem/fscDeviceHostFS.cpp | 16 +++ src/Cafe/Filesystem/fscDeviceHostFS.h | 3 + src/Cafe/Filesystem/fscDeviceWua.cpp | 5 + src/Cafe/Filesystem/fscDeviceWud.cpp | 5 + src/Cafe/HW/MMU/MMU.cpp | 89 +++++++++++++++ src/Cafe/HW/MMU/MMU.h | 20 +++- src/Cafe/IOSU/fsa/iosu_fsa.cpp | 108 ++++++++++++++++++ src/Cafe/IOSU/fsa/iosu_fsa.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_FS.cpp | 10 ++ src/Cafe/OS/libs/coreinit/coreinit_FS.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 59 ++++++++++ src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 3 + src/gui/MainWindow.cpp | 46 ++++++++ src/gui/MainWindow.h | 7 ++ src/util/helpers/Serializer.cpp | 34 ++++++ 19 files changed, 573 insertions(+), 5 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 8ca86adf..3ebc86a7 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -68,6 +68,8 @@ // dependency to be removed #include "gui/guiWrapper.h" +#include "Cafe/OS/libs/coreinit/coreinit_FS.h" + std::string _pathToExecutable; std::string _pathToBaseExecutable; @@ -792,6 +794,99 @@ namespace CafeSystem sSystemRunning = false; } + void PauseTitle() + { + if (!sSystemRunning) + return; + coreinit::SuspendAllThreads(); + sSystemRunning = false; + } + + void ResumeTitle(bool* runningThreads) + { + if (sSystemRunning) + return; + + coreinit::ResumeAllThreads(runningThreads); + sSystemRunning = true; + } + + void SaveState(std::string path) + { + cemuLog_log(LogType::Force, "[SAVESTATE] Saving state..."); + MemStreamWriter writer(0); + // pause game + PauseTitle(); + // memory + memory_Serialize(writer); + // gpu + writer.writeData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); + writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); + writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); + // cpu + auto threads = coreinit::GetAllThreads(); + for (auto& thr : threads) + { + writer.writeBE(thr != nullptr); + if (thr != nullptr) + writer.writeData(thr, sizeof(OSThread_t)); + } + for (auto& thr : activeThread) + { + writer.writeBE(thr); + } + // fs + coreinit::FSSave(writer); + iosu::fsa::Save(writer); + + FileStream* stream = FileStream::createFile(path); + stream->writeData(writer.getResult().data(), writer.getResult().size_bytes()); + delete stream; + cemuLog_log(LogType::Force, "[SAVESTATE] Saved state to {}.", path); + ResumeTitle(/*isThreadRunning*/); + } + + void LoadState(std::string path) + { + PauseTitle(); + cemuLog_log(LogType::Force, "[SAVESTATE] Loading state...", path); + + auto data = FileStream::LoadIntoMemory(path); + assert(data.has_value()); + MemStreamReader reader(data->data(), data->size()); + // memory + memory_Deserialize(reader); + // gpu + reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); + reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); + reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); + // cpu + auto threads = coreinit::GetAllThreads(); + for (auto& thr : threads) + { + bool notnull = reader.readBE(); + if (notnull) + { + if (!thr) + { + thr = new OSThread_t; + } + reader.readData(thr, sizeof(OSThread_t)); + } + } + for (size_t i = 0; i < 256; i++) + { + activeThread[i] = reader.readBE(); + } + // fs + coreinit::FSRestore(reader); + iosu::fsa::Restore(reader); + + cemuLog_log(LogType::Force, "[SAVESTATE] Loaded state from {}.", path); + + ResumeTitle(/*isThreadRunning*/); + } + /* Virtual mlc storage */ void InitVirtualMlcStorage() diff --git a/src/Cafe/CafeSystem.h b/src/Cafe/CafeSystem.h index 236cf44a..8be2355d 100644 --- a/src/Cafe/CafeSystem.h +++ b/src/Cafe/CafeSystem.h @@ -30,6 +30,12 @@ namespace CafeSystem void ShutdownTitle(); + void PauseTitle(); + void ResumeTitle(bool* runningThreads = nullptr); + + void SaveState(std::string path); + void LoadState(std::string path); + std::string GetMlcStoragePath(TitleId titleId); void MlcStorageMountAllTitles(); diff --git a/src/Cafe/Filesystem/fsc.cpp b/src/Cafe/Filesystem/fsc.cpp index b2500667..ec53673d 100644 --- a/src/Cafe/Filesystem/fsc.cpp +++ b/src/Cafe/Filesystem/fsc.cpp @@ -269,6 +269,8 @@ FSCMountPathNode* fsc_lookupPathVirtualNode(const char* path, sint32 priority) class FSCVirtualFileDirectoryIterator : public FSCVirtualFile { public: + void Save(MemStreamWriter& writer) override; + sint32 fscGetType() override { return FSC_TYPE_DIRECTORY; @@ -717,3 +719,59 @@ void fsc_init() { fsc_reset(); } + +void FSCVirtualFile::Save(MemStreamWriter& writer) +{ + writer.writeBE(dirIterator != nullptr); + if (dirIterator) writer.writeBE(*dirIterator); +} +#include "Cafe/Filesystem/fscDeviceHostFS.h" + +FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) +{ + FSCVirtualFile* file; + switch ((Child)reader.readBE()) + { + case Child::DIRECTORY_ITERATOR: + { + std::string path = reader.readBE(); + std::vector folders{}; + size_t size = reader.readBE(); + for (size_t i = 0; i < size; i++) + { + folders.push_back(Restore(reader)); + } + file = new FSCVirtualFileDirectoryIterator(path, folders); + break; + } + case Child::HOST: + { + std::string path = reader.readBE(); + FSC_ACCESS_FLAG flags = (FSC_ACCESS_FLAG)reader.readBE(); + sint32 status{}; + file = FSCVirtualFile_Host::OpenFile(path, flags, status); + file->fscSetSeek(reader.readBE()); + break; + } + default: + throw std::exception("Not implemented"); + } + if (reader.readBE()) + { + file->dirIterator = new FSCDirIteratorState; + *file->dirIterator = reader.readBE(); + } + return file; +} + +void FSCVirtualFileDirectoryIterator::Save(MemStreamWriter& writer) +{ + writer.writeBE((uint32)Child::DIRECTORY_ITERATOR); + writer.writeBE(m_path); + writer.writeBE(m_folders.size()); + for (auto& folder : m_folders) + { + folder->Save(writer); + } + FSCVirtualFile::Save(writer); +} \ No newline at end of file diff --git a/src/Cafe/Filesystem/fsc.h b/src/Cafe/Filesystem/fsc.h index 2854a301..b9ef6f84 100644 --- a/src/Cafe/Filesystem/fsc.h +++ b/src/Cafe/Filesystem/fsc.h @@ -89,12 +89,20 @@ public: struct FSCVirtualFile { + enum class Child : uint32 + { + DIRECTORY_ITERATOR, HOST, WUACTX, WUDCTX, NONE + }; + struct FSCDirIteratorState { sint32 index; std::vector dirEntries; }; + virtual void Save(MemStreamWriter& writer); + static FSCVirtualFile* Restore(MemStreamReader& reader); + FSCVirtualFile() { diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.cpp b/src/Cafe/Filesystem/fscDeviceHostFS.cpp index f63d2920..2e1954d9 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.cpp +++ b/src/Cafe/Filesystem/fscDeviceHostFS.cpp @@ -157,6 +157,19 @@ bool FSCVirtualFile_Host::fscDirNext(FSCDirEntry* dirEntry) return true; } +void FSCVirtualFile_Host::Save(MemStreamWriter& writer) +{ + writer.writeBE((uint32)Child::HOST); + + writer.writeBE(m_path->string()); + writer.writeBE((uint32)m_accessFlags); + + writer.writeBE(m_seek); + + FSCVirtualFile::Save(writer); +} + + FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus) { if (!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && !HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)) @@ -191,9 +204,11 @@ FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_F if (fs) { FSCVirtualFile_Host* vf = new FSCVirtualFile_Host(FSC_TYPE_FILE); + vf->m_path.reset(new std::filesystem::path(path)); vf->m_fs = fs; vf->m_isWritable = writeAccessRequested; vf->m_fileSize = fs->GetSize(); + vf->m_accessFlags = accessFlags; fscStatus = FSC_STATUS_OK; return vf; } @@ -208,6 +223,7 @@ FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_F { FSCVirtualFile_Host* vf = new FSCVirtualFile_Host(FSC_TYPE_DIRECTORY); vf->m_path.reset(new std::filesystem::path(path)); + vf->m_accessFlags = accessFlags; fscStatus = FSC_STATUS_OK; return vf; } diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.h b/src/Cafe/Filesystem/fscDeviceHostFS.h index 7121594c..6daab151 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.h +++ b/src/Cafe/Filesystem/fscDeviceHostFS.h @@ -3,6 +3,7 @@ class FSCVirtualFile_Host : public FSCVirtualFile { public: + void Save(MemStreamWriter& writer) override; static FSCVirtualFile* OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus); ~FSCVirtualFile_Host() override; @@ -31,4 +32,6 @@ private: // directory std::unique_ptr m_path{}; std::unique_ptr m_dirIterator{}; + // serialization + FSC_ACCESS_FLAG m_accessFlags; }; \ No newline at end of file diff --git a/src/Cafe/Filesystem/fscDeviceWua.cpp b/src/Cafe/Filesystem/fscDeviceWua.cpp index f9014bdb..5bea3715 100644 --- a/src/Cafe/Filesystem/fscDeviceWua.cpp +++ b/src/Cafe/Filesystem/fscDeviceWua.cpp @@ -15,6 +15,11 @@ protected: }; public: + void Save(MemStreamWriter& writer) override + { + throw std::exception("Not implemented"); + } + sint32 fscGetType() override { return m_fscType; diff --git a/src/Cafe/Filesystem/fscDeviceWud.cpp b/src/Cafe/Filesystem/fscDeviceWud.cpp index bf43bf3e..70d9b5c9 100644 --- a/src/Cafe/Filesystem/fscDeviceWud.cpp +++ b/src/Cafe/Filesystem/fscDeviceWud.cpp @@ -22,6 +22,11 @@ protected: } public: + void Save(MemStreamWriter& writer) override + { + throw std::exception("Not implemented"); + } + sint32 fscGetType() override { return m_fscType; diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 1a776d6b..e6b47838 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -80,6 +80,66 @@ MMURange* memory_getMMURangeByAddress(MPTR address) return nullptr; } +bool MMURange::serializeImpl(MemStreamWriter& streamWriter) +{ + streamWriter.writeBE(this->m_isMapped); + if (m_isMapped) + { + streamWriter.writeBE(this->baseAddress); + streamWriter.writeBE((uint8)this->areaId); + streamWriter.writeBE((uint8)this->flags); + streamWriter.writeBE(this->name); + streamWriter.writeBE(this->size); + streamWriter.writeBE(this->initSize); + } + return true; +} + +template<> +void MemStreamWriter::writeBE(const MMURange& v) +{ + writeBE(v.m_isMapped); + writeBE(v.baseAddress); + writeBE((uint8)v.areaId); + writeBE((uint8)v.flags); + writeBE(v.name); + writeBE(v.size); + writeBE(v.initSize); +} + +template <> +MMURange MemStreamReader::readBE() +{ + bool mapped = readBE(); + uint32 base = readBE(); + MMU_MEM_AREA_ID areaid = (MMU_MEM_AREA_ID)readBE(); + MMURange::MFLAG flags = (MMURange::MFLAG)readBE(); + std::string name = readBE(); + uint32 size = readBE(); + uint32 initsize = readBE(); + MMURange range(base, size, areaid, name, flags); + if (mapped) + range.mapMem(); + return range; +} + +bool MMURange::deserializeImpl(MemStreamReader& streamReader) +{ + m_isMapped = streamReader.readBE(); + if (m_isMapped) + { + baseAddress = streamReader.readBE(); + areaId = (MMU_MEM_AREA_ID)streamReader.readBE(); + this->flags = (MFLAG)streamReader.readBE(); + this->name = streamReader.readBE(); + this->size = streamReader.readBE(); + this->initSize = streamReader.readBE(); + m_isMapped = false; + mapMem(); + } + return true; +} + MMURange::MMURange(const uint32 baseAddress, const uint32 size, MMU_MEM_AREA_ID areaId, const std::string_view name, MFLAG flags) : baseAddress(baseAddress), size(size), initSize(size), areaId(areaId), name(name), flags(flags) { g_mmuRanges.emplace_back(this); @@ -403,6 +463,35 @@ void memory_createDump() } } +void memory_Serialize(MemStreamWriter& s) +{ + s.writeBE(g_mmuRanges.size()); + for (auto& itr : g_mmuRanges) + { + s.writeBE(*itr); + if (itr->isMapped()) + { + s.writeData(memory_base + itr->getBase(), itr->getSize()); + } + } +} + +void memory_Deserialize(MemStreamReader& s) +{ + g_mmuRanges.clear(); + size_t cnt = s.readBE(); + for (size_t i = 0; i < cnt; i++) + { + auto range = s.readBE(); + bool mapped = range.isMapped(); + if (mapped) + { + s.readData(memory_base + range.getBase(), range.getSize()); + } + g_mmuRanges.push_back(std::move(&range)); + } +} + namespace MMU { // MMIO access handler diff --git a/src/Cafe/HW/MMU/MMU.h b/src/Cafe/HW/MMU/MMU.h index 222e8c0e..d03307a9 100644 --- a/src/Cafe/HW/MMU/MMU.h +++ b/src/Cafe/HW/MMU/MMU.h @@ -1,5 +1,7 @@ #pragma once +#include "util/helpers/Serializer.h" + void memory_init(); void memory_mapForCurrentTitle(); void memory_logModifiedMemoryRanges(); @@ -48,6 +50,9 @@ struct MMURange FLAG_MAP_EARLY = (1 << 1), // map at Cemu launch, normally memory is mapped when a game is loaded }; + bool serializeImpl(MemStreamWriter& streamWriter); + bool deserializeImpl(MemStreamReader& streamReader); + MMURange(const uint32 baseAddress, const uint32 size, MMU_MEM_AREA_ID areaId, const std::string_view name, MFLAG flags = (MFLAG)0); void mapMem(); @@ -107,14 +112,16 @@ struct MMURange bool isOptional() const { return (flags & MFLAG::FLAG_OPTIONAL) != 0; }; bool isMappedEarly() const { return (flags & MFLAG::FLAG_MAP_EARLY) != 0; }; - const uint32 baseAddress; - const uint32 initSize; // initial size - const std::string name; - const MFLAG flags; - const MMU_MEM_AREA_ID areaId; + uint32 baseAddress; + uint32 initSize; // initial size + std::string name; + MFLAG flags; + MMU_MEM_AREA_ID areaId; // runtime parameters uint32 size; bool m_isMapped{}; + friend class MemStreamWriter; + friend class MemStreamReader; }; @@ -202,6 +209,9 @@ uint8 memory_readU8(uint32 address); void memory_createDump(); +void memory_Serialize(MemStreamWriter& s); +void memory_Deserialize(MemStreamReader& s); + template void memory_readBytes(VAddr address, std::array& buffer) { diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index 1429d083..e2cf8988 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -169,6 +169,8 @@ namespace iosu } class _FSAHandleTable { + friend class MemStreamWriter; + friend class MemStreamReader; struct _FSAHandleResource { bool isAllocated{false}; @@ -904,3 +906,109 @@ namespace iosu } } // namespace fsa } // namespace iosu + +template <> +void MemStreamWriter::writeBE(const FSCDirEntry& v); +template <> +FSCDirEntry MemStreamReader::readBE(); +template <> +FSCVirtualFile::FSCDirIteratorState MemStreamReader::readBE(); +template <> +void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v); + +template <> +void MemStreamWriter::writeBE(const iosu::fsa::_FSAHandleTable& v) +{ + writeBE(v.m_currentCounter); + for (int i = 0; i < 0x3C0; i++) + { + writeBE(v.m_handleTable[i].handleCheckValue); + writeBE(v.m_handleTable[i].isAllocated); + writeBE(v.m_handleTable[i].fscFile != nullptr); + if (v.m_handleTable[i].fscFile != nullptr) v.m_handleTable[i].fscFile->Save(*this); + } +} + +template <> +iosu::fsa::_FSAHandleTable MemStreamReader::readBE() +{ + iosu::fsa::_FSAHandleTable table{}; + table.m_currentCounter = readBE(); + for (int i = 0; i < 0x3C0; i++) + { + table.m_handleTable[i].handleCheckValue = readBE(); + table.m_handleTable[i].isAllocated = readBE(); + if (readBE()) table.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); + } + return table; +} + +template <> +void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v) +{ + writeBE(v.index); + writeBE(v.dirEntries.size()); + for (int i = 0; i < v.dirEntries.size(); i++) + { + writeBE(v.dirEntries[i]); + } +} + +template <> +void MemStreamWriter::writeBE(const FSCDirEntry& v) +{ + writeData(v.path, FSC_MAX_DIR_NAME_LENGTH); + writeBE(v.isDirectory); + writeBE(v.isFile); + writeBE(v.fileSize); +} + +template <> +FSCDirEntry MemStreamReader::readBE() +{ + FSCDirEntry entry{}; + readData(entry.path, FSC_MAX_DIR_NAME_LENGTH); + entry.isDirectory = readBE(); + entry.isFile = readBE(); + entry.fileSize = readBE(); + return entry; +} + +template <> +FSCVirtualFile::FSCDirIteratorState MemStreamReader::readBE() +{ + FSCVirtualFile::FSCDirIteratorState state{}; + state.index = readBE(); + size_t size = readBE(); + for (size_t i = 0; i < size; i++) + { + state.dirEntries[i] = readBE(); + } + return state; +} + +namespace iosu::fsa +{ + + void Save(MemStreamWriter& writer) + { + writer.writeBE(sFSAIoMsgQueue); + for (size_t i = 0; i < 352; i++) + { + writer.writeBE(_m_sFSAIoMsgQueueMsgBuffer[i]); + } + writer.writeBE(sDirHandleTable); + writer.writeBE(sFileHandleTable); + } + + void Restore(MemStreamReader& reader) + { + sFSAIoMsgQueue = reader.readBE(); + for (size_t i = 0; i < 352; i++) + { + _m_sFSAIoMsgQueueMsgBuffer[i] = reader.readBE(); + } + sDirHandleTable = reader.readBE<_FSAHandleTable>(); + sFileHandleTable = reader.readBE<_FSAHandleTable>(); + } +} \ No newline at end of file diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.h b/src/Cafe/IOSU/fsa/iosu_fsa.h index 8181a4a8..d5fb2118 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.h +++ b/src/Cafe/IOSU/fsa/iosu_fsa.h @@ -213,5 +213,8 @@ namespace iosu void Initialize(); void Shutdown(); + + void Save(MemStreamWriter& writer); + void Restore(MemStreamReader& reader); } // namespace fsa } // namespace iosu diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp index 26636eae..70c047a4 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp @@ -2638,6 +2638,16 @@ namespace coreinit return FSA_RESULT::OK; } + void FSSave(MemStreamWriter& s) + { + s.writeData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + } + + void FSRestore(MemStreamReader& s) + { + s.readData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + } + void InitializeFS() { cafeExportRegister("coreinit", FSInit, LogType::CoreinitFile); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.h b/src/Cafe/OS/libs/coreinit/coreinit_FS.h index 0355c9aa..6a0bf9b3 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.h @@ -308,5 +308,8 @@ namespace coreinit FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient); + void FSSave(MemStreamWriter& s); + void FSRestore(MemStreamReader& s); + void InitializeFS(); }; // namespace coreinit diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index b97f896e..ab82175b 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -198,6 +198,65 @@ namespace coreinit return __currentCoreThread[currentInstance->spr.UPIR]; } + void SuspendAllThreads() + { + for (auto& thr : activeThread) + { + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); + if (thr != 0) + { + OSSuspendThread(ptr); + } + } + if (__currentCoreThread[0]) + OSSuspendThread(__currentCoreThread[0]); + if (__currentCoreThread[1]) + OSSuspendThread(__currentCoreThread[1]); + if (__currentCoreThread[2]) + OSSuspendThread(__currentCoreThread[2]); + + } + + void ResumeAllThreads(bool* runningThreads) + { + for (auto& thr : activeThread) + { + int i = 0; + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); + if (thr != 0) + { + if (runningThreads && runningThreads[i]) + { + if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) + __OSCreateHostThread(ptr); + OSResumeThread(ptr); + } + else if (!runningThreads) + { + if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) + __OSCreateHostThread(ptr); + OSResumeThread(ptr); + } + } + i++; + } + if (__currentCoreThread[0]) + OSResumeThread(__currentCoreThread[0]); + if (__currentCoreThread[1]) + OSResumeThread(__currentCoreThread[1]); + if (__currentCoreThread[2]) + OSResumeThread(__currentCoreThread[2]); + } + + std::vector GetAllThreads() + { + auto ret = std::vector(); + ret.push_back(__currentCoreThread[0]); + ret.push_back(__currentCoreThread[1]); + ret.push_back(__currentCoreThread[2]); + return ret; + } + MPTR funcPtr_threadEntry = 0; void threadEntry(PPCInterpreter_t* hCPU) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index 7c1e618b..d04b8ee4 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -524,6 +524,9 @@ namespace coreinit sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount); sint32 OSResumeThread(OSThread_t* thread); + void SuspendAllThreads(); + void ResumeAllThreads(bool* runningThreads); + std::vector GetAllThreads(); void OSContinueThread(OSThread_t* thread); void __OSSuspendThreadInternal(OSThread_t* thread); void __OSSuspendThreadNolock(OSThread_t* thread); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 142d5ef3..33b4b7d6 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -83,6 +83,8 @@ enum MAINFRAME_MENU_ID_FILE_LOAD = 20100, MAINFRAME_MENU_ID_FILE_INSTALL_UPDATE, MAINFRAME_MENU_ID_FILE_OPEN_CEMU_FOLDER, + MAINFRAME_MENU_ID_FILE_SAVESTATE, + MAINFRAME_MENU_ID_FILE_LOADSTATE, MAINFRAME_MENU_ID_FILE_EXIT, MAINFRAME_MENU_ID_FILE_END_EMULATION, MAINFRAME_MENU_ID_FILE_RECENT_0, @@ -131,6 +133,13 @@ enum MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE = 21000, MAINFRAME_MENU_ID_NFC_RECENT_0, MAINFRAME_MENU_ID_NFC_RECENT_LAST = MAINFRAME_MENU_ID_NFC_RECENT_0 + 15, + + // savestates + MAINFRAME_MENU_ID_SAVESTATES_PAUSE_TITLE, + MAINFRAME_MENU_ID_SAVESTATES_RESUME_TITLE, + MAINFRAME_MENU_ID_SAVESTATES_SAVE_STATE, + MAINFRAME_MENU_ID_SAVESTATES_LOAD_STATE, + // debug MAINFRAME_MENU_ID_DEBUG_RENDER_UPSIDE_DOWN = 21100, MAINFRAME_MENU_ID_DEBUG_VIEW_LOGGING_WINDOW, @@ -174,6 +183,7 @@ EVT_MOVE(MainWindow::OnMove) EVT_MENU(MAINFRAME_MENU_ID_FILE_LOAD, MainWindow::OnFileMenu) EVT_MENU(MAINFRAME_MENU_ID_FILE_INSTALL_UPDATE, MainWindow::OnInstallUpdate) EVT_MENU(MAINFRAME_MENU_ID_FILE_OPEN_CEMU_FOLDER, MainWindow::OnOpenCemuFolder) + EVT_MENU(MAINFRAME_MENU_ID_FILE_EXIT, MainWindow::OnFileExit) EVT_MENU(MAINFRAME_MENU_ID_FILE_END_EMULATION, MainWindow::OnFileMenu) EVT_MENU_RANGE(MAINFRAME_MENU_ID_FILE_RECENT_0 + 0, MAINFRAME_MENU_ID_FILE_RECENT_LAST, MainWindow::OnFileMenu) @@ -204,6 +214,11 @@ EVT_MENU(MAINFRAME_MENU_ID_TIMER_SPEED_0125X, MainWindow::OnDebugSetting) // nfc menu EVT_MENU(MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE, MainWindow::OnNFCMenu) EVT_MENU_RANGE(MAINFRAME_MENU_ID_NFC_RECENT_0 + 0, MAINFRAME_MENU_ID_NFC_RECENT_LAST, MainWindow::OnNFCMenu) +// savestates menu +EVT_MENU(MAINFRAME_MENU_ID_SAVESTATES_PAUSE_TITLE, MainWindow::OnSavestatesMenu) +EVT_MENU(MAINFRAME_MENU_ID_SAVESTATES_RESUME_TITLE, MainWindow::OnSavestatesMenu) +EVT_MENU(MAINFRAME_MENU_ID_SAVESTATES_SAVE_STATE, MainWindow::OnSavestatesMenu) +EVT_MENU(MAINFRAME_MENU_ID_SAVESTATES_LOAD_STATE, MainWindow::OnSavestatesMenu) // debug -> logging menu EVT_MENU_RANGE(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 0, MAINFRAME_MENU_ID_DEBUG_LOGGING0 + 98, MainWindow::OnDebugLoggingToggleFlagGeneric) EVT_MENU(MAINFRAME_MENU_ID_DEBUG_ADVANCED_PPC_INFO, MainWindow::OnPPCInfoToggle) @@ -778,6 +793,27 @@ void MainWindow::OnNFCMenu(wxCommandEvent& event) } } +void MainWindow::OnSavestatesMenu(wxCommandEvent& event) +{ + const auto menuId = event.GetId(); + if (menuId == MAINFRAME_MENU_ID_SAVESTATES_PAUSE_TITLE) + { + CafeSystem::PauseTitle(); + } + if (menuId == MAINFRAME_MENU_ID_SAVESTATES_RESUME_TITLE) + { + CafeSystem::ResumeTitle(); + } + else if (menuId == MAINFRAME_MENU_ID_SAVESTATES_SAVE_STATE) + { + CafeSystem::SaveState("state.bin"); + } + else if (menuId == MAINFRAME_MENU_ID_SAVESTATES_LOAD_STATE) + { + CafeSystem::LoadState("state.bin"); + } +} + void MainWindow::OnFileExit(wxCommandEvent& event) { // todo: Safely clean up everything @@ -2184,6 +2220,16 @@ void MainWindow::RecreateMenu() nfcMenu->Append(MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE, _("&Scan NFC tag from file"))->Enable(false); m_menuBar->Append(nfcMenu, _("&NFC")); m_nfcMenuSeparator0 = nullptr; + + // savestates menu + wxMenu* savestatesMenu = new wxMenu; + savestatesMenu->Append(MAINFRAME_MENU_ID_SAVESTATES_PAUSE_TITLE, _("&Pause"), wxEmptyString); + savestatesMenu->Append(MAINFRAME_MENU_ID_SAVESTATES_RESUME_TITLE, _("&Resume"), wxEmptyString); + savestatesMenu->AppendSeparator(); + savestatesMenu->Append(MAINFRAME_MENU_ID_SAVESTATES_SAVE_STATE, _("&Save state"), wxEmptyString); + savestatesMenu->Append(MAINFRAME_MENU_ID_SAVESTATES_LOAD_STATE, _("&Load state"), wxEmptyString); + m_menuBar->Append(savestatesMenu, _("&Savestates")); + // debug->logging submenu wxMenu* debugLoggingMenu = new wxMenu; diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 735f73af..610fbcac 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -93,6 +93,7 @@ public: void OnInstallUpdate(wxCommandEvent& event); void OnFileExit(wxCommandEvent& event); void OnNFCMenu(wxCommandEvent& event); + void OnSavestatesMenu(wxCommandEvent& event); void OnOptionsInput(wxCommandEvent& event); void OnAccountSelect(wxCommandEvent& event); void OnConsoleLanguage(wxCommandEvent& event); @@ -227,6 +228,12 @@ private: wxMenu* m_nfcMenu; wxMenuItem* m_nfcMenuSeparator0; + // savestates + //wxMenuItem* m_pause; + //wxMenuItem* m_resume; + //wxMenuItem* m_saveState; + //wxMenuItem* m_loadState; + // debug wxMenu* m_debugMenu; wxMenu* m_loggingSubmenu; diff --git a/src/util/helpers/Serializer.cpp b/src/util/helpers/Serializer.cpp index e9e60b0a..8e162c30 100644 --- a/src/util/helpers/Serializer.cpp +++ b/src/util/helpers/Serializer.cpp @@ -36,6 +36,19 @@ uint32 MemStreamReader::readBE() return v; } +template<> +sint32 MemStreamReader::readBE() +{ + if (!reserveReadLength(sizeof(sint32))) + return 0; + const uint8* p = m_data + m_cursorPos; + sint32 v; + std::memcpy(&v, p, sizeof(v)); + v = _BE(v); + m_cursorPos += sizeof(sint32); + return v; +} + template<> uint64 MemStreamReader::readBE() { @@ -117,6 +130,14 @@ void MemStreamWriter::writeBE(const uint32& v) std::memcpy(p, &tmp, sizeof(tmp)); } +template<> +void MemStreamWriter::writeBE(const sint32& v) +{ + m_buffer.resize(m_buffer.size() + 4); + uint8* p = m_buffer.data() + m_buffer.size() - 4; + uint32 tmp = _BE(v); + std::memcpy(p, &tmp, sizeof(tmp)); +} template<> void MemStreamWriter::writeBE(const uint16& v) @@ -134,6 +155,19 @@ void MemStreamWriter::writeBE(const uint8& v) m_buffer.emplace_back(v); } +template<> +void MemStreamWriter::writeBE(const bool& v) +{ + writeData(&v, sizeof(bool)); +} + +template<> +bool MemStreamReader::readBE() +{ + bool v{ false }; + readData(&v, sizeof(bool)); + return v; +} template<> void MemStreamWriter::writeBE(const std::string& v) From aa472e13c57c9b1c0cc7855772310fdf971e698b Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sat, 19 Aug 2023 17:23:08 -0400 Subject: [PATCH 2/9] Fix memory leak by modifying MMURange in place. Aquire lock for __OSCreateHostThread. --- src/Cafe/CafeSystem.cpp | 25 +---------- src/Cafe/CafeSystem.h | 2 +- src/Cafe/HW/MMU/MMU.cpp | 31 ++++++-------- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 41 +++---------------- src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 3 +- src/util/helpers/Serializer.h | 1 + 6 files changed, 23 insertions(+), 80 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 3ebc86a7..b81b3681 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -802,12 +802,11 @@ namespace CafeSystem sSystemRunning = false; } - void ResumeTitle(bool* runningThreads) + void ResumeTitle() { if (sSystemRunning) return; - - coreinit::ResumeAllThreads(runningThreads); + coreinit::ResumeAllThreads(); sSystemRunning = true; } @@ -824,13 +823,6 @@ namespace CafeSystem writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - auto threads = coreinit::GetAllThreads(); - for (auto& thr : threads) - { - writer.writeBE(thr != nullptr); - if (thr != nullptr) - writer.writeData(thr, sizeof(OSThread_t)); - } for (auto& thr : activeThread) { writer.writeBE(thr); @@ -861,19 +853,6 @@ namespace CafeSystem reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - auto threads = coreinit::GetAllThreads(); - for (auto& thr : threads) - { - bool notnull = reader.readBE(); - if (notnull) - { - if (!thr) - { - thr = new OSThread_t; - } - reader.readData(thr, sizeof(OSThread_t)); - } - } for (size_t i = 0; i < 256; i++) { activeThread[i] = reader.readBE(); diff --git a/src/Cafe/CafeSystem.h b/src/Cafe/CafeSystem.h index 8be2355d..db5f1dc4 100644 --- a/src/Cafe/CafeSystem.h +++ b/src/Cafe/CafeSystem.h @@ -31,7 +31,7 @@ namespace CafeSystem void ShutdownTitle(); void PauseTitle(); - void ResumeTitle(bool* runningThreads = nullptr); + void ResumeTitle(); void SaveState(std::string path); void LoadState(std::string path); diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index e6b47838..eec61b8b 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -108,19 +108,15 @@ void MemStreamWriter::writeBE(const MMURange& v) } template <> -MMURange MemStreamReader::readBE() +void MemStreamReader::readBE(MMURange& mmuRange) { - bool mapped = readBE(); - uint32 base = readBE(); - MMU_MEM_AREA_ID areaid = (MMU_MEM_AREA_ID)readBE(); - MMURange::MFLAG flags = (MMURange::MFLAG)readBE(); - std::string name = readBE(); - uint32 size = readBE(); - uint32 initsize = readBE(); - MMURange range(base, size, areaid, name, flags); - if (mapped) - range.mapMem(); - return range; + mmuRange.m_isMapped = readBE(); + mmuRange.baseAddress = readBE(); + mmuRange.areaId = (MMU_MEM_AREA_ID)readBE(); + mmuRange.flags = (MMURange::MFLAG)readBE(); + mmuRange.name = readBE(); + mmuRange.size = readBE(); + mmuRange.initSize = readBE(); } bool MMURange::deserializeImpl(MemStreamReader& streamReader) @@ -478,17 +474,14 @@ void memory_Serialize(MemStreamWriter& s) void memory_Deserialize(MemStreamReader& s) { - g_mmuRanges.clear(); size_t cnt = s.readBE(); - for (size_t i = 0; i < cnt; i++) + for (auto& itr : g_mmuRanges) { - auto range = s.readBE(); - bool mapped = range.isMapped(); - if (mapped) + s.readBE(*itr); + if (itr->isMapped()) { - s.readData(memory_base + range.getBase(), range.getSize()); + s.readData(memory_base + itr->getBase(), itr->getSize()); } - g_mmuRanges.push_back(std::move(&range)); } } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index ab82175b..6724ee5f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -208,53 +208,24 @@ namespace coreinit OSSuspendThread(ptr); } } - if (__currentCoreThread[0]) - OSSuspendThread(__currentCoreThread[0]); - if (__currentCoreThread[1]) - OSSuspendThread(__currentCoreThread[1]); - if (__currentCoreThread[2]) - OSSuspendThread(__currentCoreThread[2]); - } - void ResumeAllThreads(bool* runningThreads) + void ResumeAllThreads() { for (auto& thr : activeThread) { - int i = 0; auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); if (thr != 0) { - if (runningThreads && runningThreads[i]) + if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) { - if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) - __OSCreateHostThread(ptr); - OSResumeThread(ptr); - } - else if (!runningThreads) - { - if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) - __OSCreateHostThread(ptr); - OSResumeThread(ptr); + __OSLockScheduler(); + __OSCreateHostThread(ptr); + __OSUnlockScheduler(); } + OSResumeThread(ptr); } - i++; } - if (__currentCoreThread[0]) - OSResumeThread(__currentCoreThread[0]); - if (__currentCoreThread[1]) - OSResumeThread(__currentCoreThread[1]); - if (__currentCoreThread[2]) - OSResumeThread(__currentCoreThread[2]); - } - - std::vector GetAllThreads() - { - auto ret = std::vector(); - ret.push_back(__currentCoreThread[0]); - ret.push_back(__currentCoreThread[1]); - ret.push_back(__currentCoreThread[2]); - return ret; } MPTR funcPtr_threadEntry = 0; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index d04b8ee4..bac966a2 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -525,8 +525,7 @@ namespace coreinit sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount); sint32 OSResumeThread(OSThread_t* thread); void SuspendAllThreads(); - void ResumeAllThreads(bool* runningThreads); - std::vector GetAllThreads(); + void ResumeAllThreads(); void OSContinueThread(OSThread_t* thread); void __OSSuspendThreadInternal(OSThread_t* thread); void __OSSuspendThreadNolock(OSThread_t* thread); diff --git a/src/util/helpers/Serializer.h b/src/util/helpers/Serializer.h index a4941c29..1c7bbce1 100644 --- a/src/util/helpers/Serializer.h +++ b/src/util/helpers/Serializer.h @@ -9,6 +9,7 @@ public: } template T readBE(); + template void readBE(T& v); template T readLE(); template From 288c8d98541ad42983628458a89b4d26481f5f86 Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Thu, 31 Aug 2023 19:02:10 -0400 Subject: [PATCH 3/9] Map mem range as needed; save/restore for coreinit; add logging for save states --- src/Cafe/CafeSystem.cpp | 46 ++++--- src/Cafe/HW/MMU/MMU.cpp | 7 +- src/Cafe/IOSU/fsa/iosu_fsa.cpp | 6 + src/Cafe/OS/libs/coreinit/coreinit.cpp | 50 +++++++ src/Cafe/OS/libs/coreinit/coreinit.h | 9 ++ src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp | 66 ++++++++- src/Cafe/OS/libs/coreinit/coreinit_Alarm.h | 3 + .../OS/libs/coreinit/coreinit_Callbacks.cpp | 57 ++++++++ .../OS/libs/coreinit/coreinit_CodeGen.cpp | 15 ++ src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h | 3 + .../OS/libs/coreinit/coreinit_DynLoad.cpp | 22 +++ src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_FG.cpp | 20 +++ src/Cafe/OS/libs/coreinit/coreinit_FG.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_FS.cpp | 28 +++- src/Cafe/OS/libs/coreinit/coreinit_FS.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp | 20 +++ src/Cafe/OS/libs/coreinit/coreinit_GHS.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp | 29 +++- src/Cafe/OS/libs/coreinit/coreinit_IPC.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_Init.cpp | 22 +++ .../OS/libs/coreinit/coreinit_LockedCache.cpp | 20 +++ .../OS/libs/coreinit/coreinit_LockedCache.h | 3 + src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp | 40 ++++++ src/Cafe/OS/libs/coreinit/coreinit_MEM.h | 3 + .../libs/coreinit/coreinit_MemoryMapping.cpp | 23 ++++ .../OS/libs/coreinit/coreinit_MemoryMapping.h | 3 + .../libs/coreinit/coreinit_MessageQueue.cpp | 18 +++ .../OS/libs/coreinit/coreinit_MessageQueue.h | 3 + .../libs/coreinit/coreinit_OverlayArena.cpp | 15 ++ .../OS/libs/coreinit/coreinit_OverlayArena.h | 3 + .../coreinit/coreinit_Synchronization.cpp | 16 +++ .../OS/libs/coreinit/coreinit_SysHeap.cpp | 20 +++ src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h | 3 + .../OS/libs/coreinit/coreinit_SystemInfo.cpp | 16 +++ .../OS/libs/coreinit/coreinit_SystemInfo.h | 5 +- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 128 ++++++++++++++---- src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 11 +- src/Cemu/Logging/CemuLogging.h | 2 + src/Common/SysAllocator.h | 12 ++ src/gui/MainWindow.cpp | 1 + 41 files changed, 704 insertions(+), 60 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 76bce1b1..891d1738 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -981,7 +981,8 @@ namespace CafeSystem { if (!sSystemRunning) return; - coreinit::SuspendAllThreads(); + coreinit::SuspendActiveThreads(); + iosu::pdm::Stop(); sSystemRunning = false; } @@ -989,13 +990,14 @@ namespace CafeSystem { if (sSystemRunning) return; - coreinit::ResumeAllThreads(); + coreinit::ResumeActiveThreads(); + iosu::pdm::StartTrackingTime(GetForegroundTitleId()); sSystemRunning = true; } void SaveState(std::string path) { - cemuLog_log(LogType::Force, "[SAVESTATE] Saving state..."); + cemuLog_log(LogType::SaveStates, "Saving state..."); MemStreamWriter writer(0); // pause game PauseTitle(); @@ -1006,45 +1008,53 @@ namespace CafeSystem writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - for (auto& thr : activeThread) - { - writer.writeBE(thr); - } - // fs - coreinit::FSSave(writer); + ci_Save(writer); + coreinit::ci_Alarm_Save(writer); + ci_Callbacks_Save(writer); + coreinit::ci_FS_Save(writer); + ci_Init_Save(writer); + coreinit::ci_Thread_Save(writer); iosu::fsa::Save(writer); FileStream* stream = FileStream::createFile(path); stream->writeData(writer.getResult().data(), writer.getResult().size_bytes()); delete stream; - cemuLog_log(LogType::Force, "[SAVESTATE] Saved state to {}.", path); + cemuLog_log(LogType::SaveStates, "Saved state to {}.", path); + ResumeTitle(/*isThreadRunning*/); } void LoadState(std::string path) { + PauseTitle(); - cemuLog_log(LogType::Force, "[SAVESTATE] Loading state...", path); + cemuLog_log(LogType::SaveStates, "Loading state...", path); auto data = FileStream::LoadIntoMemory(path); assert(data.has_value()); MemStreamReader reader(data->data(), data->size()); + + bool recreate = false; + if (recreate) + coreinit::__OSDeleteAllActivePPCThreads(); + // memory + DestroyMemorySpace(); memory_Deserialize(reader); // gpu reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - for (size_t i = 0; i < 256; i++) - { - activeThread[i] = reader.readBE(); - } - // fs - coreinit::FSRestore(reader); + ci_Restore(reader); + coreinit::ci_Alarm_Restore(reader); + ci_Callbacks_Restore(reader); + coreinit::ci_FS_Restore(reader); + ci_Init_Restore(reader); + coreinit::ci_Thread_Restore(reader, recreate); iosu::fsa::Restore(reader); - cemuLog_log(LogType::Force, "[SAVESTATE] Loaded state from {}.", path); + cemuLog_log(LogType::SaveStates, "Loaded state from {}.", path); ResumeTitle(/*isThreadRunning*/); } diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 443607e9..508b9cc2 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -110,13 +110,16 @@ void MemStreamWriter::writeBE(const MMURange& v) template <> void MemStreamReader::readBE(MMURange& mmuRange) { - mmuRange.m_isMapped = readBE(); + bool needsMapped = readBE(); + mmuRange.m_isMapped = false; mmuRange.baseAddress = readBE(); mmuRange.areaId = (MMU_MEM_AREA_ID)readBE(); mmuRange.flags = (MMURange::MFLAG)readBE(); mmuRange.name = readBE(); mmuRange.size = readBE(); mmuRange.initSize = readBE(); + if (needsMapped) + mmuRange.mapMem(); } bool MMURange::deserializeImpl(MemStreamReader& streamReader) @@ -470,7 +473,6 @@ void memory_createDump() void memory_Serialize(MemStreamWriter& s) { - s.writeBE(g_mmuRanges.size()); for (auto& itr : g_mmuRanges) { s.writeBE(*itr); @@ -483,7 +485,6 @@ void memory_Serialize(MemStreamWriter& s) void memory_Deserialize(MemStreamReader& s) { - size_t cnt = s.readBE(); for (auto& itr : g_mmuRanges) { s.readBE(*itr); diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index e2cf8988..903aa881 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -992,6 +992,8 @@ namespace iosu::fsa void Save(MemStreamWriter& writer) { + writer.writeData("iosu_fsa_S", 15); + writer.writeBE(sFSAIoMsgQueue); for (size_t i = 0; i < 352; i++) { @@ -1003,6 +1005,10 @@ namespace iosu::fsa void Restore(MemStreamReader& reader) { + char section[16] = { '\0' }; + reader.readData(section, 15); + cemu_assert_debug(strcmp(section, "iosu_fsa_S") == 0); + sFSAIoMsgQueue = reader.readBE(); for (size_t i = 0; i < 352; i++) { diff --git a/src/Cafe/OS/libs/coreinit/coreinit.cpp b/src/Cafe/OS/libs/coreinit/coreinit.cpp index e8e4ce1f..ce2588bc 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit.cpp @@ -316,6 +316,56 @@ namespace coreinit } }; +void ci_Save(MemStreamWriter& s) +{ + s.writeData("ci_S", 15); + + s.writeData(gCoreinitData, sizeof(coreinitData_t)); + s.writeBE(placeholderFont); + s.writeBE(placeholderFontSize); + + using namespace coreinit; + ci_CodeGen_Save(s); + ci_DynLoad_Save(s); + ci_FG_Save(s); + ci_GHS_Save(s); + ci_IPC_Save(s); + ci_LockedCache_Save(s); + ci_MEM_Save(s); + ci_MemoryMapping_Save(s); + ci_MessageQueue_Save(s); + ci_OverlayArena_Save(s); + ci_Sync_Save(s); + ci_SysHeap_Save(s); + ci_SystemInfo_Save(s); +} + +void ci_Restore(MemStreamReader& s) +{ + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_S") == 0); + + s.readData(gCoreinitData, sizeof(coreinitData_t)); + placeholderFont = s.readBE(); + placeholderFontSize = s.readBE(); + + using namespace coreinit; + ci_CodeGen_Restore(s); + ci_DynLoad_Restore(s); + ci_FG_Restore(s); + ci_GHS_Restore(s); + ci_IPC_Restore(s); + ci_LockedCache_Restore(s); + ci_MEM_Restore(s); + ci_MemoryMapping_Restore(s); + ci_MessageQueue_Restore(s); + ci_OverlayArena_Restore(s); + ci_Sync_Restore(s); + ci_SysHeap_Restore(s); + ci_SystemInfo_Restore(s); +} + void coreinit_load() { coreinit::InitializeCore(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit.h b/src/Cafe/OS/libs/coreinit/coreinit.h index 046ffe1e..81d80f08 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.h +++ b/src/Cafe/OS/libs/coreinit/coreinit.h @@ -11,10 +11,16 @@ void InitializeAsyncCallback(); void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0); void coreinitAsyncCallback_addWithLock(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0); +void ci_Callbacks_Save(MemStreamWriter& s); +void ci_Callbacks_Restore(MemStreamReader& s); + // misc void coreinit_load(); +void ci_Save(MemStreamWriter& s); +void ci_Restore(MemStreamReader& s); + // coreinit shared memory typedef struct @@ -35,6 +41,9 @@ extern coreinitData_t* gCoreinitData; // coreinit init void coreinit_start(PPCInterpreter_t* hCPU); +void ci_Init_Save(MemStreamWriter& s); +void ci_Init_Restore(MemStreamReader& s); + MPTR OSAllocFromSystem(uint32 size, uint32 alignment); void OSFreeToSystem(MPTR mem); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index f7e58115..d379d49c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -247,7 +247,7 @@ namespace coreinit } else { - alarm->nextTime = _swapEndianU64(startTime); + alarm->nextTime = _swapEndianU64(nextTime); alarm->period = 0; alarm->handler = _swapEndianU32(handlerFunc); } @@ -305,6 +305,70 @@ namespace coreinit __OSUnlockScheduler(); } + void ci_Alarm_Save(MemStreamWriter& s) + { + s.writeData("ci_A_S", 15); + + s.writeBE(g_alarmEvent.GetMPTR()); + s.writeBE(g_alarmThread.GetMPTR()); + s.writeBE(_g_alarmThreadStack.GetMPTR()); + s.writeBE(_g_alarmThreadName.GetMPTR()); + + s.writeBE(coreinit_getOSTime()); + + s.writeBE(g_activeAlarms.size()); + for (auto& itr : g_activeAlarms) + { + s.writeBE(memory_getVirtualOffsetFromPointer(itr.first)); + s.writeBE(itr.second->getNextFire()); + } + } + + void ci_Alarm_Restore(MemStreamReader& s) + { + OSAlarm_Shutdown(); + + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_A_S") == 0); + + g_alarmEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE()); + g_alarmThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + _g_alarmThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); + _g_alarmThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); + + uint64 currentTime = coreinit_getOSTime(); + uint64_t timeOffset = currentTime - s.readBE(); + + size_t alms = s.readBE(); + for (size_t alm = 0; alm < alms; alm++) + { + OSAlarm_t* alarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(s.readBE()); + + uint64 startTime = _swapEndianU64(alarm->startTime) + timeOffset; + uint64 nextTime = _swapEndianU64(alarm->nextTime) + timeOffset; + //uint64 nextTime = startTime; + + uint64 period = _swapEndianU64(alarm->period); + + if (period != 0) + { + //uint64 ticksSinceStart = currentTime - startTime; + //uint64 numPeriods = ticksSinceStart / period; + + //nextTime = startTime + (numPeriods + 1ull) * period; + + alarm->startTime = _swapEndianU64(startTime); + } + alarm->nextTime = _swapEndianU64(nextTime); + + uint64 nextFire = s.readBE() + timeOffset; + __OSLockScheduler(); + g_activeAlarms[alarm] = OSHostAlarmCreate(nextFire, period, __OSHostAlarmTriggered, nullptr); + __OSUnlockScheduler(); + } + } + void _OSAlarmThread(PPCInterpreter_t* hCPU) { while( true ) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h index 472d4f21..93523d68 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h @@ -47,6 +47,9 @@ namespace coreinit void OSAlarm_Shutdown(); + void ci_Alarm_Save(MemStreamWriter& s); + void ci_Alarm_Restore(MemStreamReader& s); + void alarm_update(); void InitializeAlarm(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp index aef7e5aa..9507249d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp @@ -31,6 +31,19 @@ struct CoreinitAsyncCallback s_asyncCallbackSpinlock.unlock(); } + static std::vector* getPoolPtr() + { + return &s_asyncCallbackPool; + } + + static std::vector* getQueuePtr() + { + return &s_asyncCallbackQueue; + } + + friend void ci_Callbacks_Save(MemStreamWriter& s); + friend void ci_Callbacks_Restore(MemStreamReader& s); + private: void doCall() { @@ -104,6 +117,50 @@ void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r coreinitAsyncCallback_addWithLock(functionMPTR, numParameters, r3, r4, r5, r6, r7, r8, r9, r10); } +void ci_Callbacks_Save(MemStreamWriter& s) +{ + s.writeData("ci_C_S", 15); + + s.writeBE(g_coreinitCallbackThread.GetMPTR()); + s.writeBE(_g_coreinitCallbackThreadStack.GetMPTR()); + s.writeBE(g_asyncCallbackAsync.GetMPTR()); + s.writeBE(_g_coreinitCBThreadName.GetMPTR()); + + std::vector* pool = CoreinitAsyncCallback::getPoolPtr(); + size_t poolSize = pool->size(); + s.writeBE(poolSize); + s.writeData(pool, sizeof(CoreinitAsyncCallback) * poolSize); + + std::vector* queue = CoreinitAsyncCallback::getQueuePtr(); + size_t queueSize = queue->size(); + s.writeBE(queueSize); + s.writeData(queue, sizeof(CoreinitAsyncCallback) * queueSize); +} + +void ci_Callbacks_Restore(MemStreamReader& s) +{ + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_C_S") == 0); + + g_coreinitCallbackThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + _g_coreinitCallbackThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); + g_asyncCallbackAsync = (coreinit::OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE()); + _g_coreinitCBThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); + + std::vector* pool = CoreinitAsyncCallback::getPoolPtr(); + size_t poolSize = s.readBE(); + pool->clear(); + pool->resize(poolSize); + s.readData(pool, sizeof(CoreinitAsyncCallback) * poolSize); + + std::vector* queue = CoreinitAsyncCallback::getPoolPtr(); + size_t queueSize = s.readBE(); + queue->clear(); + queue->resize(queueSize); + s.readData(queue, sizeof(CoreinitAsyncCallback) * queueSize); +} + void InitializeAsyncCallback() { coreinit::OSInitSemaphore(g_asyncCallbackAsync.GetPtr(), 0); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp index f0e0bd80..c27c1a52 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp @@ -136,6 +136,21 @@ namespace coreinit return true; } + void ci_CodeGen_Save(MemStreamWriter& s) + { + s.writeData("ci_CG_S", 15); + s.writeData(&coreinitCodeGen, sizeof(coreinitCodeGen)); + } + + void ci_CodeGen_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_CG_S") == 0); + + s.readData(&coreinitCodeGen, sizeof(coreinitCodeGen)); + } + void InitializeCodeGen() { cafeExportRegister("coreinit", OSGetCodegenVirtAddrRange, LogType::Placeholder); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h index ba41dd87..f7bdff04 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h @@ -6,5 +6,8 @@ namespace coreinit void codeGenHandleICBI(uint32 ea); bool codeGenShouldAvoid(); + void ci_CodeGen_Save(MemStreamWriter& s); + void ci_CodeGen_Restore(MemStreamReader& s); + void InitializeCodeGen(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp index c8b05124..4a3db30e 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp @@ -129,6 +129,28 @@ namespace coreinit return 0; } + void ci_DynLoad_Save(MemStreamWriter& s) + { + s.writeData("ci_DL_S", 15); + + s.writeBE(_osDynLoadFuncAlloc); + s.writeBE(_osDynLoadFuncFree); + s.writeBE(_osDynLoadTLSFuncAlloc); + s.writeBE(_osDynLoadTLSFuncFree); + } + + void ci_DynLoad_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_DL_S") == 0); + + _osDynLoadFuncAlloc = s.readBE(); + _osDynLoadFuncFree = s.readBE(); + _osDynLoadTLSFuncAlloc = s.readBE(); + _osDynLoadTLSFuncFree = s.readBE(); + } + void InitializeDynLoad() { cafeExportRegister("coreinit", OSDynLoad_SetAllocator, LogType::Placeholder); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h index 0be8226c..c31040a9 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h @@ -14,5 +14,8 @@ namespace coreinit void OSDynLoad_Release(uint32 moduleHandle); uint32 OSDynLoad_FindExport(uint32 moduleHandle, uint32 isData, const char* exportName, betype* addrOut); + void ci_DynLoad_Save(MemStreamWriter& s); + void ci_DynLoad_Restore(MemStreamReader& s); + void InitializeDynLoad(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp index 15dcd6da..457aa01e 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp @@ -191,6 +191,26 @@ namespace coreinit osLib_returnFromFunction(hCPU, r ? 1 : 0); } + void ci_FG_Save(MemStreamWriter& s) + { + s.writeData("ci_FG_S", 15); + + s.writeBE(fgAddr.GetMPTR()); + s.writeBE(fgSaveAreaAddr.GetMPTR()); + s.writeData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT); + } + + void ci_FG_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_FG_S") == 0); + + fgAddr = memory_getPointerFromVirtualOffset(s.readBE()); + fgSaveAreaAddr = memory_getPointerFromVirtualOffset(s.readBE()); + s.readData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT); + } + void InitializeFG() { osLib_addFunction("coreinit", "OSGetForegroundBucket", coreinitExport_OSGetForegroundBucket); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FG.h b/src/Cafe/OS/libs/coreinit/coreinit_FG.h index 846001b9..fcc88b4f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FG.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_FG.h @@ -13,5 +13,8 @@ namespace coreinit void InitForegroundBucket(); + void ci_FG_Save(MemStreamWriter& s); + void ci_FG_Restore(MemStreamReader& s); + void InitializeFG(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp index 70c047a4..c230d14f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp @@ -2638,14 +2638,38 @@ namespace coreinit return FSA_RESULT::OK; } - void FSSave(MemStreamWriter& s) + void ci_FS_Save(MemStreamWriter& s) { + s.writeData("ci_FS_S", 15); s.writeData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + s.writeBE(_sdCard01Mounted); + s.writeBE(_mlc01Mounted); + s.writeBE(_tempFSSpace.GetMPTR()); + size_t s_fsa_activeClients_size = s_fsa_activeClients.size(); + s.writeBE(s_fsa_activeClients_size); + s.writeData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size); + s.writeBE(s_fsaIpcPool.GetMPTR()); + s.writeBE(s_fsaIpcPoolBuffer.GetMPTR()); + s.writeBE(s_fsaIpcPoolBufferNumItems.GetMPTR()); } - void FSRestore(MemStreamReader& s) + void ci_FS_Restore(MemStreamReader& s) { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_FS_S") == 0); + s.readData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + _sdCard01Mounted = s.readBE(); + _mlc01Mounted = s.readBE(); + _tempFSSpace = memory_getPointerFromVirtualOffset(s.readBE()); + size_t s_fsa_activeClients_size = s.readBE(); + s_fsa_activeClients.clear(); + s_fsa_activeClients.resize(s_fsa_activeClients_size); + s.readData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size); + s_fsaIpcPool = (IPCBufPool_t*)memory_getPointerFromVirtualOffset(s.readBE()); + s_fsaIpcPoolBuffer = memory_getPointerFromVirtualOffset(s.readBE()); + s_fsaIpcPoolBufferNumItems = (uint32be*)memory_getPointerFromVirtualOffset(s.readBE()); } void InitializeFS() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.h b/src/Cafe/OS/libs/coreinit/coreinit_FS.h index 6a0bf9b3..0b576126 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.h @@ -308,8 +308,8 @@ namespace coreinit FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient); - void FSSave(MemStreamWriter& s); - void FSRestore(MemStreamReader& s); + void ci_FS_Save(MemStreamWriter& s); + void ci_FS_Restore(MemStreamReader& s); void InitializeFS(); }; // namespace coreinit diff --git a/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp index 5699e3e7..f967781f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp @@ -258,6 +258,26 @@ namespace coreinit return memory_getPointerFromVirtualOffset(_swapEndianU32(tlsBlock->addr) + _swapEndianU32(tlsIndex->ukn04)); } + void ci_GHS_Save(MemStreamWriter& s) + { + s.writeData("ci_GHS_S", 15); + + s.writeBE(g_ghs_data.GetMPTR()); + s.writeBE(_flockMutexArray.GetMPTR()); + s.writeData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX); + } + + void ci_GHS_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_GHS_S") == 0); + + g_ghs_data = (GHSAccessibleData*)memory_getPointerFromVirtualOffset(s.readBE()); + _flockMutexArray = (coreinit::OSMutex*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX); + } + void InitializeGHS() { cafeExportRegister("coreinit", __ghs_flock_create, LogType::Placeholder); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_GHS.h b/src/Cafe/OS/libs/coreinit/coreinit_GHS.h index 0ac09e94..3cc64445 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_GHS.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_GHS.h @@ -4,5 +4,8 @@ namespace coreinit { void PrepareGHSRuntime(); + void ci_GHS_Save(MemStreamWriter& s); + void ci_GHS_Restore(MemStreamReader& s); + void InitializeGHS(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp index ef847f26..6a582203 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp @@ -462,6 +462,34 @@ namespace coreinit return r; } + void ci_IPC_Save(MemStreamWriter& s) + { + s.writeData("ci_IPC_S", 15); + + s.writeBE(s_ipcResourceBuffers.GetMPTR()); + s.writeBE(s_ipcDriver.GetMPTR()); + s.writeBE(gIPCThread.GetMPTR()); + s.writeBE(_gIPCThreadStack.GetMPTR()); + s.writeBE(_gIPCThreadNameStorage.GetMPTR()); + s.writeBE(gIPCThreadMsgQueue.GetMPTR()); + s.writeBE(_gIPCThreadSemaphoreStorage.GetMPTR()); + } + + void ci_IPC_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_IPC_S") == 0); + + s_ipcResourceBuffers = (IPCResourceBuffer*)memory_getPointerFromVirtualOffset(s.readBE()); + s_ipcDriver = (IPCDriver*)memory_getPointerFromVirtualOffset(s.readBE()); + gIPCThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + _gIPCThreadStack = memory_getPointerFromVirtualOffset(s.readBE()); + _gIPCThreadNameStorage = memory_getPointerFromVirtualOffset(s.readBE()); + gIPCThreadMsgQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE()); + _gIPCThreadSemaphoreStorage = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE()); + } + void InitializeIPC() { for (uint32 i = 0; i < Espresso::CORE_COUNT; i++) @@ -478,5 +506,4 @@ namespace coreinit cafeExportRegister("coreinit", IOS_Ioctlv, LogType::PPC_IPC); cafeExportRegister("coreinit", IOS_IoctlvAsync, LogType::PPC_IPC); } - }; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h index 362c4725..f379773e 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h @@ -12,5 +12,8 @@ namespace coreinit IOS_ERROR IOS_Ioctlv(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec); IOS_ERROR IOS_IoctlvAsync(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec, MEMPTR asyncResultFunc, MEMPTR asyncResultUserParam); + void ci_IPC_Save(MemStreamWriter& s); + void ci_IPC_Restore(MemStreamReader& s); + void InitializeIPC(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp index 51a3f542..591a3c61 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp @@ -215,3 +215,25 @@ void coreinit_start(PPCInterpreter_t* hCPU) hCPU->gpr[3] = _coreinitInfo->argc; hCPU->instructionPointer = _coreinitTitleEntryPoint; } + +void ci_Init_Save(MemStreamWriter& s) +{ + s.writeData("ci_Init_S", 15); + + s.writeData(_coreinitInfo, sizeof(coreinitInit_t)); + s.writeBE(argStorageIndex); + s.writeBE(g_preinitUserParam.GetMPTR()); + s.writeBE(_coreinitTitleEntryPoint); +} + +void ci_Init_Restore(MemStreamReader& s) +{ + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_Init_S") == 0); + + s.readData(_coreinitInfo, sizeof(coreinitInit_t)); + argStorageIndex = s.readBE(); + g_preinitUserParam = (PreinitUserHeapStruct*)memory_getPointerFromVirtualOffset(s.readBE()); + _coreinitTitleEntryPoint = s.readBE(); +} \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp index a051fce1..b330f979 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp @@ -271,6 +271,26 @@ namespace coreinit osLib_returnFromFunction(hCPU, 0); } + void ci_LockedCache_Save(MemStreamWriter& s) + { + s.writeData("ci_LC_S", 15); + + s.writeData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); + s.writeData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); + s.writeBE(_lcDisableErrorCounter); + } + + void ci_LockedCache_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_LC_S") == 0); + + s.readData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); + s.readData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); + _lcDisableErrorCounter = s.readBE(); + } + void InitializeLC() { for (sint32 f = 0; f < PPC_CORE_COUNT; f++) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h index d2fbcbdf..89d2b11c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h @@ -2,5 +2,8 @@ namespace coreinit { + void ci_LockedCache_Save(MemStreamWriter& s); + void ci_LockedCache_Restore(MemStreamReader& s); + void InitializeLC(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp index dc82f772..cfbeee5e 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp @@ -630,6 +630,46 @@ namespace coreinit memset(&g_list3, 0, sizeof(g_list3)); } + void ci_MEM_Save(MemStreamWriter& s) + { + s.writeData("ci_MEM_S", 15); + + s.writeBE(sysAreaAllocatorOffset); + s.writeBE(g_heapTableCount); + s.writeData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); + s.writeBE(g_slockInitialized); + s.writeBE(g_listsInitialized); + s.writeData(&g_list1, sizeof(MEMList)); + s.writeData(&g_list2, sizeof(MEMList)); + s.writeData(&g_list3, sizeof(MEMList)); + s.writeData(&gHeapFillValues, sizeof(uint32) * 3); + s.writeBE(gHeapGlobalLock.GetMPTR()); + s.writeData(&gDefaultHeap, sizeof(MEMHeapBase)); + s.writeData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9); + s.writeBE(gDefaultHeapAllocator.GetMPTR()); + } + + void ci_MEM_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_MEM_S") == 0); + + sysAreaAllocatorOffset = s.readBE(); + g_heapTableCount = s.readBE(); + s.readData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); + g_slockInitialized = s.readBE(); + g_listsInitialized = s.readBE(); + s.readData(&g_list1, sizeof(MEMList)); + s.readData(&g_list2, sizeof(MEMList)); + s.readData(&g_list3, sizeof(MEMList)); + s.readData(&gHeapFillValues, sizeof(uint32) * 3); + gHeapGlobalLock = (OSSpinLock*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readData(&gDefaultHeap, sizeof(MEMHeapBase)); + s.readData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9); + gDefaultHeapAllocator = (MEMAllocatorFunc*)memory_getPointerFromVirtualOffset(s.readBE()); + } + void InitializeMEM() { MEMResetToDefaultState(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MEM.h b/src/Cafe/OS/libs/coreinit/coreinit_MEM.h index 7e583195..f057fa0f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MEM.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MEM.h @@ -179,5 +179,8 @@ namespace coreinit void InitializeMEMUnitHeap(); + void ci_MEM_Save(MemStreamWriter& s); + void ci_MEM_Restore(MemStreamReader& s); + void InitializeMEM(); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp index d32a105c..cfeb94b7 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp @@ -16,6 +16,8 @@ namespace coreinit struct OSVirtMemoryEntry { + OSVirtMemoryEntry() : virtualAddress(0), size(0), alignment(0) {}; + OSVirtMemoryEntry(MPTR virtualAddress, uint32 size, uint32 alignment) : virtualAddress(virtualAddress), size(size), alignment(alignment) {}; MPTR virtualAddress; @@ -151,6 +153,27 @@ namespace coreinit return 1; } + void ci_MemoryMapping_Save(MemStreamWriter& s) + { + s.writeData("ci_MemMap_S", 15); + + size_t s_allocatedVirtMemorySize = s_allocatedVirtMemory.size(); + s.writeBE(s_allocatedVirtMemorySize); + s.writeData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize); + } + + void ci_MemoryMapping_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_MemMap_S") == 0); + + size_t s_allocatedVirtMemorySize = s.readBE(); + s_allocatedVirtMemory.clear(); + s_allocatedVirtMemory.resize(s_allocatedVirtMemorySize); + s.readData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize); + } + void InitializeMemoryMapping() { s_allocatedVirtMemory.clear(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h index f51d9a6a..5988fa39 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h @@ -1,5 +1,8 @@ namespace coreinit { + void ci_MemoryMapping_Save(MemStreamWriter& s); + void ci_MemoryMapping_Restore(MemStreamReader& s); + void InitializeMemoryMapping(); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp index 6e6a7bc1..dce041e1 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp @@ -117,6 +117,24 @@ namespace coreinit return g_systemMessageQueue.GetPtr(); } + void ci_MessageQueue_Save(MemStreamWriter& s) + { + s.writeData("ci_MessQue_S", 15); + + s.writeBE(g_systemMessageQueue.GetMPTR()); + s.writeBE(_systemMessageQueueArray.GetMPTR()); + } + + void ci_MessageQueue_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_MessQue_S") == 0); + + g_systemMessageQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE()); + _systemMessageQueueArray = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE()); + } + void InitializeMessageQueue() { OSInitMessageQueue(g_systemMessageQueue.GetPtr(), _systemMessageQueueArray.GetPtr(), _systemMessageQueueArray.GetCount()); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h index 6741ab84..97343c13 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h @@ -36,5 +36,8 @@ namespace coreinit bool OSPeekMessage(OSMessageQueue* msgQueue, OSMessage* msg); sint32 OSSendMessage(OSMessageQueue* msgQueue, OSMessage* msg, uint32 flags); + void ci_MessageQueue_Save(MemStreamWriter& s); + void ci_MessageQueue_Restore(MemStreamReader& s); + void InitializeMessageQueue(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp index 5e5d8852..962a9a94 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp @@ -25,6 +25,21 @@ namespace coreinit *areaSize = MEMORY_OVERLAY_AREA_SIZE; } + void ci_OverlayArena_Save(MemStreamWriter& s) + { + s.writeData("ci_OverArea_S", 15); + + s.writeData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena)); + } + void ci_OverlayArena_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_OverArea_S") == 0); + + s.readData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena)); + } + void InitializeOverlayArena() { cafeExportRegister("coreinit", OSIsEnabledOverlayArena, LogType::Placeholder); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h index d9d5868f..52cb4dbc 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h @@ -1,4 +1,7 @@ namespace coreinit { + void ci_OverlayArena_Save(MemStreamWriter& s); + void ci_OverlayArena_Restore(MemStreamReader& s); + void InitializeOverlayArena(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp index 92c90a9d..4e818e24 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp @@ -614,6 +614,22 @@ namespace coreinit OSWakeupThread(&fastCond->threadQueue); } + void ci_Sync_Save(MemStreamWriter& s) + { + s.writeData("ci_Sync_S", 15); + + s.writeBE(g_rendezvousEvent.GetMPTR()); + } + + void ci_Sync_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_Sync_S") == 0); + + g_rendezvousEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE()); + } + /************* init ************/ void InitializeConcurrency() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp index e37949d7..41a47295 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp @@ -32,6 +32,26 @@ namespace coreinit _sysHeapFreeCounter = 0; } + void ci_SysHeap_Save(MemStreamWriter& s) + { + s.writeData("ci_SysHeap_S", 15); + + s.writeData(_sysHeapHandle, sizeof(MEMHeapBase)); + s.writeBE(_sysHeapAllocCounter); + s.writeBE(_sysHeapFreeCounter); + } + + void ci_SysHeap_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_SysHeap_S") == 0); + + s.readData(_sysHeapHandle, sizeof(MEMHeapBase)); + _sysHeapAllocCounter = s.readBE(); + _sysHeapFreeCounter = s.readBE(); + } + void InitializeSysHeap() { osLib_addFunction("coreinit", "OSAllocFromSystem", export_OSAllocFromSystem); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h index 428224af..3001438a 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h @@ -4,5 +4,8 @@ namespace coreinit { void InitSysHeap(); + void ci_SysHeap_Save(MemStreamWriter& s); + void ci_SysHeap_Restore(MemStreamReader& s); + void InitializeSysHeap(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp index 83925acd..64bb4ff9 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp @@ -10,6 +10,22 @@ namespace coreinit return *g_system_info.GetPtr(); } + void ci_SystemInfo_Save(MemStreamWriter& s) + { + s.writeData("ci_SysInfo_S", 15); + + s.writeBE(g_system_info.GetMPTR()); + } + + void ci_SystemInfo_Restore(MemStreamReader& s) + { + char section[16] = { '\0' }; + s.readData(section, 15); + cemu_assert_debug(strcmp(section, "ci_SysInfo_S") == 0); + + g_system_info = (OSSystemInfo*)memory_getPointerFromVirtualOffset(s.readBE()); + } + void InitializeSystemInfo() { cemu_assert(ppcCyclesSince2000 != 0); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h index b2c50069..49a52625 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h @@ -15,7 +15,10 @@ namespace coreinit static_assert(sizeof(OSSystemInfo) == 0x20); const OSSystemInfo& OSGetSystemInfo(); - + + void ci_SystemInfo_Save(MemStreamWriter& s); + void ci_SystemInfo_Restore(MemStreamReader& s); + void InitializeSystemInfo(); }; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index 0ba23708..590f625c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -196,36 +196,6 @@ namespace coreinit return __currentCoreThread[currentInstance->spr.UPIR]; } - void SuspendAllThreads() - { - for (auto& thr : activeThread) - { - auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); - if (thr != 0) - { - OSSuspendThread(ptr); - } - } - } - - void ResumeAllThreads() - { - for (auto& thr : activeThread) - { - auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); - if (thr != 0) - { - if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) - { - __OSLockScheduler(); - __OSCreateHostThread(ptr); - __OSUnlockScheduler(); - } - OSResumeThread(ptr); - } - } - } - void threadEntry(PPCInterpreter_t* hCPU) { OSThread_t* currentThread = coreinitThread_getCurrentThreadDepr(hCPU); @@ -1361,6 +1331,104 @@ namespace coreinit } } + void ci_Thread_Save(MemStreamWriter& s) + { + s.writeData("ci_T_S", 15); + + s.writeBE(g_activeThreadQueue.GetMPTR()); + s.writeBE(g_coreRunQueue.GetMPTR()); + + s.writeBE(activeThreadCount); + for (sint32 i = 0; i < activeThreadCount; i++) + { + s.writeBE(activeThread[i]); + } + for (sint32 i = 0; i < PPC_CORE_COUNT; i++) + { + s.writeBE(memory_getVirtualOffsetFromPointer(__currentCoreThread[i])); + s.writeBE(s_lehmer_lcg[i]); + s.writeBE(s_terminatorThreads[i].terminatorThread.GetMPTR()); + s.writeBE(s_terminatorThreads[i].threadStack.GetMPTR()); + s.writeBE(s_terminatorThreads[i].threadName.GetMPTR()); + s.writeBE(s_terminatorThreads[i].semaphoreQueuedDeallocators.GetMPTR()); + } + s.writeBE(s_defaultThreads.GetMPTR()); + s.writeBE(s_stack.GetMPTR()); + } + + void ci_Thread_Restore(MemStreamReader& s, bool recreate) + { + char section[16] = { '\0' }; + s.readData(section,15); + cemu_assert_debug(strcmp(section, "ci_T_S") == 0); + + g_activeThreadQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE()); + g_coreRunQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE()); + + sint32 prevActiveThreadCount = s.readBE(); + for (sint32 i = 0; i < prevActiveThreadCount; i++) + { + MPTR threadMPTR = s.readBE(); + if (recreate) + { + __OSLockScheduler(); + __OSActivateThread((OSThread_t*)memory_getPointerFromVirtualOffset(threadMPTR)); + __OSUnlockScheduler(); + } + else + { + activeThreadCount = prevActiveThreadCount; + activeThread[i] = threadMPTR; + } + } + for (sint32 i = 0; i < PPC_CORE_COUNT; i++) + { + __currentCoreThread[i] = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + s_lehmer_lcg[i] = s.readBE(); + s_terminatorThreads[i].terminatorThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + s_terminatorThreads[i].threadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); + s_terminatorThreads[i].threadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); + s_terminatorThreads[i].semaphoreQueuedDeallocators = (OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE()); + } + s_defaultThreads = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); + s_stack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); + } + + void SuspendActiveThreads() + { + + for (auto& thr : activeThread) + { + if (thr != MPTR_NULL) + { + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); + cemuLog_log(LogType::SaveStates, "Before State: {}", ptr->state.value()); + cemuLog_log(LogType::SaveStates, "Before SusCnt: {}", ptr->suspendCounter); + OSSuspendThread(ptr); + cemuLog_log(LogType::SaveStates, "After State: {}", ptr->state.value()); + cemuLog_log(LogType::SaveStates, "After SusCnt: {}", ptr->suspendCounter); + } + } + } + + void ResumeActiveThreads() + { + for (auto& thr : activeThread) + { + if (thr != MPTR_NULL) + { + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); + if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) + { + __OSLockScheduler(); + __OSCreateHostThread(ptr); + __OSUnlockScheduler(); + } + OSResumeThread(ptr); + } + } + } + void InitializeThread() { cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index 74e27d8f..321ddb3f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -496,7 +496,16 @@ static_assert(sizeof(OSThread_t) == 0x6A0-4); // todo - determine correct size namespace coreinit { + void ci_Thread_Save(MemStreamWriter& s); + void ci_Thread_Restore(MemStreamReader& s, bool recreate); + void SuspendActiveThreads(); + void ResumeActiveThreads(); + void InitializeThread(); + + void ci_Sync_Save(MemStreamWriter& s); + void ci_Sync_Restore(MemStreamReader& s); + void InitializeConcurrency(); bool __CemuIsMulticoreMode(); @@ -524,8 +533,6 @@ namespace coreinit sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount); sint32 OSResumeThread(OSThread_t* thread); - void SuspendAllThreads(); - void ResumeAllThreads(); void OSContinueThread(OSThread_t* thread); void __OSSuspendThreadInternal(OSThread_t* thread); void __OSSuspendThreadNolock(OSThread_t* thread); diff --git a/src/Cemu/Logging/CemuLogging.h b/src/Cemu/Logging/CemuLogging.h index d55256c9..fe9f941a 100644 --- a/src/Cemu/Logging/CemuLogging.h +++ b/src/Cemu/Logging/CemuLogging.h @@ -35,6 +35,8 @@ enum class LogType : sint32 ProcUi = 40, + SaveStates = 50, + APIErrors = 0, // alias for Force. Logs bad parameters or other API errors in OS libs diff --git a/src/Common/SysAllocator.h b/src/Common/SysAllocator.h index 7930a16b..92140949 100644 --- a/src/Common/SysAllocator.h +++ b/src/Common/SysAllocator.h @@ -56,6 +56,12 @@ public: m_tempData.insert(m_tempData.begin(), str, str + N); } + SysAllocator& operator=(T* value) + { + m_sysMem = value; + return *this; + } + constexpr uint32 GetCount() const { return count; @@ -165,6 +171,12 @@ public: return *this; } + SysAllocator& operator=(T* value) + { + m_sysMem = value; + return *this; + } + operator T() { return *GetPtr(); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index d6688ef3..2a7237f2 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -2250,6 +2250,7 @@ void MainWindow::RecreateMenu() debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::Patches), _("&Graphic pack patches"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::Patches)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::TextureCache), _("&Texture cache warnings"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::TextureCache)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::TextureReadback), _("&Texture readback"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::TextureReadback)); + debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::SaveStates), _("&Save states"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::SaveStates)); debugLoggingMenu->AppendSeparator(); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::OpenGLLogging), _("&OpenGL debug output"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::OpenGLLogging)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::VulkanValidation), _("&Vulkan validation layer (slow)"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::VulkanValidation)); From 35f6e67903da0b825267a0d382dd0a8f27c25558 Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sun, 8 Oct 2023 10:34:45 -0400 Subject: [PATCH 4/9] Refactoring, save/restore additional libs --- src/Cafe/CafeSystem.cpp | 26 +- src/Cafe/Filesystem/fsc.cpp | 93 ++++--- src/Cafe/Filesystem/fsc.h | 1 - src/Cafe/Filesystem/fscDeviceHostFS.cpp | 24 +- src/Cafe/Filesystem/fscDeviceHostFS.h | 3 +- src/Cafe/Filesystem/fscDeviceWua.cpp | 10 +- src/Cafe/Filesystem/fscDeviceWud.cpp | 10 +- src/Cafe/HW/MMU/MMU.cpp | 44 +--- src/Cafe/HW/MMU/MMU.h | 3 - src/Cafe/IOSU/fsa/iosu_fsa.cpp | 142 +++++------ src/Cafe/OS/common/OSCommon.cpp | 41 ++++ src/Cafe/OS/common/OSCommon.h | 3 + src/Cafe/OS/libs/camera/camera.cpp | 26 +- src/Cafe/OS/libs/camera/camera.h | 3 + src/Cafe/OS/libs/coreinit/coreinit.cpp | 82 ++++--- src/Cafe/OS/libs/coreinit/coreinit.h | 14 +- src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp | 30 ++- src/Cafe/OS/libs/coreinit/coreinit_Alarm.h | 4 +- .../OS/libs/coreinit/coreinit_Callbacks.cpp | 62 ++--- .../OS/libs/coreinit/coreinit_CodeGen.cpp | 11 +- src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h | 4 +- .../OS/libs/coreinit/coreinit_DynLoad.cpp | 20 +- src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_FG.cpp | 20 +- src/Cafe/OS/libs/coreinit/coreinit_FG.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_FS.cpp | 44 ++-- src/Cafe/OS/libs/coreinit/coreinit_FS.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp | 26 +- src/Cafe/OS/libs/coreinit/coreinit_GHS.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp | 40 ++- src/Cafe/OS/libs/coreinit/coreinit_IPC.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_Init.cpp | 20 +- .../OS/libs/coreinit/coreinit_LockedCache.cpp | 14 +- .../OS/libs/coreinit/coreinit_LockedCache.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp | 32 ++- src/Cafe/OS/libs/coreinit/coreinit_MEM.h | 4 +- .../libs/coreinit/coreinit_MemoryMapping.cpp | 21 +- .../OS/libs/coreinit/coreinit_MemoryMapping.h | 4 +- .../libs/coreinit/coreinit_MessageQueue.cpp | 20 +- .../OS/libs/coreinit/coreinit_MessageQueue.h | 4 +- .../libs/coreinit/coreinit_OverlayArena.cpp | 16 +- .../OS/libs/coreinit/coreinit_OverlayArena.h | 4 +- .../coreinit/coreinit_Synchronization.cpp | 16 +- .../OS/libs/coreinit/coreinit_SysHeap.cpp | 16 +- src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h | 4 +- .../OS/libs/coreinit/coreinit_SystemInfo.cpp | 16 +- .../OS/libs/coreinit/coreinit_SystemInfo.h | 4 +- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 52 ++-- src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 8 +- src/Cafe/OS/libs/dmae/dmae.cpp | 11 + src/Cafe/OS/libs/dmae/dmae.h | 3 + src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp | 23 ++ src/Cafe/OS/libs/nlibcurl/nlibcurl.h | 3 + src/Cafe/OS/libs/nn_acp/nn_acp.cpp | 12 + src/Cafe/OS/libs/nn_acp/nn_acp.h | 3 + src/Cafe/OS/libs/nn_act/nn_act.cpp | 13 + src/Cafe/OS/libs/nn_act/nn_act.h | 3 + src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp | 15 ++ src/Cafe/OS/libs/nn_aoc/nn_aoc.h | 3 + src/Cafe/OS/libs/nn_boss/nn_boss.cpp | 16 ++ src/Cafe/OS/libs/nn_boss/nn_boss.h | 3 + src/Cafe/OS/libs/nn_fp/nn_fp.cpp | 12 + src/Cafe/OS/libs/nn_fp/nn_fp.h | 3 + src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp | 14 ++ src/Cafe/OS/libs/nn_ndm/nn_ndm.h | 3 + src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp | 12 + src/Cafe/OS/libs/nn_nfp/nn_nfp.h | 3 + src/Cafe/OS/libs/nn_olv/nn_olv.cpp | 34 +++ src/Cafe/OS/libs/nn_olv/nn_olv.h | 3 + src/Cafe/OS/libs/nn_olv/nn_olv_OfflineDB.cpp | 5 + src/Cafe/OS/libs/nn_olv/nn_olv_OfflineDB.h | 4 +- src/Cafe/OS/libs/nn_save/nn_save.cpp | 12 + src/Cafe/OS/libs/nn_save/nn_save.h | 3 + src/Cafe/OS/libs/nn_temp/nn_temp.cpp | 12 + src/Cafe/OS/libs/nn_temp/nn_temp.h | 3 + src/Cafe/OS/libs/nn_uds/nn_uds.cpp | 12 + src/Cafe/OS/libs/nn_uds/nn_uds.h | 3 + src/Cafe/OS/libs/nsyshid/nsyshid.cpp | 22 ++ src/Cafe/OS/libs/nsyshid/nsyshid.h | 3 + src/Cafe/OS/libs/nsysnet/nsysnet.cpp | 26 ++ src/Cafe/OS/libs/nsysnet/nsysnet.h | 3 + src/Cafe/OS/libs/padscore/padscore.cpp | 27 ++- src/Cafe/OS/libs/padscore/padscore.h | 3 + src/Cafe/OS/libs/proc_ui/proc_ui.cpp | 10 + src/Cafe/OS/libs/proc_ui/proc_ui.h | 3 + src/util/helpers/Serializer.cpp | 229 +++++++----------- src/util/helpers/Serializer.h | 104 +++++++- 87 files changed, 1024 insertions(+), 717 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 891d1738..8340a179 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -1007,13 +1007,10 @@ namespace CafeSystem writer.writeData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); - // cpu - ci_Save(writer); - coreinit::ci_Alarm_Save(writer); - ci_Callbacks_Save(writer); - coreinit::ci_FS_Save(writer); - ci_Init_Save(writer); - coreinit::ci_Thread_Save(writer); + + nn::temp::save(writer); + nn::aoc::save(writer); + osLib_save(writer); iosu::fsa::Save(writer); FileStream* stream = FileStream::createFile(path); @@ -1034,10 +1031,6 @@ namespace CafeSystem assert(data.has_value()); MemStreamReader reader(data->data(), data->size()); - bool recreate = false; - if (recreate) - coreinit::__OSDeleteAllActivePPCThreads(); - // memory DestroyMemorySpace(); memory_Deserialize(reader); @@ -1045,13 +1038,10 @@ namespace CafeSystem reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); - // cpu - ci_Restore(reader); - coreinit::ci_Alarm_Restore(reader); - ci_Callbacks_Restore(reader); - coreinit::ci_FS_Restore(reader); - ci_Init_Restore(reader); - coreinit::ci_Thread_Restore(reader, recreate); + + nn::temp::restore(reader); + nn::aoc::restore(reader); + osLib_restore(reader); iosu::fsa::Restore(reader); cemuLog_log(LogType::SaveStates, "Loaded state from {}.", path); diff --git a/src/Cafe/Filesystem/fsc.cpp b/src/Cafe/Filesystem/fsc.cpp index ed7cfb00..48a2e1b7 100644 --- a/src/Cafe/Filesystem/fsc.cpp +++ b/src/Cafe/Filesystem/fsc.cpp @@ -285,8 +285,6 @@ FSCMountPathNode* fsc_lookupPathVirtualNode(const char* path, sint32 priority) class FSCVirtualFileDirectoryIterator : public FSCVirtualFile { public: - void Save(MemStreamWriter& writer) override; - sint32 fscGetType() override { return FSC_TYPE_DIRECTORY; @@ -340,6 +338,8 @@ public: dirIterator->dirEntries.emplace_back(dirEntry); } + void Save(MemStreamWriter& writer) override; + private: void PopulateIterationList() { @@ -736,11 +736,39 @@ void fsc_init() fsc_reset(); } +template <> +void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v) +{ + writeBE(v.index); + writePODVector(v.dirEntries); +} + +template <> +void MemStreamReader::readBE(FSCVirtualFile::FSCDirIteratorState& v) +{ + readBE(v.index); + readPODVector(v.dirEntries); +} + void FSCVirtualFile::Save(MemStreamWriter& writer) { - writer.writeBE(dirIterator != nullptr); + writer.writeBool(dirIterator != nullptr); if (dirIterator) writer.writeBE(*dirIterator); + writer.writeBool(m_isAppend); } + +void FSCVirtualFileDirectoryIterator::Save(MemStreamWriter& writer) +{ + writer.writeBE((uint32)Child::DIRECTORY_ITERATOR); + writer.writeBE(m_path); + writer.writeBE(m_folders.size()); + for (auto& folder : m_folders) + { + folder->Save(writer); + } + FSCVirtualFile::Save(writer); +} + #include "Cafe/Filesystem/fscDeviceHostFS.h" FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) @@ -748,46 +776,35 @@ FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) FSCVirtualFile* file; switch ((Child)reader.readBE()) { - case Child::DIRECTORY_ITERATOR: - { - std::string path = reader.readBE(); - std::vector folders{}; - size_t size = reader.readBE(); - for (size_t i = 0; i < size; i++) + case Child::DIRECTORY_ITERATOR: { - folders.push_back(Restore(reader)); + std::string path = reader.readBE(); + std::vector folders{}; + size_t size = reader.readBE(); + for (size_t i = 0; i < size; i++) + { + folders.push_back(Restore(reader)); + } + file = new FSCVirtualFileDirectoryIterator(path, folders); + break; } - file = new FSCVirtualFileDirectoryIterator(path, folders); - break; + case Child::HOST: + { + std::string path = reader.readBE(); + FSC_ACCESS_FLAG flags = (FSC_ACCESS_FLAG)reader.readBE(); + sint32 status{}; + file = FSCVirtualFile_Host::OpenFile(path, flags, status); + file->fscSetSeek(reader.readBE()); + break; + } + default: + throw std::exception("Not implemented"); } - case Child::HOST: - { - std::string path = reader.readBE(); - FSC_ACCESS_FLAG flags = (FSC_ACCESS_FLAG)reader.readBE(); - sint32 status{}; - file = FSCVirtualFile_Host::OpenFile(path, flags, status); - file->fscSetSeek(reader.readBE()); - break; - } - default: - throw std::exception("Not implemented"); - } - if (reader.readBE()) + if (reader.readBool()) { file->dirIterator = new FSCDirIteratorState; - *file->dirIterator = reader.readBE(); + reader.readBE(*file->dirIterator); } + reader.readBool(file->m_isAppend); return file; -} - -void FSCVirtualFileDirectoryIterator::Save(MemStreamWriter& writer) -{ - writer.writeBE((uint32)Child::DIRECTORY_ITERATOR); - writer.writeBE(m_path); - writer.writeBE(m_folders.size()); - for (auto& folder : m_folders) - { - folder->Save(writer); - } - FSCVirtualFile::Save(writer); } \ No newline at end of file diff --git a/src/Cafe/Filesystem/fsc.h b/src/Cafe/Filesystem/fsc.h index b3b66d04..8d9ab032 100644 --- a/src/Cafe/Filesystem/fsc.h +++ b/src/Cafe/Filesystem/fsc.h @@ -38,7 +38,6 @@ DEFINE_ENUM_FLAG_OPERATORS(FSC_ACCESS_FLAG); #define FSC_STATUS_ALREADY_EXISTS (3) // note: Unlike the native Wii U filesystem, FSC does not provide separate error codes for NOT_A_FILE and NOT_A_DIRECTORY // to determine them manually, open with both modes (file and dir) and check the type - #define FSC_MAX_DIR_NAME_LENGTH (256) #define FSC_MAX_DEVICE_PATH_LENGTH ((std::max)(260,FSA_PATH_SIZE_MAX)) // max length for FSC device paths (should be at least equal or greater than supported by host filesystem) diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.cpp b/src/Cafe/Filesystem/fscDeviceHostFS.cpp index 7f66c99b..12b15024 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.cpp +++ b/src/Cafe/Filesystem/fscDeviceHostFS.cpp @@ -157,19 +157,6 @@ bool FSCVirtualFile_Host::fscDirNext(FSCDirEntry* dirEntry) return true; } -void FSCVirtualFile_Host::Save(MemStreamWriter& writer) -{ - writer.writeBE((uint32)Child::HOST); - - writer.writeBE(m_path->string()); - writer.writeBE((uint32)m_accessFlags); - - writer.writeBE(m_seek); - - FSCVirtualFile::Save(writer); -} - - FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus) { if (!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && !HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)) @@ -308,4 +295,13 @@ public: bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTargetPath, sint32 priority) { return fsc_mount(mountPath, hostTargetPath, &fscDeviceHostFSC::instance(), nullptr, priority) == FSC_STATUS_OK; -} \ No newline at end of file +} + +void FSCVirtualFile_Host::Save(MemStreamWriter& writer) +{ + writer.writeBE((uint32)Child::HOST); + writer.writeBE(m_path->string()); + writer.writeBE((uint32)m_accessFlags); + writer.writeBE(m_seek); + FSCVirtualFile::Save(writer); +} diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.h b/src/Cafe/Filesystem/fscDeviceHostFS.h index 6daab151..0a7df4cd 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.h +++ b/src/Cafe/Filesystem/fscDeviceHostFS.h @@ -3,7 +3,6 @@ class FSCVirtualFile_Host : public FSCVirtualFile { public: - void Save(MemStreamWriter& writer) override; static FSCVirtualFile* OpenFile(const fs::path& path, FSC_ACCESS_FLAG accessFlags, sint32& fscStatus); ~FSCVirtualFile_Host() override; @@ -19,6 +18,8 @@ public: void fscSetFileLength(uint64 endOffset) override; bool fscDirNext(FSCDirEntry* dirEntry) override; + void Save(MemStreamWriter& writer) override; + private: FSCVirtualFile_Host(uint32 type) : m_type(type) {}; diff --git a/src/Cafe/Filesystem/fscDeviceWua.cpp b/src/Cafe/Filesystem/fscDeviceWua.cpp index 5bea3715..e5f23a9e 100644 --- a/src/Cafe/Filesystem/fscDeviceWua.cpp +++ b/src/Cafe/Filesystem/fscDeviceWua.cpp @@ -15,11 +15,6 @@ protected: }; public: - void Save(MemStreamWriter& writer) override - { - throw std::exception("Not implemented"); - } - sint32 fscGetType() override { return m_fscType; @@ -112,6 +107,11 @@ public: return true; } + void Save(MemStreamWriter& writer) override + { + throw std::exception("Not implemented"); + } + private: ZArchiveReader* m_archive{nullptr}; sint32 m_fscType; diff --git a/src/Cafe/Filesystem/fscDeviceWud.cpp b/src/Cafe/Filesystem/fscDeviceWud.cpp index 70d9b5c9..537699b7 100644 --- a/src/Cafe/Filesystem/fscDeviceWud.cpp +++ b/src/Cafe/Filesystem/fscDeviceWud.cpp @@ -22,11 +22,6 @@ protected: } public: - void Save(MemStreamWriter& writer) override - { - throw std::exception("Not implemented"); - } - sint32 fscGetType() override { return m_fscType; @@ -113,6 +108,11 @@ public: return true; } + void Save(MemStreamWriter& writer) override + { + throw std::exception("Not implemented"); + } + private: FSTVolume* m_volume{nullptr}; sint32 m_fscType; diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 508b9cc2..e65e62f9 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -80,37 +80,22 @@ MMURange* memory_getMMURangeByAddress(MPTR address) return nullptr; } -bool MMURange::serializeImpl(MemStreamWriter& streamWriter) -{ - streamWriter.writeBE(this->m_isMapped); - if (m_isMapped) - { - streamWriter.writeBE(this->baseAddress); - streamWriter.writeBE((uint8)this->areaId); - streamWriter.writeBE((uint8)this->flags); - streamWriter.writeBE(this->name); - streamWriter.writeBE(this->size); - streamWriter.writeBE(this->initSize); - } - return true; -} - template<> -void MemStreamWriter::writeBE(const MMURange& v) +void MemStreamWriter::writeBE(const MMURange& v) { - writeBE(v.m_isMapped); + writeBool(v.m_isMapped); writeBE(v.baseAddress); - writeBE((uint8)v.areaId); - writeBE((uint8)v.flags); + writeBE((uint8)v.areaId); + writeBE((uint8)v.flags); writeBE(v.name); writeBE(v.size); writeBE(v.initSize); } template <> -void MemStreamReader::readBE(MMURange& mmuRange) +void MemStreamReader::readBE(MMURange& mmuRange) { - bool needsMapped = readBE(); + bool needsMapped = readBool(); mmuRange.m_isMapped = false; mmuRange.baseAddress = readBE(); mmuRange.areaId = (MMU_MEM_AREA_ID)readBE(); @@ -122,23 +107,6 @@ void MemStreamReader::readBE(MMURange& mmuRange) mmuRange.mapMem(); } -bool MMURange::deserializeImpl(MemStreamReader& streamReader) -{ - m_isMapped = streamReader.readBE(); - if (m_isMapped) - { - baseAddress = streamReader.readBE(); - areaId = (MMU_MEM_AREA_ID)streamReader.readBE(); - this->flags = (MFLAG)streamReader.readBE(); - this->name = streamReader.readBE(); - this->size = streamReader.readBE(); - this->initSize = streamReader.readBE(); - m_isMapped = false; - mapMem(); - } - return true; -} - MMURange::MMURange(const uint32 baseAddress, const uint32 size, MMU_MEM_AREA_ID areaId, const std::string_view name, MFLAG flags) : baseAddress(baseAddress), size(size), initSize(size), areaId(areaId), name(name), flags(flags) { g_mmuRanges.emplace_back(this); diff --git a/src/Cafe/HW/MMU/MMU.h b/src/Cafe/HW/MMU/MMU.h index 216b4109..3090e3c9 100644 --- a/src/Cafe/HW/MMU/MMU.h +++ b/src/Cafe/HW/MMU/MMU.h @@ -51,9 +51,6 @@ struct MMURange FLAG_MAP_EARLY = (1 << 1), // map at Cemu launch, normally memory is mapped when a game is loaded }; - bool serializeImpl(MemStreamWriter& streamWriter); - bool deserializeImpl(MemStreamReader& streamReader); - MMURange(const uint32 baseAddress, const uint32 size, MMU_MEM_AREA_ID areaId, const std::string_view name, MFLAG flags = (MFLAG)0); void mapMem(); diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index 903aa881..fdb7dee4 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -36,7 +36,9 @@ namespace iosu } }; - std::array sFSAClientArray; + static constexpr int const sFSAClientArraySize = 624; + + std::array sFSAClientArray; IOS_ERROR FSAAllocateClient(sint32& indexOut) { @@ -229,9 +231,10 @@ namespace iosu return it.fscFile; } + static constexpr int const m_handleTableSize = 0x3C0; private: uint32 m_currentCounter = 1; - std::array<_FSAHandleResource, 0x3C0> m_handleTable; + std::array<_FSAHandleResource, m_handleTableSize> m_handleTable; }; _FSAHandleTable sFileHandleTable; @@ -908,113 +911,76 @@ namespace iosu } // namespace iosu template <> -void MemStreamWriter::writeBE(const FSCDirEntry& v); -template <> -FSCDirEntry MemStreamReader::readBE(); -template <> -FSCVirtualFile::FSCDirIteratorState MemStreamReader::readBE(); -template <> -void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v); +void MemStreamWriter::writeBE(const iosu::fsa::FSAClient& v) +{ + writeBE(v.workingDirectory); + writeBool(v.isAllocated); +} template <> -void MemStreamWriter::writeBE(const iosu::fsa::_FSAHandleTable& v) +void MemStreamReader::readBE(iosu::fsa::FSAClient& v) +{ + readBE(v.workingDirectory); + readBool(v.isAllocated); +} + +template <> +void MemStreamWriter::writeBE(const iosu::fsa::_FSAHandleTable& v) { writeBE(v.m_currentCounter); - for (int i = 0; i < 0x3C0; i++) + for (sint32 i = 0; i < v.m_handleTableSize; i++) { writeBE(v.m_handleTable[i].handleCheckValue); - writeBE(v.m_handleTable[i].isAllocated); - writeBE(v.m_handleTable[i].fscFile != nullptr); + writeBool(v.m_handleTable[i].isAllocated); + + writeBool(v.m_handleTable[i].fscFile != nullptr); if (v.m_handleTable[i].fscFile != nullptr) v.m_handleTable[i].fscFile->Save(*this); } } template <> -iosu::fsa::_FSAHandleTable MemStreamReader::readBE() +void MemStreamReader::readBE(iosu::fsa::_FSAHandleTable& v) { - iosu::fsa::_FSAHandleTable table{}; - table.m_currentCounter = readBE(); - for (int i = 0; i < 0x3C0; i++) + readBE(v.m_currentCounter); + for (sint32 i = 0; i < v.m_handleTableSize; i++) { - table.m_handleTable[i].handleCheckValue = readBE(); - table.m_handleTable[i].isAllocated = readBE(); - if (readBE()) table.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); - } - return table; -} + readBE(v.m_handleTable[i].handleCheckValue); + readBool(v.m_handleTable[i].isAllocated); -template <> -void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v) -{ - writeBE(v.index); - writeBE(v.dirEntries.size()); - for (int i = 0; i < v.dirEntries.size(); i++) - { - writeBE(v.dirEntries[i]); + if (readBool()) v.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); } } -template <> -void MemStreamWriter::writeBE(const FSCDirEntry& v) +namespace iosu { - writeData(v.path, FSC_MAX_DIR_NAME_LENGTH); - writeBE(v.isDirectory); - writeBE(v.isFile); - writeBE(v.fileSize); -} - -template <> -FSCDirEntry MemStreamReader::readBE() -{ - FSCDirEntry entry{}; - readData(entry.path, FSC_MAX_DIR_NAME_LENGTH); - entry.isDirectory = readBE(); - entry.isFile = readBE(); - entry.fileSize = readBE(); - return entry; -} - -template <> -FSCVirtualFile::FSCDirIteratorState MemStreamReader::readBE() -{ - FSCVirtualFile::FSCDirIteratorState state{}; - state.index = readBE(); - size_t size = readBE(); - for (size_t i = 0; i < size; i++) + namespace fsa { - state.dirEntries[i] = readBE(); - } - return state; -} - -namespace iosu::fsa -{ - - void Save(MemStreamWriter& writer) - { - writer.writeData("iosu_fsa_S", 15); - - writer.writeBE(sFSAIoMsgQueue); - for (size_t i = 0; i < 352; i++) + void Save(MemStreamWriter& s) { - writer.writeBE(_m_sFSAIoMsgQueueMsgBuffer[i]); + s.writeSection("iosu_fsa"); + s.writeBE(sFSAIoMsgQueue); + s.writeMPTR(_m_sFSAIoMsgQueueMsgBuffer); + + for (sint32 i = 0; i < sFSAClientArraySize; i++) + { + s.writeBE(sFSAClientArray[i]); + } + s.writeBE(sDirHandleTable); + s.writeBE(sFileHandleTable); } - writer.writeBE(sDirHandleTable); - writer.writeBE(sFileHandleTable); - } - void Restore(MemStreamReader& reader) - { - char section[16] = { '\0' }; - reader.readData(section, 15); - cemu_assert_debug(strcmp(section, "iosu_fsa_S") == 0); - - sFSAIoMsgQueue = reader.readBE(); - for (size_t i = 0; i < 352; i++) + void Restore(MemStreamReader& s) { - _m_sFSAIoMsgQueueMsgBuffer[i] = reader.readBE(); + s.readSection("iosu_fsa"); + s.readBE(sFSAIoMsgQueue); + s.readMPTR(_m_sFSAIoMsgQueueMsgBuffer); + + for (sint32 i = 0; i < sFSAClientArraySize; i++) + { + s.readBE(sFSAClientArray[i]); + } + s.readBE(sDirHandleTable); + s.readBE(sFileHandleTable); } - sDirHandleTable = reader.readBE<_FSAHandleTable>(); - sFileHandleTable = reader.readBE<_FSAHandleTable>(); - } -} \ No newline at end of file + } // namespace fsa +} // namespace iosu \ No newline at end of file diff --git a/src/Cafe/OS/common/OSCommon.cpp b/src/Cafe/OS/common/OSCommon.cpp index 7e11ea13..29379f61 100644 --- a/src/Cafe/OS/common/OSCommon.cpp +++ b/src/Cafe/OS/common/OSCommon.cpp @@ -185,6 +185,47 @@ void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64) hCPU->instructionPointer = hCPU->spr.LR; } +void osLib_save(MemStreamWriter& s) +{ + coreinit_save(s); + dmae_save(s); + padscore::save(s); + nnAct_save(s); + nn::acp::save(s); + nnBoss_save(s); + nn::nfp::save(s); + nnUds_save(s); + nn::ndm::save(s); + nn::save::save(s); + nsysnet_save(s); + nn::fp::save(s); + nn::olv::save(s); + nlibcurl::save(s); + nsyshid::save(s); + camera::save(s); + procui_save(s); +} +void osLib_restore(MemStreamReader& s) +{ + coreinit_restore(s); + dmae_restore(s); + padscore::restore(s); + nnAct_restore(s); + nn::acp::restore(s); + nnBoss_restore(s); + nn::nfp::restore(s); + nnUds_restore(s); + nn::ndm::restore(s); + nn::save::restore(s); + nsysnet_restore(s); + nn::fp::restore(s); + nn::olv::restore(s); + nlibcurl::restore(s); + nsyshid::restore(s); + camera::restore(s); + procui_restore(s); +} + void osLib_load() { // load HLE modules diff --git a/src/Cafe/OS/common/OSCommon.h b/src/Cafe/OS/common/OSCommon.h index 4fb65a47..04f3b4f4 100644 --- a/src/Cafe/OS/common/OSCommon.h +++ b/src/Cafe/OS/common/OSCommon.h @@ -6,6 +6,9 @@ struct PPCInterpreter_t; #define OSLIB_FUNCTIONTABLE_TYPE_FUNCTION (1) #define OSLIB_FUNCTIONTABLE_TYPE_POINTER (2) +void osLib_save(MemStreamWriter& s); +void osLib_restore(MemStreamReader& s); + void osLib_load(); void osLib_generateHashFromName(const char* name, uint32* hashA, uint32* hashB); sint32 osLib_getFunctionIndex(const char* libraryName, const char* functionName); diff --git a/src/Cafe/OS/libs/camera/camera.cpp b/src/Cafe/OS/libs/camera/camera.cpp index 4debb37f..c9b5cbc8 100644 --- a/src/Cafe/OS/libs/camera/camera.cpp +++ b/src/Cafe/OS/libs/camera/camera.cpp @@ -242,6 +242,29 @@ namespace camera g_cameraCounter = 0; } + void save(MemStreamWriter& s) + { + s.writeSection("camera"); + + s.writePODVector(g_table_cameraHandles); + s.writePODVector(g_activeCameraInstances); + s.writeAtomic(g_cameraCounter); + s.writeMPTR(g_alarm_camera); + s.writeMPTR(g_cameraHandlerParam); + } + void restore(MemStreamReader& s) + { + s.readSection("camera"); + + std::unique_lock _lock(g_mutex_camera); + + s.readPODVector(g_table_cameraHandles); + s.readPODVector(g_activeCameraInstances); + s.readAtomic(g_cameraCounter); + s.readMPTR(g_alarm_camera); + s.readMPTR(g_cameraHandlerParam); + } + void load() { reset(); @@ -253,5 +276,4 @@ namespace camera cafeExportRegister("camera", CAMClose, LogType::Placeholder); cafeExportRegister("camera", CAMSubmitTargetSurface, LogType::Placeholder); } -} - +} \ No newline at end of file diff --git a/src/Cafe/OS/libs/camera/camera.h b/src/Cafe/OS/libs/camera/camera.h index 04248bbc..6b3d48b1 100644 --- a/src/Cafe/OS/libs/camera/camera.h +++ b/src/Cafe/OS/libs/camera/camera.h @@ -6,5 +6,8 @@ namespace camera sint32 CAMOpen(sint32 camHandle); sint32 CAMClose(sint32 camHandle); + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void load(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit.cpp b/src/Cafe/OS/libs/coreinit/coreinit.cpp index ce2588bc..e573c11d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit.cpp @@ -316,54 +316,64 @@ namespace coreinit } }; -void ci_Save(MemStreamWriter& s) +void coreinit_save(MemStreamWriter& s) { - s.writeData("ci_S", 15); + s.writeSection("coreinit"); s.writeData(gCoreinitData, sizeof(coreinitData_t)); s.writeBE(placeholderFont); s.writeBE(placeholderFontSize); - using namespace coreinit; - ci_CodeGen_Save(s); - ci_DynLoad_Save(s); - ci_FG_Save(s); - ci_GHS_Save(s); - ci_IPC_Save(s); - ci_LockedCache_Save(s); - ci_MEM_Save(s); - ci_MemoryMapping_Save(s); - ci_MessageQueue_Save(s); - ci_OverlayArena_Save(s); - ci_Sync_Save(s); - ci_SysHeap_Save(s); - ci_SystemInfo_Save(s); + coreinit_Init_Save(s); + coreinit::SysHeap_Save(s); + coreinit::Thread_Save(s); + coreinit::MEM_Save(s); + coreinit::FG_Save(s); + coreinit::OverlayArena_Save(s); + coreinit::DynLoad_Save(s); + coreinit::GHS_Save(s); + coreinit::LockedCache_Save(s); + coreinit::Alarm_Save(s); + coreinit::FS_Save(s); + coreinit::SystemInfo_Save(s); + coreinit::Synchronization_Save(s); + coreinit::MessageQueue_Save(s); + coreinit::IPC_Save(s); + coreinit::MemoryMapping_Save(s); + coreinit::CodeGen_Save(s); + coreinit_Callbacks_Save(s); } -void ci_Restore(MemStreamReader& s) +void coreinit_restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_S") == 0); + s.readSection("coreinit"); + + bool recreate = false; + if (recreate) + coreinit::__OSDeleteAllActivePPCThreads(); s.readData(gCoreinitData, sizeof(coreinitData_t)); - placeholderFont = s.readBE(); - placeholderFontSize = s.readBE(); + s.readBE(placeholderFont); + s.readBE(placeholderFontSize); - using namespace coreinit; - ci_CodeGen_Restore(s); - ci_DynLoad_Restore(s); - ci_FG_Restore(s); - ci_GHS_Restore(s); - ci_IPC_Restore(s); - ci_LockedCache_Restore(s); - ci_MEM_Restore(s); - ci_MemoryMapping_Restore(s); - ci_MessageQueue_Restore(s); - ci_OverlayArena_Restore(s); - ci_Sync_Restore(s); - ci_SysHeap_Restore(s); - ci_SystemInfo_Restore(s); + coreinit_Init_Restore(s); + coreinit::SysHeap_Restore(s); + coreinit::Thread_Restore(s, recreate); + coreinit::MEM_Restore(s); + coreinit::FG_Restore(s); + coreinit::OverlayArena_Restore(s); + coreinit::DynLoad_Restore(s); + coreinit::GHS_Restore(s); + coreinit::LockedCache_Restore(s); + coreinit::Alarm_Restore(s); + coreinit::FS_Restore(s); + coreinit::SystemInfo_Restore(s); + coreinit::Synchronization_Restore(s); + coreinit::MessageQueue_Restore(s); + coreinit::IPC_Restore(s); + coreinit::MemoryMapping_Restore(s); + coreinit::CodeGen_Restore(s); + coreinit_Callbacks_Restore(s); } void coreinit_load() diff --git a/src/Cafe/OS/libs/coreinit/coreinit.h b/src/Cafe/OS/libs/coreinit/coreinit.h index 81d80f08..c15cbe6d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.h +++ b/src/Cafe/OS/libs/coreinit/coreinit.h @@ -11,15 +11,15 @@ void InitializeAsyncCallback(); void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0); void coreinitAsyncCallback_addWithLock(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0); -void ci_Callbacks_Save(MemStreamWriter& s); -void ci_Callbacks_Restore(MemStreamReader& s); +void coreinit_Callbacks_Save(MemStreamWriter& s); +void coreinit_Callbacks_Restore(MemStreamReader& s); // misc -void coreinit_load(); +void coreinit_save(MemStreamWriter& s); +void coreinit_restore(MemStreamReader& s); -void ci_Save(MemStreamWriter& s); -void ci_Restore(MemStreamReader& s); +void coreinit_load(); // coreinit shared memory @@ -41,8 +41,8 @@ extern coreinitData_t* gCoreinitData; // coreinit init void coreinit_start(PPCInterpreter_t* hCPU); -void ci_Init_Save(MemStreamWriter& s); -void ci_Init_Restore(MemStreamReader& s); +void coreinit_Init_Save(MemStreamWriter& s); +void coreinit_Init_Restore(MemStreamReader& s); MPTR OSAllocFromSystem(uint32 size, uint32 alignment); void OSFreeToSystem(MPTR mem); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index d379d49c..bfc975fc 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -305,18 +305,18 @@ namespace coreinit __OSUnlockScheduler(); } - void ci_Alarm_Save(MemStreamWriter& s) + void Alarm_Save(MemStreamWriter& s) { - s.writeData("ci_A_S", 15); + s.writeSection("coreinit_Alarm"); - s.writeBE(g_alarmEvent.GetMPTR()); - s.writeBE(g_alarmThread.GetMPTR()); - s.writeBE(_g_alarmThreadStack.GetMPTR()); - s.writeBE(_g_alarmThreadName.GetMPTR()); + s.writeMPTR(g_alarmEvent); + s.writeMPTR(g_alarmThread); + s.writeMPTR(_g_alarmThreadStack); + s.writeMPTR(_g_alarmThreadName); s.writeBE(coreinit_getOSTime()); - s.writeBE(g_activeAlarms.size()); + s.writeBE((uint64)g_activeAlarms.size()); for (auto& itr : g_activeAlarms) { s.writeBE(memory_getVirtualOffsetFromPointer(itr.first)); @@ -324,23 +324,21 @@ namespace coreinit } } - void ci_Alarm_Restore(MemStreamReader& s) + void Alarm_Restore(MemStreamReader& s) { OSAlarm_Shutdown(); - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_A_S") == 0); + s.readSection("coreinit_Alarm"); - g_alarmEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE()); - g_alarmThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - _g_alarmThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); - _g_alarmThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readMPTR(g_alarmEvent); + s.readMPTR(g_alarmThread); + s.readMPTR(_g_alarmThreadStack); + s.readMPTR(_g_alarmThreadName); uint64 currentTime = coreinit_getOSTime(); uint64_t timeOffset = currentTime - s.readBE(); - size_t alms = s.readBE(); + size_t alms = s.readBE(); for (size_t alm = 0; alm < alms; alm++) { OSAlarm_t* alarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(s.readBE()); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h index 93523d68..5b75570f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h @@ -47,8 +47,8 @@ namespace coreinit void OSAlarm_Shutdown(); - void ci_Alarm_Save(MemStreamWriter& s); - void ci_Alarm_Restore(MemStreamReader& s); + void Alarm_Save(MemStreamWriter& s); + void Alarm_Restore(MemStreamReader& s); void alarm_update(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp index 9507249d..e080c3cb 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Callbacks.cpp @@ -31,14 +31,14 @@ struct CoreinitAsyncCallback s_asyncCallbackSpinlock.unlock(); } - static std::vector* getPoolPtr() + static std::vector& getPool() { - return &s_asyncCallbackPool; + return s_asyncCallbackPool; } - static std::vector* getQueuePtr() + static std::vector& getQueue() { - return &s_asyncCallbackQueue; + return s_asyncCallbackQueue; } friend void ci_Callbacks_Save(MemStreamWriter& s); @@ -117,48 +117,26 @@ void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r coreinitAsyncCallback_addWithLock(functionMPTR, numParameters, r3, r4, r5, r6, r7, r8, r9, r10); } -void ci_Callbacks_Save(MemStreamWriter& s) +void coreinit_Callbacks_Save(MemStreamWriter& s) { - s.writeData("ci_C_S", 15); - - s.writeBE(g_coreinitCallbackThread.GetMPTR()); - s.writeBE(_g_coreinitCallbackThreadStack.GetMPTR()); - s.writeBE(g_asyncCallbackAsync.GetMPTR()); - s.writeBE(_g_coreinitCBThreadName.GetMPTR()); - - std::vector* pool = CoreinitAsyncCallback::getPoolPtr(); - size_t poolSize = pool->size(); - s.writeBE(poolSize); - s.writeData(pool, sizeof(CoreinitAsyncCallback) * poolSize); - - std::vector* queue = CoreinitAsyncCallback::getQueuePtr(); - size_t queueSize = queue->size(); - s.writeBE(queueSize); - s.writeData(queue, sizeof(CoreinitAsyncCallback) * queueSize); + s.writeSection("coreinit_Callbacks"); + s.writeMPTR(g_coreinitCallbackThread); + s.writeMPTR(_g_coreinitCallbackThreadStack); + s.writeMPTR(g_asyncCallbackAsync); + s.writeMPTR(_g_coreinitCBThreadName); + s.writePODVector(CoreinitAsyncCallback::getPool()); + s.writePODVector(CoreinitAsyncCallback::getQueue()); } -void ci_Callbacks_Restore(MemStreamReader& s) +void coreinit_Callbacks_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_C_S") == 0); - - g_coreinitCallbackThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - _g_coreinitCallbackThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); - g_asyncCallbackAsync = (coreinit::OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE()); - _g_coreinitCBThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); - - std::vector* pool = CoreinitAsyncCallback::getPoolPtr(); - size_t poolSize = s.readBE(); - pool->clear(); - pool->resize(poolSize); - s.readData(pool, sizeof(CoreinitAsyncCallback) * poolSize); - - std::vector* queue = CoreinitAsyncCallback::getPoolPtr(); - size_t queueSize = s.readBE(); - queue->clear(); - queue->resize(queueSize); - s.readData(queue, sizeof(CoreinitAsyncCallback) * queueSize); + s.readSection("coreinit_Callbacks"); + s.readMPTR(g_coreinitCallbackThread); + s.readMPTR(_g_coreinitCallbackThreadStack); + s.readMPTR(g_asyncCallbackAsync); + s.readMPTR(_g_coreinitCBThreadName); + s.readPODVector(CoreinitAsyncCallback::getPool()); + s.readPODVector(CoreinitAsyncCallback::getQueue()); } void InitializeAsyncCallback() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp index c27c1a52..7fea2b46 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp @@ -136,18 +136,15 @@ namespace coreinit return true; } - void ci_CodeGen_Save(MemStreamWriter& s) + void CodeGen_Save(MemStreamWriter& s) { - s.writeData("ci_CG_S", 15); + s.writeSection("coreinit_CodeGen"); s.writeData(&coreinitCodeGen, sizeof(coreinitCodeGen)); } - void ci_CodeGen_Restore(MemStreamReader& s) + void CodeGen_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_CG_S") == 0); - + s.readSection("coreinit_CodeGen"); s.readData(&coreinitCodeGen, sizeof(coreinitCodeGen)); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h index f7bdff04..ffc4ad68 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.h @@ -6,8 +6,8 @@ namespace coreinit void codeGenHandleICBI(uint32 ea); bool codeGenShouldAvoid(); - void ci_CodeGen_Save(MemStreamWriter& s); - void ci_CodeGen_Restore(MemStreamReader& s); + void CodeGen_Save(MemStreamWriter& s); + void CodeGen_Restore(MemStreamReader& s); void InitializeCodeGen(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp index 4a3db30e..35e1447c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp @@ -129,26 +129,22 @@ namespace coreinit return 0; } - void ci_DynLoad_Save(MemStreamWriter& s) + void DynLoad_Save(MemStreamWriter& s) { - s.writeData("ci_DL_S", 15); - + s.writeSection("coreinit_DynLoad"); s.writeBE(_osDynLoadFuncAlloc); s.writeBE(_osDynLoadFuncFree); s.writeBE(_osDynLoadTLSFuncAlloc); s.writeBE(_osDynLoadTLSFuncFree); } - void ci_DynLoad_Restore(MemStreamReader& s) + void DynLoad_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_DL_S") == 0); - - _osDynLoadFuncAlloc = s.readBE(); - _osDynLoadFuncFree = s.readBE(); - _osDynLoadTLSFuncAlloc = s.readBE(); - _osDynLoadTLSFuncFree = s.readBE(); + s.readSection("coreinit_DynLoad"); + s.readBE(_osDynLoadFuncAlloc); + s.readBE(_osDynLoadFuncFree); + s.readBE(_osDynLoadTLSFuncAlloc); + s.readBE(_osDynLoadTLSFuncFree); } void InitializeDynLoad() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h index c31040a9..8eaa4bcb 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.h @@ -14,8 +14,8 @@ namespace coreinit void OSDynLoad_Release(uint32 moduleHandle); uint32 OSDynLoad_FindExport(uint32 moduleHandle, uint32 isData, const char* exportName, betype* addrOut); - void ci_DynLoad_Save(MemStreamWriter& s); - void ci_DynLoad_Restore(MemStreamReader& s); + void DynLoad_Save(MemStreamWriter& s); + void DynLoad_Restore(MemStreamReader& s); void InitializeDynLoad(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp index 457aa01e..1aead0ca 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FG.cpp @@ -191,23 +191,19 @@ namespace coreinit osLib_returnFromFunction(hCPU, r ? 1 : 0); } - void ci_FG_Save(MemStreamWriter& s) + void FG_Save(MemStreamWriter& s) { - s.writeData("ci_FG_S", 15); - - s.writeBE(fgAddr.GetMPTR()); - s.writeBE(fgSaveAreaAddr.GetMPTR()); + s.writeSection("coreinit_FG"); + s.writeMPTR(fgAddr); + s.writeMPTR(fgSaveAreaAddr); s.writeData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT); } - void ci_FG_Restore(MemStreamReader& s) + void FG_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_FG_S") == 0); - - fgAddr = memory_getPointerFromVirtualOffset(s.readBE()); - fgSaveAreaAddr = memory_getPointerFromVirtualOffset(s.readBE()); + s.readSection("coreinit_FG"); + s.readMPTR(fgAddr); + s.readMPTR(fgSaveAreaAddr); s.readData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FG.h b/src/Cafe/OS/libs/coreinit/coreinit_FG.h index fcc88b4f..07f272d0 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FG.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_FG.h @@ -13,8 +13,8 @@ namespace coreinit void InitForegroundBucket(); - void ci_FG_Save(MemStreamWriter& s); - void ci_FG_Restore(MemStreamReader& s); + void FG_Save(MemStreamWriter& s); + void FG_Restore(MemStreamReader& s); void InitializeFG(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp index c230d14f..ca840517 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp @@ -2638,38 +2638,30 @@ namespace coreinit return FSA_RESULT::OK; } - void ci_FS_Save(MemStreamWriter& s) + void FS_Save(MemStreamWriter& s) { - s.writeData("ci_FS_S", 15); + s.writeSection("coreinit_FS"); s.writeData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); - s.writeBE(_sdCard01Mounted); - s.writeBE(_mlc01Mounted); - s.writeBE(_tempFSSpace.GetMPTR()); - size_t s_fsa_activeClients_size = s_fsa_activeClients.size(); - s.writeBE(s_fsa_activeClients_size); - s.writeData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size); - s.writeBE(s_fsaIpcPool.GetMPTR()); - s.writeBE(s_fsaIpcPoolBuffer.GetMPTR()); - s.writeBE(s_fsaIpcPoolBufferNumItems.GetMPTR()); + s.writeBool(_sdCard01Mounted); + s.writeBool(_mlc01Mounted); + s.writeMPTR(_tempFSSpace); + s.writePODVector(s_fsa_activeClients); + s.writeMPTR(s_fsaIpcPool); + s.writeMPTR(s_fsaIpcPoolBuffer); + s.writeMPTR(s_fsaIpcPoolBufferNumItems); } - void ci_FS_Restore(MemStreamReader& s) + void FS_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_FS_S") == 0); - + s.readSection("coreinit_FS"); s.readData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); - _sdCard01Mounted = s.readBE(); - _mlc01Mounted = s.readBE(); - _tempFSSpace = memory_getPointerFromVirtualOffset(s.readBE()); - size_t s_fsa_activeClients_size = s.readBE(); - s_fsa_activeClients.clear(); - s_fsa_activeClients.resize(s_fsa_activeClients_size); - s.readData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size); - s_fsaIpcPool = (IPCBufPool_t*)memory_getPointerFromVirtualOffset(s.readBE()); - s_fsaIpcPoolBuffer = memory_getPointerFromVirtualOffset(s.readBE()); - s_fsaIpcPoolBufferNumItems = (uint32be*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readBool(_sdCard01Mounted); + s.readBool(_mlc01Mounted); + s.readMPTR(_tempFSSpace); + s.readPODVector(s_fsa_activeClients); + s.readMPTR(s_fsaIpcPool); + s.readMPTR(s_fsaIpcPoolBuffer); + s.readMPTR(s_fsaIpcPoolBufferNumItems); } void InitializeFS() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.h b/src/Cafe/OS/libs/coreinit/coreinit_FS.h index 0b576126..7a9fc72c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.h @@ -308,8 +308,8 @@ namespace coreinit FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient); - void ci_FS_Save(MemStreamWriter& s); - void ci_FS_Restore(MemStreamReader& s); + void FS_Save(MemStreamWriter& s); + void FS_Restore(MemStreamReader& s); void InitializeFS(); }; // namespace coreinit diff --git a/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp index f967781f..d17b466c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_GHS.cpp @@ -258,24 +258,22 @@ namespace coreinit return memory_getPointerFromVirtualOffset(_swapEndianU32(tlsBlock->addr) + _swapEndianU32(tlsIndex->ukn04)); } - void ci_GHS_Save(MemStreamWriter& s) + void GHS_Save(MemStreamWriter& s) { - s.writeData("ci_GHS_S", 15); - - s.writeBE(g_ghs_data.GetMPTR()); - s.writeBE(_flockMutexArray.GetMPTR()); - s.writeData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX); + s.writeSection("coreinit_GHS"); + s.writeMPTR(g_ghs_data); + s.writeMPTR(_flockMutexArray); + s.writeData(reinterpret_cast(_flockMutexMask), sizeof(uint8) * GHS_FOPEN_MAX); } - void ci_GHS_Restore(MemStreamReader& s) + void GHS_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_GHS_S") == 0); - - g_ghs_data = (GHSAccessibleData*)memory_getPointerFromVirtualOffset(s.readBE()); - _flockMutexArray = (coreinit::OSMutex*)memory_getPointerFromVirtualOffset(s.readBE()); - s.readData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX); + s.readSection("coreinit_GHS"); + s.readMPTR(g_ghs_data); + s.readMPTR(_flockMutexArray); + uint8 _flockMutexMaskTmp[GHS_FOPEN_MAX] = { 0 }; + s.readData(_flockMutexMaskTmp, sizeof(uint8) * GHS_FOPEN_MAX); + memcpy(_flockMutexMask, reinterpret_cast(_flockMutexMaskTmp), sizeof(bool) * GHS_FOPEN_MAX); } void InitializeGHS() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_GHS.h b/src/Cafe/OS/libs/coreinit/coreinit_GHS.h index 3cc64445..fbef43c7 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_GHS.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_GHS.h @@ -4,8 +4,8 @@ namespace coreinit { void PrepareGHSRuntime(); - void ci_GHS_Save(MemStreamWriter& s); - void ci_GHS_Restore(MemStreamReader& s); + void GHS_Save(MemStreamWriter& s); + void GHS_Restore(MemStreamReader& s); void InitializeGHS(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp index 6a582203..75ef6131 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp @@ -462,32 +462,28 @@ namespace coreinit return r; } - void ci_IPC_Save(MemStreamWriter& s) + void IPC_Save(MemStreamWriter& s) { - s.writeData("ci_IPC_S", 15); - - s.writeBE(s_ipcResourceBuffers.GetMPTR()); - s.writeBE(s_ipcDriver.GetMPTR()); - s.writeBE(gIPCThread.GetMPTR()); - s.writeBE(_gIPCThreadStack.GetMPTR()); - s.writeBE(_gIPCThreadNameStorage.GetMPTR()); - s.writeBE(gIPCThreadMsgQueue.GetMPTR()); - s.writeBE(_gIPCThreadSemaphoreStorage.GetMPTR()); + s.writeSection("coreinit_IPC"); + s.writeMPTR(s_ipcResourceBuffers); + s.writeMPTR(s_ipcDriver); + s.writeMPTR(gIPCThread); + s.writeMPTR(_gIPCThreadStack); + s.writeMPTR(_gIPCThreadNameStorage); + s.writeMPTR(gIPCThreadMsgQueue); + s.writeMPTR(_gIPCThreadSemaphoreStorage); } - void ci_IPC_Restore(MemStreamReader& s) + void IPC_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_IPC_S") == 0); - - s_ipcResourceBuffers = (IPCResourceBuffer*)memory_getPointerFromVirtualOffset(s.readBE()); - s_ipcDriver = (IPCDriver*)memory_getPointerFromVirtualOffset(s.readBE()); - gIPCThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - _gIPCThreadStack = memory_getPointerFromVirtualOffset(s.readBE()); - _gIPCThreadNameStorage = memory_getPointerFromVirtualOffset(s.readBE()); - gIPCThreadMsgQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE()); - _gIPCThreadSemaphoreStorage = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readSection("coreinit_IPC"); + s.readMPTR(s_ipcResourceBuffers); + s.readMPTR(s_ipcDriver); + s.readMPTR(gIPCThread); + s.readMPTR(_gIPCThreadStack); + s.readMPTR(_gIPCThreadNameStorage); + s.readMPTR(gIPCThreadMsgQueue); + s.readMPTR(_gIPCThreadSemaphoreStorage); } void InitializeIPC() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h index f379773e..dc20dcfb 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h @@ -12,8 +12,8 @@ namespace coreinit IOS_ERROR IOS_Ioctlv(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec); IOS_ERROR IOS_IoctlvAsync(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec, MEMPTR asyncResultFunc, MEMPTR asyncResultUserParam); - void ci_IPC_Save(MemStreamWriter& s); - void ci_IPC_Restore(MemStreamReader& s); + void IPC_Save(MemStreamWriter& s); + void IPC_Restore(MemStreamReader& s); void InitializeIPC(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp index 591a3c61..0d7cb477 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp @@ -216,24 +216,20 @@ void coreinit_start(PPCInterpreter_t* hCPU) hCPU->instructionPointer = _coreinitTitleEntryPoint; } -void ci_Init_Save(MemStreamWriter& s) +void coreinit_Init_Save(MemStreamWriter& s) { - s.writeData("ci_Init_S", 15); - + s.writeSection("coreinit_Init"); s.writeData(_coreinitInfo, sizeof(coreinitInit_t)); s.writeBE(argStorageIndex); - s.writeBE(g_preinitUserParam.GetMPTR()); + s.writeMPTR(g_preinitUserParam); s.writeBE(_coreinitTitleEntryPoint); } -void ci_Init_Restore(MemStreamReader& s) +void coreinit_Init_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_Init_S") == 0); - + s.readSection("coreinit_Init"); s.readData(_coreinitInfo, sizeof(coreinitInit_t)); - argStorageIndex = s.readBE(); - g_preinitUserParam = (PreinitUserHeapStruct*)memory_getPointerFromVirtualOffset(s.readBE()); - _coreinitTitleEntryPoint = s.readBE(); + s.readBE(argStorageIndex); + s.readMPTR(g_preinitUserParam); + s.readBE(_coreinitTitleEntryPoint); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp index b330f979..05fd1645 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp @@ -271,24 +271,20 @@ namespace coreinit osLib_returnFromFunction(hCPU, 0); } - void ci_LockedCache_Save(MemStreamWriter& s) + void LockedCache_Save(MemStreamWriter& s) { - s.writeData("ci_LC_S", 15); - + s.writeSection("coreinit_LockedCache"); s.writeData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); s.writeData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); s.writeBE(_lcDisableErrorCounter); } - void ci_LockedCache_Restore(MemStreamReader& s) + void LockedCache_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_LC_S") == 0); - + s.readSection("coreinit_LockedCache"); s.readData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); s.readData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); - _lcDisableErrorCounter = s.readBE(); + s.readBE(_lcDisableErrorCounter); } void InitializeLC() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h index 89d2b11c..3ef21993 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.h @@ -2,8 +2,8 @@ namespace coreinit { - void ci_LockedCache_Save(MemStreamWriter& s); - void ci_LockedCache_Restore(MemStreamReader& s); + void LockedCache_Save(MemStreamWriter& s); + void LockedCache_Restore(MemStreamReader& s); void InitializeLC(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp index cfbeee5e..e7594de1 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp @@ -630,44 +630,40 @@ namespace coreinit memset(&g_list3, 0, sizeof(g_list3)); } - void ci_MEM_Save(MemStreamWriter& s) + void MEM_Save(MemStreamWriter& s) { - s.writeData("ci_MEM_S", 15); - + s.writeSection("coreinit_MEM"); s.writeBE(sysAreaAllocatorOffset); s.writeBE(g_heapTableCount); s.writeData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); - s.writeBE(g_slockInitialized); - s.writeBE(g_listsInitialized); + s.writeBool(g_slockInitialized); + s.writeBool(g_listsInitialized); s.writeData(&g_list1, sizeof(MEMList)); s.writeData(&g_list2, sizeof(MEMList)); s.writeData(&g_list3, sizeof(MEMList)); s.writeData(&gHeapFillValues, sizeof(uint32) * 3); - s.writeBE(gHeapGlobalLock.GetMPTR()); + s.writeMPTR(gHeapGlobalLock); s.writeData(&gDefaultHeap, sizeof(MEMHeapBase)); s.writeData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9); - s.writeBE(gDefaultHeapAllocator.GetMPTR()); + s.writeMPTR(gDefaultHeapAllocator); } - void ci_MEM_Restore(MemStreamReader& s) + void MEM_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_MEM_S") == 0); - - sysAreaAllocatorOffset = s.readBE(); - g_heapTableCount = s.readBE(); + s.readSection("coreinit_MEM"); + s.readBE(sysAreaAllocatorOffset); + s.readBE(g_heapTableCount); s.readData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); - g_slockInitialized = s.readBE(); - g_listsInitialized = s.readBE(); + s.readBool(g_slockInitialized); + s.readBool(g_listsInitialized); s.readData(&g_list1, sizeof(MEMList)); s.readData(&g_list2, sizeof(MEMList)); s.readData(&g_list3, sizeof(MEMList)); s.readData(&gHeapFillValues, sizeof(uint32) * 3); - gHeapGlobalLock = (OSSpinLock*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readMPTR(gHeapGlobalLock); s.readData(&gDefaultHeap, sizeof(MEMHeapBase)); s.readData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9); - gDefaultHeapAllocator = (MEMAllocatorFunc*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readMPTR(gDefaultHeapAllocator); } void InitializeMEM() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MEM.h b/src/Cafe/OS/libs/coreinit/coreinit_MEM.h index f057fa0f..7420fe5b 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MEM.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MEM.h @@ -179,8 +179,8 @@ namespace coreinit void InitializeMEMUnitHeap(); - void ci_MEM_Save(MemStreamWriter& s); - void ci_MEM_Restore(MemStreamReader& s); + void MEM_Save(MemStreamWriter& s); + void MEM_Restore(MemStreamReader& s); void InitializeMEM(); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp index cfeb94b7..fbdc366f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp @@ -153,25 +153,16 @@ namespace coreinit return 1; } - void ci_MemoryMapping_Save(MemStreamWriter& s) + void MemoryMapping_Save(MemStreamWriter& s) { - s.writeData("ci_MemMap_S", 15); - - size_t s_allocatedVirtMemorySize = s_allocatedVirtMemory.size(); - s.writeBE(s_allocatedVirtMemorySize); - s.writeData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize); + s.writeSection("coreinit_MemoryMapping "); + s.writePODVector(s_allocatedVirtMemory); } - void ci_MemoryMapping_Restore(MemStreamReader& s) + void MemoryMapping_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_MemMap_S") == 0); - - size_t s_allocatedVirtMemorySize = s.readBE(); - s_allocatedVirtMemory.clear(); - s_allocatedVirtMemory.resize(s_allocatedVirtMemorySize); - s.readData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize); + s.readSection("coreinit_MemoryMapping "); + s.readPODVector(s_allocatedVirtMemory); } void InitializeMemoryMapping() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h index 5988fa39..a884fa3f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.h @@ -1,8 +1,8 @@ namespace coreinit { - void ci_MemoryMapping_Save(MemStreamWriter& s); - void ci_MemoryMapping_Restore(MemStreamReader& s); + void MemoryMapping_Save(MemStreamWriter& s); + void MemoryMapping_Restore(MemStreamReader& s); void InitializeMemoryMapping(); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp index dce041e1..b1789a4f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.cpp @@ -117,22 +117,18 @@ namespace coreinit return g_systemMessageQueue.GetPtr(); } - void ci_MessageQueue_Save(MemStreamWriter& s) + void MessageQueue_Save(MemStreamWriter& s) { - s.writeData("ci_MessQue_S", 15); - - s.writeBE(g_systemMessageQueue.GetMPTR()); - s.writeBE(_systemMessageQueueArray.GetMPTR()); + s.writeSection("coreinit_MessageQueue"); + s.writeMPTR(g_systemMessageQueue); + s.writeMPTR(_systemMessageQueueArray); } - void ci_MessageQueue_Restore(MemStreamReader& s) + void MessageQueue_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_MessQue_S") == 0); - - g_systemMessageQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE()); - _systemMessageQueueArray = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readSection("coreinit_MessageQueue"); + s.readMPTR(g_systemMessageQueue); + s.readMPTR(_systemMessageQueueArray); } void InitializeMessageQueue() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h index 97343c13..2f31022a 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_MessageQueue.h @@ -36,8 +36,8 @@ namespace coreinit bool OSPeekMessage(OSMessageQueue* msgQueue, OSMessage* msg); sint32 OSSendMessage(OSMessageQueue* msgQueue, OSMessage* msg, uint32 flags); - void ci_MessageQueue_Save(MemStreamWriter& s); - void ci_MessageQueue_Restore(MemStreamReader& s); + void MessageQueue_Save(MemStreamWriter& s); + void MessageQueue_Restore(MemStreamReader& s); void InitializeMessageQueue(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp index 962a9a94..85978484 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.cpp @@ -25,19 +25,15 @@ namespace coreinit *areaSize = MEMORY_OVERLAY_AREA_SIZE; } - void ci_OverlayArena_Save(MemStreamWriter& s) + void OverlayArena_Save(MemStreamWriter& s) { - s.writeData("ci_OverArea_S", 15); - - s.writeData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena)); + s.writeSection("coreinit_OverlayArena"); + s.writeBool(g_coreinitOverlayArena.isEnabled); } - void ci_OverlayArena_Restore(MemStreamReader& s) + void OverlayArena_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_OverArea_S") == 0); - - s.readData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena)); + s.readSection("coreinit_OverlayArena"); + s.readBool(g_coreinitOverlayArena.isEnabled); } void InitializeOverlayArena() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h index 52cb4dbc..70657fc9 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_OverlayArena.h @@ -1,7 +1,7 @@ namespace coreinit { - void ci_OverlayArena_Save(MemStreamWriter& s); - void ci_OverlayArena_Restore(MemStreamReader& s); + void OverlayArena_Save(MemStreamWriter& s); + void OverlayArena_Restore(MemStreamReader& s); void InitializeOverlayArena(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp index 4e818e24..cab6d072 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Synchronization.cpp @@ -614,20 +614,16 @@ namespace coreinit OSWakeupThread(&fastCond->threadQueue); } - void ci_Sync_Save(MemStreamWriter& s) + void Synchronization_Save(MemStreamWriter& s) { - s.writeData("ci_Sync_S", 15); - - s.writeBE(g_rendezvousEvent.GetMPTR()); + s.writeSection("coreinit_Synchronization"); + s.writeMPTR(g_rendezvousEvent); } - void ci_Sync_Restore(MemStreamReader& s) + void Synchronization_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_Sync_S") == 0); - - g_rendezvousEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readSection("coreinit_Synchronization"); + s.readMPTR(g_rendezvousEvent); } /************* init ************/ diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp index 41a47295..43d5bbf7 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp @@ -32,24 +32,20 @@ namespace coreinit _sysHeapFreeCounter = 0; } - void ci_SysHeap_Save(MemStreamWriter& s) + void SysHeap_Save(MemStreamWriter& s) { - s.writeData("ci_SysHeap_S", 15); - + s.writeSection("coreinit_SysHeap"); s.writeData(_sysHeapHandle, sizeof(MEMHeapBase)); s.writeBE(_sysHeapAllocCounter); s.writeBE(_sysHeapFreeCounter); } - void ci_SysHeap_Restore(MemStreamReader& s) + void SysHeap_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_SysHeap_S") == 0); - + s.readSection("coreinit_SysHeap"); s.readData(_sysHeapHandle, sizeof(MEMHeapBase)); - _sysHeapAllocCounter = s.readBE(); - _sysHeapFreeCounter = s.readBE(); + s.readBE(_sysHeapAllocCounter); + s.readBE(_sysHeapFreeCounter); } void InitializeSysHeap() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h index 3001438a..23ab51e1 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.h @@ -4,8 +4,8 @@ namespace coreinit { void InitSysHeap(); - void ci_SysHeap_Save(MemStreamWriter& s); - void ci_SysHeap_Restore(MemStreamReader& s); + void SysHeap_Save(MemStreamWriter& s); + void SysHeap_Restore(MemStreamReader& s); void InitializeSysHeap(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp index 64bb4ff9..638d4093 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.cpp @@ -10,20 +10,16 @@ namespace coreinit return *g_system_info.GetPtr(); } - void ci_SystemInfo_Save(MemStreamWriter& s) + void SystemInfo_Save(MemStreamWriter& s) { - s.writeData("ci_SysInfo_S", 15); - - s.writeBE(g_system_info.GetMPTR()); + s.writeSection("coreinit_SysInfo"); + s.writeMPTR(g_system_info); } - void ci_SystemInfo_Restore(MemStreamReader& s) + void SystemInfo_Restore(MemStreamReader& s) { - char section[16] = { '\0' }; - s.readData(section, 15); - cemu_assert_debug(strcmp(section, "ci_SysInfo_S") == 0); - - g_system_info = (OSSystemInfo*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readSection("coreinit_SysInfo"); + s.readMPTR(g_system_info); } void InitializeSystemInfo() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h index 49a52625..478dd4f8 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_SystemInfo.h @@ -16,8 +16,8 @@ namespace coreinit const OSSystemInfo& OSGetSystemInfo(); - void ci_SystemInfo_Save(MemStreamWriter& s); - void ci_SystemInfo_Restore(MemStreamReader& s); + void SystemInfo_Save(MemStreamWriter& s); + void SystemInfo_Restore(MemStreamReader& s); void InitializeSystemInfo(); }; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index 590f625c..3237cf61 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -1331,12 +1331,13 @@ namespace coreinit } } - void ci_Thread_Save(MemStreamWriter& s) + void Thread_Save(MemStreamWriter& s) { - s.writeData("ci_T_S", 15); + s.writeSection("coreinit_Thread"); - s.writeBE(g_activeThreadQueue.GetMPTR()); - s.writeBE(g_coreRunQueue.GetMPTR()); + s.writeBE((uint8)sSchedulerActive.load()); + s.writeMPTR(g_activeThreadQueue); + s.writeMPTR(g_coreRunQueue); s.writeBE(activeThreadCount); for (sint32 i = 0; i < activeThreadCount; i++) @@ -1345,25 +1346,25 @@ namespace coreinit } for (sint32 i = 0; i < PPC_CORE_COUNT; i++) { - s.writeBE(memory_getVirtualOffsetFromPointer(__currentCoreThread[i])); + s.writePTR(__currentCoreThread[i]); s.writeBE(s_lehmer_lcg[i]); - s.writeBE(s_terminatorThreads[i].terminatorThread.GetMPTR()); - s.writeBE(s_terminatorThreads[i].threadStack.GetMPTR()); - s.writeBE(s_terminatorThreads[i].threadName.GetMPTR()); - s.writeBE(s_terminatorThreads[i].semaphoreQueuedDeallocators.GetMPTR()); + s.writeMPTR(s_terminatorThreads[i].terminatorThread); + s.writeMPTR(s_terminatorThreads[i].threadStack); + s.writeMPTR(s_terminatorThreads[i].threadName); + s.writeMPTR(s_terminatorThreads[i].semaphoreQueuedDeallocators); + s.writeMPTR(_defaultThreadName[i]); } - s.writeBE(s_defaultThreads.GetMPTR()); - s.writeBE(s_stack.GetMPTR()); + s.writeMPTR(s_defaultThreads); + s.writeMPTR(s_stack); } - void ci_Thread_Restore(MemStreamReader& s, bool recreate) + void Thread_Restore(MemStreamReader& s, bool recreate) { - char section[16] = { '\0' }; - s.readData(section,15); - cemu_assert_debug(strcmp(section, "ci_T_S") == 0); + s.readSection("coreinit_Thread"); - g_activeThreadQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE()); - g_coreRunQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE()); + sSchedulerActive.store(s.readBE()); + s.readMPTR(g_activeThreadQueue); + s.readMPTR(g_coreRunQueue); sint32 prevActiveThreadCount = s.readBE(); for (sint32 i = 0; i < prevActiveThreadCount; i++) @@ -1383,15 +1384,16 @@ namespace coreinit } for (sint32 i = 0; i < PPC_CORE_COUNT; i++) { - __currentCoreThread[i] = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - s_lehmer_lcg[i] = s.readBE(); - s_terminatorThreads[i].terminatorThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - s_terminatorThreads[i].threadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); - s_terminatorThreads[i].threadName = (char*)memory_getPointerFromVirtualOffset(s.readBE()); - s_terminatorThreads[i].semaphoreQueuedDeallocators = (OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readPTR(__currentCoreThread[i]); + s.readBE(s_lehmer_lcg[i]); + s.readMPTR(s_terminatorThreads[i].terminatorThread); + s.readMPTR(s_terminatorThreads[i].threadStack); + s.readMPTR(s_terminatorThreads[i].threadName); + s.readMPTR(s_terminatorThreads[i].semaphoreQueuedDeallocators); + s.readMPTR(_defaultThreadName[i]); } - s_defaultThreads = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE()); - s_stack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE()); + s.readMPTR(s_defaultThreads); + s.readMPTR(s_stack); } void SuspendActiveThreads() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index 321ddb3f..de042da6 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -496,15 +496,15 @@ static_assert(sizeof(OSThread_t) == 0x6A0-4); // todo - determine correct size namespace coreinit { - void ci_Thread_Save(MemStreamWriter& s); - void ci_Thread_Restore(MemStreamReader& s, bool recreate); + void Thread_Save(MemStreamWriter& s); + void Thread_Restore(MemStreamReader& s, bool recreate); void SuspendActiveThreads(); void ResumeActiveThreads(); void InitializeThread(); - void ci_Sync_Save(MemStreamWriter& s); - void ci_Sync_Restore(MemStreamReader& s); + void Synchronization_Save(MemStreamWriter& s); + void Synchronization_Restore(MemStreamReader& s); void InitializeConcurrency(); diff --git a/src/Cafe/OS/libs/dmae/dmae.cpp b/src/Cafe/OS/libs/dmae/dmae.cpp index 6b3e8d0d..1a02f61a 100644 --- a/src/Cafe/OS/libs/dmae/dmae.cpp +++ b/src/Cafe/OS/libs/dmae/dmae.cpp @@ -108,6 +108,17 @@ void dmaeExport_DMAEGetRetiredTimeStamp(PPCInterpreter_t* hCPU) osLib_returnFromFunction64(hCPU, dmaeRetiredTimestamp); } +void dmae_save(MemStreamWriter& s) +{ + s.writeSection("dmae"); + s.writeBE(dmaeRetiredTimestamp); +} + +void dmae_restore(MemStreamReader& s) +{ + s.readSection("dmae"); + s.readBE(dmaeRetiredTimestamp); +} void dmae_load() { diff --git a/src/Cafe/OS/libs/dmae/dmae.h b/src/Cafe/OS/libs/dmae/dmae.h index 26d371c9..74acef4c 100644 --- a/src/Cafe/OS/libs/dmae/dmae.h +++ b/src/Cafe/OS/libs/dmae/dmae.h @@ -1 +1,4 @@ +void dmae_save(MemStreamWriter& s); +void dmae_restore(MemStreamReader& s); + void dmae_load(); \ No newline at end of file diff --git a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp index 9afb9f85..fafa21ed 100644 --- a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp +++ b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp @@ -1354,6 +1354,29 @@ void export_curl_global_init_mem(PPCInterpreter_t* hCPU) osLib_returnFromFunction(hCPU, result); } +void save(MemStreamWriter& s) +{ + s.writeSection("nlibcurl"); + s.writeBE(g_nlibcurl.initialized); + s.writeMPTR(g_nlibcurl.proxyConfig); + s.writeMPTR(g_nlibcurl.malloc); + s.writeMPTR(g_nlibcurl.free); + s.writeMPTR(g_nlibcurl.realloc); + s.writeMPTR(g_nlibcurl.strdup); + s.writeMPTR(g_nlibcurl.calloc); +} +void restore(MemStreamReader& s) +{ + s.readSection("nlibcurl"); + s.readBE(g_nlibcurl.initialized); + s.readMPTR(g_nlibcurl.proxyConfig); + s.readMPTR(g_nlibcurl.malloc); + s.readMPTR(g_nlibcurl.free); + s.readMPTR(g_nlibcurl.realloc); + s.readMPTR(g_nlibcurl.strdup); + s.readMPTR(g_nlibcurl.calloc); +} + void load() { osLib_addFunction("nlibcurl", "curl_global_init_mem", export_curl_global_init_mem); diff --git a/src/Cafe/OS/libs/nlibcurl/nlibcurl.h b/src/Cafe/OS/libs/nlibcurl/nlibcurl.h index 5075a79c..273b5a6b 100644 --- a/src/Cafe/OS/libs/nlibcurl/nlibcurl.h +++ b/src/Cafe/OS/libs/nlibcurl/nlibcurl.h @@ -2,5 +2,8 @@ namespace nlibcurl { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void load(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/nn_acp/nn_acp.cpp b/src/Cafe/OS/libs/nn_acp/nn_acp.cpp index 516087a3..4d661d55 100644 --- a/src/Cafe/OS/libs/nn_acp/nn_acp.cpp +++ b/src/Cafe/OS/libs/nn_acp/nn_acp.cpp @@ -490,6 +490,18 @@ namespace acp osLib_returnFromFunction(hCPU, 0); } + void save(MemStreamWriter& s) + { + s.writeSection("nn_acp"); + s.writeBool(sSaveDirMounted); + } + + void restore(MemStreamReader& s) + { + s.readSection("nn_acp"); + s.readBool(sSaveDirMounted); + } + void load() { cafeExportRegister("nn_acp", ACPCheckApplicationDeviceEmulation, LogType::Placeholder); diff --git a/src/Cafe/OS/libs/nn_acp/nn_acp.h b/src/Cafe/OS/libs/nn_acp/nn_acp.h index cbf36c64..b4d8d4ce 100644 --- a/src/Cafe/OS/libs/nn_acp/nn_acp.h +++ b/src/Cafe/OS/libs/nn_acp/nn_acp.h @@ -24,6 +24,9 @@ namespace acp ACPStatus ACPCreateSaveDir(uint32 persistentId, ACPDeviceType type); ACPStatus ACPUpdateSaveTimeStamp(uint32 persistentId, uint64 titleId, ACPDeviceType deviceType);; + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void load(); } } diff --git a/src/Cafe/OS/libs/nn_act/nn_act.cpp b/src/Cafe/OS/libs/nn_act/nn_act.cpp index fb1d4d14..f9b52871 100644 --- a/src/Cafe/OS/libs/nn_act/nn_act.cpp +++ b/src/Cafe/OS/libs/nn_act/nn_act.cpp @@ -664,6 +664,19 @@ void nnActExport_AcquirePrincipalIdByAccountId(PPCInterpreter_t* hCPU) osLib_returnFromFunction(hCPU, result); } +void nnAct_save(MemStreamWriter& s) +{ + s.writeSection("nn_act"); + s.writeBE(nn::act::g_initializeCount); + s.writeBE((uint32)g_isParentalControlCheckEnabled); +} +void nnAct_restore(MemStreamReader& s) +{ + s.readSection("nn_act"); + s.readBE(nn::act::g_initializeCount); + g_isParentalControlCheckEnabled = s.readBE(); +} + // register account functions void nnAct_load() { diff --git a/src/Cafe/OS/libs/nn_act/nn_act.h b/src/Cafe/OS/libs/nn_act/nn_act.h index 6b0a1236..e0d0f9d6 100644 --- a/src/Cafe/OS/libs/nn_act/nn_act.h +++ b/src/Cafe/OS/libs/nn_act/nn_act.h @@ -33,4 +33,7 @@ namespace act } } +void nnAct_save(MemStreamWriter& s); +void nnAct_restore(MemStreamReader& s); + void nnAct_load(); \ No newline at end of file diff --git a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp index aa81fa58..413730c2 100644 --- a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp +++ b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp @@ -36,6 +36,7 @@ namespace nn struct AOCCacheEntry { + AOCCacheEntry() {}; AOCCacheEntry(uint64 titleId) : aocTitleId(titleId) {}; uint64 aocTitleId; @@ -149,6 +150,20 @@ namespace nn return AOC_RESULT::ERROR_OK; } + void save(MemStreamWriter& s) + { + s.writeSection("nn_aoc"); + s.writePODVector(sAocCache); + s.writeBool(sAocCacheGenerated); + } + + void restore(MemStreamReader& s) + { + s.readSection("nn_aoc"); + s.readPODVector(sAocCache); + s.readBool(sAocCacheGenerated); + } + void Initialize() { cafeExportRegister("nn_aoc", AOC_CalculateWorkBufferSize, LogType::NN_AOC); diff --git a/src/Cafe/OS/libs/nn_aoc/nn_aoc.h b/src/Cafe/OS/libs/nn_aoc/nn_aoc.h index 3853c075..9a08667d 100644 --- a/src/Cafe/OS/libs/nn_aoc/nn_aoc.h +++ b/src/Cafe/OS/libs/nn_aoc/nn_aoc.h @@ -2,6 +2,9 @@ namespace nn { namespace aoc { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void Initialize(); } } \ No newline at end of file diff --git a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp index c2d65a5f..f71be91f 100644 --- a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp +++ b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp @@ -1714,6 +1714,22 @@ void nnBossNsDataExport_seek(PPCInterpreter_t* hCPU) osLib_returnFromFunction(hCPU, r); } +void nnBoss_save(MemStreamWriter& s) +{ + s.writeSection("nn_boss"); + s.writeMPTR(nn::boss::g_mutex); + s.writeBE(nn::boss::g_initCounter); + s.writeBool(nn::boss::g_isInitialized); +} + +void nnBoss_restore(MemStreamReader& s) +{ + s.readSection("nn_boss"); + s.readMPTR(nn::boss::g_mutex); + s.readBE(nn::boss::g_initCounter); + s.readBool(nn::boss::g_isInitialized); +} + void nnBoss_load() { OSInitMutexEx(&nn::boss::g_mutex, nullptr); diff --git a/src/Cafe/OS/libs/nn_boss/nn_boss.h b/src/Cafe/OS/libs/nn_boss/nn_boss.h index f9a434a0..ca0ee066 100644 --- a/src/Cafe/OS/libs/nn_boss/nn_boss.h +++ b/src/Cafe/OS/libs/nn_boss/nn_boss.h @@ -1 +1,4 @@ +void nnBoss_save(MemStreamWriter& s); +void nnBoss_restore(MemStreamReader& s); + void nnBoss_load(); \ No newline at end of file diff --git a/src/Cafe/OS/libs/nn_fp/nn_fp.cpp b/src/Cafe/OS/libs/nn_fp/nn_fp.cpp index e33b6369..79e67f08 100644 --- a/src/Cafe/OS/libs/nn_fp/nn_fp.cpp +++ b/src/Cafe/OS/libs/nn_fp/nn_fp.cpp @@ -739,6 +739,18 @@ namespace nn osLib_returnFromFunction(hCPU, fpdRequest->returnCode); } + void save(MemStreamWriter& s) + { + s.writeSection("nn_fp"); + s.writeData(&g_fp, sizeof(g_fp)); + } + + void restore(MemStreamReader& s) + { + s.readSection("nn_fp"); + s.readData(&g_fp, sizeof(g_fp)); + } + void load() { osLib_addFunction("nn_fp", "Initialize__Q2_2nn2fpFv", export_Initialize); diff --git a/src/Cafe/OS/libs/nn_fp/nn_fp.h b/src/Cafe/OS/libs/nn_fp/nn_fp.h index daab14a0..f3529c8c 100644 --- a/src/Cafe/OS/libs/nn_fp/nn_fp.h +++ b/src/Cafe/OS/libs/nn_fp/nn_fp.h @@ -3,6 +3,9 @@ namespace nn { namespace fp { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void load(); } } \ No newline at end of file diff --git a/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp b/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp index 5a69b787..c50641c4 100644 --- a/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp +++ b/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp @@ -74,6 +74,20 @@ namespace nn return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_NDM, 0); } + void save(MemStreamWriter& s) + { + s.writeSection("nn_ndm"); + s.writeData(s_daemonStatus, sizeof(DAEMON_STATUS) * NUM_DAEMONS); + s.writeBE(s_initializeRefCount); + } + + void restore(MemStreamReader& s) + { + s.readSection("nn_ndm"); + s.readData(s_daemonStatus, sizeof(DAEMON_STATUS) * NUM_DAEMONS); + s.readBE(s_initializeRefCount); + } + void load() { for(size_t i=0; i(); i++) + _devicePoolMask.set(i); + } + void load() { osLib_addFunction("nsyshid", "HIDAddClient", export_HIDAddClient); diff --git a/src/Cafe/OS/libs/nsyshid/nsyshid.h b/src/Cafe/OS/libs/nsyshid/nsyshid.h index 051b4e7c..af901522 100644 --- a/src/Cafe/OS/libs/nsyshid/nsyshid.h +++ b/src/Cafe/OS/libs/nsyshid/nsyshid.h @@ -1,5 +1,8 @@ #pragma once namespace nsyshid { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void load(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp index f39a24ea..42593938 100644 --- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp @@ -2161,6 +2161,32 @@ namespace nsysnet } } +void nsysnet_save(MemStreamWriter& s) +{ + s.writeSection("nsysnet"); + s.writeMPTR(_ntoa_tempString); + s.writeMPTR(_staticHostent); + s.writeMPTR(_staticHostentName); + s.writeMPTR(_staticHostentPtrList); + s.writeMPTR(_staticHostentEntries); + s.writePODVector(nsysnet::g_nsslInternalStates); + s.writeBool(sockLibReady); + s.writeData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); +} + +void nsysnet_restore(MemStreamReader& s) +{ + s.readSection("nsysnet"); + s.readMPTR(_ntoa_tempString); + s.readMPTR(_staticHostent); + s.readMPTR(_staticHostentName); + s.readMPTR(_staticHostentPtrList); + s.readMPTR(_staticHostentEntries); + s.readPODVector(nsysnet::g_nsslInternalStates); + s.readBool(sockLibReady); + s.readData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); +} + // register nsysnet functions void nsysnet_load() { diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.h b/src/Cafe/OS/libs/nsysnet/nsysnet.h index fa2f2ca4..ce931714 100644 --- a/src/Cafe/OS/libs/nsysnet/nsysnet.h +++ b/src/Cafe/OS/libs/nsysnet/nsysnet.h @@ -12,6 +12,9 @@ typedef signed int WUSOCKET; +void nsysnet_save(MemStreamWriter& s); +void nsysnet_restore(MemStreamReader& s); + void nsysnet_load(); WUSOCKET nsysnet_createVirtualSocketFromExistingSocket(SOCKET existingSocket); void nsysnet_notifyCloseSharedSocket(SOCKET existingSocket); diff --git a/src/Cafe/OS/libs/padscore/padscore.cpp b/src/Cafe/OS/libs/padscore/padscore.cpp index 47f3bc4f..fb9e2cf4 100644 --- a/src/Cafe/OS/libs/padscore/padscore.cpp +++ b/src/Cafe/OS/libs/padscore/padscore.cpp @@ -53,7 +53,8 @@ namespace padscore WPADState_t g_wpad_state = kWPADStateMaster; - struct { + struct g_padscore_t + { SysAllocator alarm; bool kpad_initialized = false; @@ -746,6 +747,30 @@ namespace padscore OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler); } + void save(MemStreamWriter& s) + { + s.writeSection("padscore"); + s.writeBool(debugUseDRC1); + s.writeBool(g_kpadIsInited); + s.writeData(&g_padscore, sizeof(g_padscore_t)); + s.writeData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); + s.writeBE(g_kpad_ringbuffer_length); + s.writeBool(g_wpad_callback_by_kpad); + s.writeBE((uint32)g_wpad_state); + } + + void restore(MemStreamReader& s) + { + s.readSection("padscore"); + s.readBool(debugUseDRC1); + s.readBool(g_kpadIsInited); + s.readData(&g_padscore, sizeof(g_padscore_t)); + s.readData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); + s.readBE(g_kpad_ringbuffer_length); + s.readBool(g_wpad_callback_by_kpad); + g_wpad_state = (WPADState_t)s.readBE(); + } + void load() { cafeExportRegister("padscore", WPADIsMplsAttached, LogType::InputAPI); diff --git a/src/Cafe/OS/libs/padscore/padscore.h b/src/Cafe/OS/libs/padscore/padscore.h index efb1fbca..32320061 100644 --- a/src/Cafe/OS/libs/padscore/padscore.h +++ b/src/Cafe/OS/libs/padscore/padscore.h @@ -4,6 +4,9 @@ namespace padscore { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void start(); void load(); } diff --git a/src/Cafe/OS/libs/proc_ui/proc_ui.cpp b/src/Cafe/OS/libs/proc_ui/proc_ui.cpp index 7de8691a..4e55f051 100644 --- a/src/Cafe/OS/libs/proc_ui/proc_ui.cpp +++ b/src/Cafe/OS/libs/proc_ui/proc_ui.cpp @@ -49,6 +49,16 @@ void ProcUI_SendForegroundMessage() } } +void procui_save(MemStreamWriter& s) +{ + s.writeSection("proc_ui"); +} + +void procui_restore(MemStreamReader& s) +{ + s.readSection("proc_ui"); +} + void procui_load() { cafeExportRegister("proc_ui", ProcUIRegisterCallback, LogType::ProcUi); diff --git a/src/Cafe/OS/libs/proc_ui/proc_ui.h b/src/Cafe/OS/libs/proc_ui/proc_ui.h index 1cd04fb1..5e23615d 100644 --- a/src/Cafe/OS/libs/proc_ui/proc_ui.h +++ b/src/Cafe/OS/libs/proc_ui/proc_ui.h @@ -1,4 +1,7 @@ +void procui_save(MemStreamWriter& s); +void procui_restore(MemStreamReader& s); + void procui_load(); void ProcUI_SendForegroundMessage(); diff --git a/src/util/helpers/Serializer.cpp b/src/util/helpers/Serializer.cpp index 8e162c30..5a76337b 100644 --- a/src/util/helpers/Serializer.cpp +++ b/src/util/helpers/Serializer.cpp @@ -1,66 +1,25 @@ #include "Serializer.h" -template<> -uint8 MemStreamReader::readBE() +// readBE return + +template +T MemStreamReader::readBE() { - if (!reserveReadLength(sizeof(uint8))) + if (!reserveReadLength(sizeof(T))) return 0; - uint8 v = m_data[m_cursorPos]; - m_cursorPos += sizeof(uint8); + const uint8* p = m_data + m_cursorPos; + T v; + std::memcpy(&v, p, sizeof(v)); + v = _BE(v); + m_cursorPos += sizeof(T); return v; } -template<> -uint16 MemStreamReader::readBE() -{ - if (!reserveReadLength(sizeof(uint16))) - return 0; - const uint8* p = m_data + m_cursorPos; - uint16 v; - std::memcpy(&v, p, sizeof(v)); - v = _BE(v); - m_cursorPos += sizeof(uint16); - return v; -} - -template<> -uint32 MemStreamReader::readBE() -{ - if (!reserveReadLength(sizeof(uint32))) - return 0; - const uint8* p = m_data + m_cursorPos; - uint32 v; - std::memcpy(&v, p, sizeof(v)); - v = _BE(v); - m_cursorPos += sizeof(uint32); - return v; -} - -template<> -sint32 MemStreamReader::readBE() -{ - if (!reserveReadLength(sizeof(sint32))) - return 0; - const uint8* p = m_data + m_cursorPos; - sint32 v; - std::memcpy(&v, p, sizeof(v)); - v = _BE(v); - m_cursorPos += sizeof(sint32); - return v; -} - -template<> -uint64 MemStreamReader::readBE() -{ - if (!reserveReadLength(sizeof(uint64))) - return 0; - const uint8* p = m_data + m_cursorPos; - uint64 v; - std::memcpy(&v, p, sizeof(v)); - v = _BE(v); - m_cursorPos += sizeof(uint64); - return v; -} +template uint8 MemStreamReader::readBE(); +template uint16 MemStreamReader::readBE(); +template uint32 MemStreamReader::readBE(); +template uint64 MemStreamReader::readBE(); +template int MemStreamReader::readBE(); template<> std::string MemStreamReader::readBE() @@ -80,94 +39,88 @@ std::string MemStreamReader::readBE() return s; } -template<> -uint8 MemStreamReader::readLE() +// readBE void + +template +void MemStreamReader::readBE(T& v) { - return readBE(); + if (reserveReadLength(sizeof(T))) + { + const uint8* p = m_data + m_cursorPos; + std::memcpy(&v, p, sizeof(v)); + v = _BE(v); + m_cursorPos += sizeof(T); + } } +template void MemStreamReader::readBE(uint8& v); +template void MemStreamReader::readBE(uint16& v); +template void MemStreamReader::readBE(uint32& v); +template void MemStreamReader::readBE(uint64& v); +template void MemStreamReader::readBE(int& v); + template<> -uint32 MemStreamReader::readLE() +void MemStreamReader::readBE(std::string& v) { - if (!reserveReadLength(sizeof(uint32))) + uint32 stringSize = readBE(); + if (!hasError()) + { + if (stringSize >= (32 * 1024 * 1024)) + { + // out of bounds read or suspiciously large string + m_hasError = true; + } + else + { + v.resize(stringSize); + readData(v.data(), stringSize); + } + } +} + +// readLE return + +template +T MemStreamReader::readLE() +{ + if (!reserveReadLength(sizeof(T))) return 0; const uint8* p = m_data + m_cursorPos; - uint32 v; + T v; std::memcpy(&v, p, sizeof(v)); v = _LE(v); - m_cursorPos += sizeof(uint32); + m_cursorPos += sizeof(T); return v; } -template<> -uint64 MemStreamReader::readLE() +template uint8 MemStreamReader::readLE(); +template uint16 MemStreamReader::readLE(); +template uint32 MemStreamReader::readLE(); + +// readSection + +void MemStreamReader::readSection(const char* sec) { - if (!reserveReadLength(sizeof(uint64))) - return 0; - const uint8* p = m_data + m_cursorPos; - uint64 v; - std::memcpy(&v, p, sizeof(v)); - v = _LE(v); - m_cursorPos += sizeof(uint64); - return v; + std::string sec_str = std::string(sec); + cemu_assert_debug(readBE() == sec_str); } -template<> -void MemStreamWriter::writeBE(const uint64& v) +// writeBE void + +template +void MemStreamWriter::writeBE(const T& v) { - m_buffer.resize(m_buffer.size() + 8); - uint8* p = m_buffer.data() + m_buffer.size() - 8; - uint64 tmp = _BE(v); + m_buffer.resize(m_buffer.size() + sizeof(T)); + uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); + T tmp = _BE(v); std::memcpy(p, &tmp, sizeof(tmp)); } -template<> -void MemStreamWriter::writeBE(const uint32& v) -{ - m_buffer.resize(m_buffer.size() + 4); - uint8* p = m_buffer.data() + m_buffer.size() - 4; - uint32 tmp = _BE(v); - std::memcpy(p, &tmp, sizeof(tmp)); -} - -template<> -void MemStreamWriter::writeBE(const sint32& v) -{ - m_buffer.resize(m_buffer.size() + 4); - uint8* p = m_buffer.data() + m_buffer.size() - 4; - uint32 tmp = _BE(v); - std::memcpy(p, &tmp, sizeof(tmp)); -} - -template<> -void MemStreamWriter::writeBE(const uint16& v) -{ - m_buffer.resize(m_buffer.size() + 2); - uint8* p = m_buffer.data() + m_buffer.size() - 2; - uint16 tmp = _BE(v); - std::memcpy(p, &tmp, sizeof(tmp)); -} - - -template<> -void MemStreamWriter::writeBE(const uint8& v) -{ - m_buffer.emplace_back(v); -} - -template<> -void MemStreamWriter::writeBE(const bool& v) -{ - writeData(&v, sizeof(bool)); -} - -template<> -bool MemStreamReader::readBE() -{ - bool v{ false }; - readData(&v, sizeof(bool)); - return v; -} +template void MemStreamWriter::writeBE(const uint8& v); +template void MemStreamWriter::writeBE(const uint16& v); +template void MemStreamWriter::writeBE(const uint32& v); +template void MemStreamWriter::writeBE(const uint64& v); +template void MemStreamWriter::writeBE(const int& v); template<> void MemStreamWriter::writeBE(const std::string& v) @@ -176,21 +129,25 @@ void MemStreamWriter::writeBE(const std::string& v) writeData(v.data(), v.size()); } -template<> -void MemStreamWriter::writeLE(const uint64& v) +// writeLE void + +template +void MemStreamWriter::writeLE(const T& v) { - m_buffer.resize(m_buffer.size() + 8); - uint8* p = m_buffer.data() + m_buffer.size() - 8; - uint64 tmp = _LE(v); + m_buffer.resize(m_buffer.size() + sizeof(T)); + uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); + T tmp = _LE(v); std::memcpy(p, &tmp, sizeof(tmp)); } +template void MemStreamWriter::writeLE(const uint8& v); +template void MemStreamWriter::writeLE(const uint16& v); +template void MemStreamWriter::writeLE(const uint32& v); -template<> -void MemStreamWriter::writeLE(const uint32& v) +// writeSection + +void MemStreamWriter::writeSection(const char* sec) { - m_buffer.resize(m_buffer.size() + 4); - uint8* p = m_buffer.data() + m_buffer.size() - 4; - uint32 tmp = _LE(v); - std::memcpy(p, &tmp, sizeof(tmp)); + std::string sec_str = std::string(sec); + writeBE(sec_str); } \ No newline at end of file diff --git a/src/util/helpers/Serializer.h b/src/util/helpers/Serializer.h index 1c7bbce1..0e493254 100644 --- a/src/util/helpers/Serializer.h +++ b/src/util/helpers/Serializer.h @@ -12,6 +12,12 @@ public: template void readBE(T& v); template T readLE(); + template + void readAtomic(std::atomic& v) + { + v.store(readBE()); + } + template std::vector readPODVector() { @@ -27,6 +33,48 @@ public: return v; } + template + void readPODVector(std::vector& v) + { + uint32 numElements = readBE(); + if (!hasError()) + { + v.reserve(numElements); + v.resize(numElements); + readData(v.data(), v.size() * sizeof(T)); + } + } + + template + void readPTR(T& v) + { + v = (T)(memory_base + readBE()); + } + + template class C, typename T> + void readMPTR(C& v) + { + v = (T*)(memory_base + readBE()); + } + + template class C, typename T, size_t c, size_t a> + void readMPTR(C& v) + { + v = (T*)(memory_base + readBE()); + } + + void readBool(bool& v) + { + v = readBE(); + } + + bool readBool() + { + return readBE(); + } + + void readSection(const char* sec); + // read string terminated by newline character (or end of stream) // will also trim off any carriage return std::string_view readLine() @@ -71,15 +119,23 @@ public: bool readData(void* ptr, size_t size) { - if (m_cursorPos + size > m_size) + if (readBE()) { - m_cursorPos = m_size; - m_hasError = true; + ptr = NULL; return false; } - memcpy(ptr, m_data + m_cursorPos, size); - m_cursorPos += (sint32)size; - return true; + else + { + if (m_cursorPos + size > m_size) + { + m_cursorPos = m_size; + m_hasError = true; + return false; + } + memcpy(ptr, m_data + m_cursorPos, size); + m_cursorPos += (sint32)size; + return true; + } } std::span readDataNoCopy(size_t size) @@ -147,21 +203,51 @@ public: void writeData(const void* ptr, size_t size) { - m_buffer.resize(m_buffer.size() + size); - uint8* p = m_buffer.data() + m_buffer.size() - size; - memcpy(p, ptr, size); + writeBE((uint8)(ptr == NULL)); + if (ptr) + { + m_buffer.resize(m_buffer.size() + size); + uint8* p = m_buffer.data() + m_buffer.size() - size; + memcpy(p, ptr, size); + } } template void writeBE(const T& v); template void writeLE(const T& v); + + template + void writeAtomic(const std::atomic& v) + { + writeBE(v.load()); + } template void writePODVector(const std::vector& v) { + cemu_assert(std::is_trivial_v); writeBE(v.size()); writeData(v.data(), v.size() * sizeof(T)); } + template + void writePTR(const T& v) + { + writeBE((uint32)((uint8*)v - (uint8*)memory_base)); + } + + template + void writeMPTR(const T& v) + { + writeBE(v.GetMPTR()); + } + + void writeBool(const bool& v) + { + writeBE((uint8)v); + } + + void writeSection(const char* sec); + // get result buffer without copy // resets internal state void getResultAndReset(std::vector& data) From b8a83ab448f3ee8309524234e2cf614625899283 Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Mon, 9 Oct 2023 09:10:07 -0400 Subject: [PATCH 5/9] Fix non-trivial uses of writePODVector --- .../libs/coreinit/coreinit_MemoryMapping.cpp | 15 +++++- src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp | 15 ++++-- src/Cafe/OS/libs/nsysnet/nsysnet.cpp | 54 ++++++++++++++++++- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp index fbdc366f..626a4daa 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp @@ -156,13 +156,26 @@ namespace coreinit void MemoryMapping_Save(MemStreamWriter& s) { s.writeSection("coreinit_MemoryMapping "); - s.writePODVector(s_allocatedVirtMemory); + s.writeBE(s_allocatedVirtMemory.size()); + for (auto i : s_allocatedVirtMemory) + { + s.writeBE(i.virtualAddress); + s.writeBE(i.size); + s.writeBE(i.alignment); + } } void MemoryMapping_Restore(MemStreamReader& s) { s.readSection("coreinit_MemoryMapping "); s.readPODVector(s_allocatedVirtMemory); + uint32 s_allocatedVirtMemorySize = s.readBE(); + s_allocatedVirtMemory.clear(); + s_allocatedVirtMemory.reserve(s_allocatedVirtMemorySize); + for (sint32 i = 0; i < s_allocatedVirtMemorySize; i++) + { + s_allocatedVirtMemory.push_back(OSVirtMemoryEntry(s.readBE(), s.readBE(), s.readBE())); + } } void InitializeMemoryMapping() diff --git a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp index 413730c2..2071153a 100644 --- a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp +++ b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp @@ -36,7 +36,6 @@ namespace nn struct AOCCacheEntry { - AOCCacheEntry() {}; AOCCacheEntry(uint64 titleId) : aocTitleId(titleId) {}; uint64 aocTitleId; @@ -153,14 +152,24 @@ namespace nn void save(MemStreamWriter& s) { s.writeSection("nn_aoc"); - s.writePODVector(sAocCache); + s.writeBE(sAocCache.size()); + for (auto i : sAocCache) + { + s.writeBE(i.aocTitleId); + } s.writeBool(sAocCacheGenerated); } void restore(MemStreamReader& s) { s.readSection("nn_aoc"); - s.readPODVector(sAocCache); + uint32 sAocCacheSize = s.readBE(); + sAocCache.clear(); + sAocCache.reserve(sAocCacheSize); + for (sint32 i = 0; i < sAocCacheSize; i++) + { + sAocCache.emplace_back(s.readBE()); + } s.readBool(sAocCacheGenerated); } diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp index 42593938..aa8d454f 100644 --- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp @@ -2161,6 +2161,45 @@ namespace nsysnet } } +template<> +void MemStreamWriter::writeBE(const nsysnet::NSSLInternalState_t& v) +{ + writeBool(v.destroyed); + writeBE(v.sslVersion); + writeBE(v.clientPKI); + + writeBE(v.serverPKIs.size()); + for (auto i : v.serverPKIs) + writeBE(i); + + writeBE(v.serverCustomPKIs.size()); + for (auto i : v.serverCustomPKIs) + writePODVector(i); +} + +template<> +void MemStreamReader::readBE(nsysnet::NSSLInternalState_t& v) +{ + readBool(v.destroyed); + readBE(v.sslVersion); + readBE(v.clientPKI); + + uint32 serverPKIsSize = readBE(); + v.serverPKIs.clear(); + for (uint32 i = 0; i < serverPKIsSize; i++) + v.serverPKIs.insert(readBE()); + + uint32 serverCustomPKIsSize = readBE(); + v.serverCustomPKIs.clear(); + v.serverCustomPKIs.resize(serverCustomPKIsSize); + for (uint32 i = 0; i < serverCustomPKIsSize; i++) + { + std::vector pki; + readPODVector(pki); + v.serverCustomPKIs.push_back(pki); + } +} + void nsysnet_save(MemStreamWriter& s) { s.writeSection("nsysnet"); @@ -2169,7 +2208,9 @@ void nsysnet_save(MemStreamWriter& s) s.writeMPTR(_staticHostentName); s.writeMPTR(_staticHostentPtrList); s.writeMPTR(_staticHostentEntries); - s.writePODVector(nsysnet::g_nsslInternalStates); + s.writeBE(nsysnet::g_nsslInternalStates.size()); + for (auto i : nsysnet::g_nsslInternalStates) + s.writeBE(i); s.writeBool(sockLibReady); s.writeData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); } @@ -2182,7 +2223,15 @@ void nsysnet_restore(MemStreamReader& s) s.readMPTR(_staticHostentName); s.readMPTR(_staticHostentPtrList); s.readMPTR(_staticHostentEntries); - s.readPODVector(nsysnet::g_nsslInternalStates); + uint32 g_nsslInternalStatesSize = s.readBE(); + nsysnet::g_nsslInternalStates.clear(); + nsysnet::g_nsslInternalStates.resize(g_nsslInternalStatesSize); + for (uint32 i = 0; i < g_nsslInternalStatesSize; i++) + { + nsysnet::NSSLInternalState_t t; + s.readBE(t); + nsysnet::g_nsslInternalStates.push_back(t); + } s.readBool(sockLibReady); s.readData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); } @@ -2247,3 +2296,4 @@ void nsysnet_load() osLib_addFunction("nsysnet", "NSSLExportInternalServerCertificate", nsysnet::export_NSSLExportInternalServerCertificate); osLib_addFunction("nsysnet", "NSSLExportInternalClientCertificate", nsysnet::export_NSSLExportInternalClientCertificate); } + From 1b7c4d8a2f9046f071dfa3b8e7080069eb573c3d Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Tue, 10 Oct 2023 10:59:26 -0400 Subject: [PATCH 6/9] Move to Endian agnostic read/write functions; add kernel --- src/Cafe/CafeSystem.cpp | 8 +- src/Cafe/Filesystem/fsc.cpp | 30 +-- src/Cafe/Filesystem/fsc.h | 1 + src/Cafe/Filesystem/fscDeviceHostFS.cpp | 8 +- src/Cafe/HW/MMU/MMU.cpp | 32 ++-- src/Cafe/IOSU/ODM/iosu_odm.cpp | 20 ++ src/Cafe/IOSU/ODM/iosu_odm.h | 3 + src/Cafe/IOSU/PDM/iosu_pdm.cpp | 9 + src/Cafe/IOSU/PDM/iosu_pdm.h | 3 + src/Cafe/IOSU/fsa/iosu_fsa.cpp | 40 ++-- src/Cafe/IOSU/fsa/iosu_fsa.h | 4 +- src/Cafe/IOSU/kernel/iosu_kernel.cpp | 132 ++++++++++++- src/Cafe/IOSU/kernel/iosu_kernel.h | 3 + src/Cafe/OS/libs/coreinit/coreinit.cpp | 8 +- src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp | 16 +- .../OS/libs/coreinit/coreinit_DynLoad.cpp | 16 +- src/Cafe/OS/libs/coreinit/coreinit_Init.cpp | 8 +- .../OS/libs/coreinit/coreinit_LockedCache.cpp | 4 +- src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp | 8 +- .../libs/coreinit/coreinit_MemoryMapping.cpp | 17 +- .../OS/libs/coreinit/coreinit_SysHeap.cpp | 8 +- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 16 +- src/Cafe/OS/libs/dmae/dmae.cpp | 4 +- src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp | 4 +- src/Cafe/OS/libs/nn_act/nn_act.cpp | 8 +- src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp | 8 +- src/Cafe/OS/libs/nn_boss/nn_boss.cpp | 4 +- src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp | 4 +- src/Cafe/OS/libs/nn_olv/nn_olv.cpp | 4 +- src/Cafe/OS/libs/nn_temp/nn_temp.cpp | 4 +- src/Cafe/OS/libs/nsyshid/nsyshid.cpp | 8 +- src/Cafe/OS/libs/nsysnet/nsysnet.cpp | 32 ++-- src/Cafe/OS/libs/padscore/padscore.cpp | 8 +- src/util/helpers/Serializer.cpp | 175 ++++++++++++------ src/util/helpers/Serializer.h | 33 +++- 35 files changed, 468 insertions(+), 222 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 8340a179..66d76ef5 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -1011,7 +1011,9 @@ namespace CafeSystem nn::temp::save(writer); nn::aoc::save(writer); osLib_save(writer); - iosu::fsa::Save(writer); + iosu::kernel::save(writer); + iosu::fsa::save(writer); + iosu::odm::save(writer); FileStream* stream = FileStream::createFile(path); stream->writeData(writer.getResult().data(), writer.getResult().size_bytes()); @@ -1042,7 +1044,9 @@ namespace CafeSystem nn::temp::restore(reader); nn::aoc::restore(reader); osLib_restore(reader); - iosu::fsa::Restore(reader); + iosu::kernel::restore(reader); + iosu::fsa::restore(reader); + iosu::odm::restore(reader); cemuLog_log(LogType::SaveStates, "Loaded state from {}.", path); diff --git a/src/Cafe/Filesystem/fsc.cpp b/src/Cafe/Filesystem/fsc.cpp index 48a2e1b7..7bb5e466 100644 --- a/src/Cafe/Filesystem/fsc.cpp +++ b/src/Cafe/Filesystem/fsc.cpp @@ -737,31 +737,31 @@ void fsc_init() } template <> -void MemStreamWriter::writeBE(const FSCVirtualFile::FSCDirIteratorState& v) +void MemStreamWriter::write(const FSCVirtualFile::FSCDirIteratorState& v) { - writeBE(v.index); + write(v.index); writePODVector(v.dirEntries); } template <> -void MemStreamReader::readBE(FSCVirtualFile::FSCDirIteratorState& v) +void MemStreamReader::read(FSCVirtualFile::FSCDirIteratorState& v) { - readBE(v.index); + read(v.index); readPODVector(v.dirEntries); } void FSCVirtualFile::Save(MemStreamWriter& writer) { writer.writeBool(dirIterator != nullptr); - if (dirIterator) writer.writeBE(*dirIterator); + if (dirIterator) writer.write(*dirIterator); writer.writeBool(m_isAppend); } void FSCVirtualFileDirectoryIterator::Save(MemStreamWriter& writer) { - writer.writeBE((uint32)Child::DIRECTORY_ITERATOR); - writer.writeBE(m_path); - writer.writeBE(m_folders.size()); + writer.write((uint32)Child::DIRECTORY_ITERATOR); + writer.write(m_path); + writer.write(m_folders.size()); for (auto& folder : m_folders) { folder->Save(writer); @@ -774,13 +774,13 @@ void FSCVirtualFileDirectoryIterator::Save(MemStreamWriter& writer) FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) { FSCVirtualFile* file; - switch ((Child)reader.readBE()) + switch ((Child)reader.read()) { case Child::DIRECTORY_ITERATOR: { - std::string path = reader.readBE(); + std::string path = reader.read(); std::vector folders{}; - size_t size = reader.readBE(); + size_t size = reader.read(); for (size_t i = 0; i < size; i++) { folders.push_back(Restore(reader)); @@ -790,11 +790,11 @@ FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) } case Child::HOST: { - std::string path = reader.readBE(); - FSC_ACCESS_FLAG flags = (FSC_ACCESS_FLAG)reader.readBE(); + std::string path = reader.read(); + FSC_ACCESS_FLAG flags = (FSC_ACCESS_FLAG)reader.read(); sint32 status{}; file = FSCVirtualFile_Host::OpenFile(path, flags, status); - file->fscSetSeek(reader.readBE()); + file->fscSetSeek(reader.read()); break; } default: @@ -803,7 +803,7 @@ FSCVirtualFile* FSCVirtualFile::Restore(MemStreamReader& reader) if (reader.readBool()) { file->dirIterator = new FSCDirIteratorState; - reader.readBE(*file->dirIterator); + reader.read(*file->dirIterator); } reader.readBool(file->m_isAppend); return file; diff --git a/src/Cafe/Filesystem/fsc.h b/src/Cafe/Filesystem/fsc.h index 8d9ab032..b3b66d04 100644 --- a/src/Cafe/Filesystem/fsc.h +++ b/src/Cafe/Filesystem/fsc.h @@ -38,6 +38,7 @@ DEFINE_ENUM_FLAG_OPERATORS(FSC_ACCESS_FLAG); #define FSC_STATUS_ALREADY_EXISTS (3) // note: Unlike the native Wii U filesystem, FSC does not provide separate error codes for NOT_A_FILE and NOT_A_DIRECTORY // to determine them manually, open with both modes (file and dir) and check the type + #define FSC_MAX_DIR_NAME_LENGTH (256) #define FSC_MAX_DEVICE_PATH_LENGTH ((std::max)(260,FSA_PATH_SIZE_MAX)) // max length for FSC device paths (should be at least equal or greater than supported by host filesystem) diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.cpp b/src/Cafe/Filesystem/fscDeviceHostFS.cpp index 12b15024..47ae761f 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.cpp +++ b/src/Cafe/Filesystem/fscDeviceHostFS.cpp @@ -299,9 +299,9 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg void FSCVirtualFile_Host::Save(MemStreamWriter& writer) { - writer.writeBE((uint32)Child::HOST); - writer.writeBE(m_path->string()); - writer.writeBE((uint32)m_accessFlags); - writer.writeBE(m_seek); + writer.write((uint32)Child::HOST); + writer.write(m_path->string()); + writer.write((uint32)m_accessFlags); + writer.write(m_seek); FSCVirtualFile::Save(writer); } diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index e65e62f9..3c05c805 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -81,28 +81,28 @@ MMURange* memory_getMMURangeByAddress(MPTR address) } template<> -void MemStreamWriter::writeBE(const MMURange& v) +void MemStreamWriter::write(const MMURange& v) { writeBool(v.m_isMapped); - writeBE(v.baseAddress); - writeBE((uint8)v.areaId); - writeBE((uint8)v.flags); - writeBE(v.name); - writeBE(v.size); - writeBE(v.initSize); + write(v.baseAddress); + write((uint8)v.areaId); + write((uint8)v.flags); + write(v.name); + write(v.size); + write(v.initSize); } template <> -void MemStreamReader::readBE(MMURange& mmuRange) +void MemStreamReader::read(MMURange& mmuRange) { bool needsMapped = readBool(); mmuRange.m_isMapped = false; - mmuRange.baseAddress = readBE(); - mmuRange.areaId = (MMU_MEM_AREA_ID)readBE(); - mmuRange.flags = (MMURange::MFLAG)readBE(); - mmuRange.name = readBE(); - mmuRange.size = readBE(); - mmuRange.initSize = readBE(); + mmuRange.baseAddress = read(); + mmuRange.areaId = (MMU_MEM_AREA_ID)read(); + mmuRange.flags = (MMURange::MFLAG)read(); + mmuRange.name = read(); + mmuRange.size = read(); + mmuRange.initSize = read(); if (needsMapped) mmuRange.mapMem(); } @@ -443,7 +443,7 @@ void memory_Serialize(MemStreamWriter& s) { for (auto& itr : g_mmuRanges) { - s.writeBE(*itr); + s.write(*itr); if (itr->isMapped()) { s.writeData(memory_base + itr->getBase(), itr->getSize()); @@ -455,7 +455,7 @@ void memory_Deserialize(MemStreamReader& s) { for (auto& itr : g_mmuRanges) { - s.readBE(*itr); + s.read(*itr); if (itr->isMapped()) { s.readData(memory_base + itr->getBase(), itr->getSize()); diff --git a/src/Cafe/IOSU/ODM/iosu_odm.cpp b/src/Cafe/IOSU/ODM/iosu_odm.cpp index 3dc8e431..086c887a 100644 --- a/src/Cafe/IOSU/ODM/iosu_odm.cpp +++ b/src/Cafe/IOSU/ODM/iosu_odm.cpp @@ -133,6 +133,26 @@ namespace iosu s_threadInitialized = false; } + void save(MemStreamWriter& s) + { + s.writeSection("iosu_odm"); + s.writeAtomic(s_requestStop); + s.writeAtomic(s_isRunning); + s.writeAtomic(s_threadInitialized); + s.write(s_msgQueueId); + s.writeMPTR(_s_msgBuffer); + } + + void restore(MemStreamReader& s) + { + s.readSection("iosu_odm"); + s.readAtomic(s_requestStop); + s.readAtomic(s_isRunning); + s.readAtomic(s_threadInitialized); + s.read(s_msgQueueId); + s.readMPTR(_s_msgBuffer); + } + void Initialize() { if (s_isRunning.exchange(true)) diff --git a/src/Cafe/IOSU/ODM/iosu_odm.h b/src/Cafe/IOSU/ODM/iosu_odm.h index f5f721a1..98ea7714 100644 --- a/src/Cafe/IOSU/ODM/iosu_odm.h +++ b/src/Cafe/IOSU/ODM/iosu_odm.h @@ -4,6 +4,9 @@ namespace iosu { namespace odm { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void Initialize(); void Shutdown(); } diff --git a/src/Cafe/IOSU/PDM/iosu_pdm.cpp b/src/Cafe/IOSU/PDM/iosu_pdm.cpp index 45b4a1d8..9a2af40a 100644 --- a/src/Cafe/IOSU/PDM/iosu_pdm.cpp +++ b/src/Cafe/IOSU/PDM/iosu_pdm.cpp @@ -352,6 +352,15 @@ namespace iosu } } + void save(MemStreamWriter& s) + { + + } + void restore(MemStreamReader& s) + { + + } + void Initialize() { // todo - add support for per-account handling diff --git a/src/Cafe/IOSU/PDM/iosu_pdm.h b/src/Cafe/IOSU/PDM/iosu_pdm.h index fbafbc02..b4d0a735 100644 --- a/src/Cafe/IOSU/PDM/iosu_pdm.h +++ b/src/Cafe/IOSU/PDM/iosu_pdm.h @@ -4,6 +4,9 @@ namespace iosu { namespace pdm { + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void Initialize(); void StartTrackingTime(uint64 titleId); void Stop(); diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index fdb7dee4..b24607a3 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -911,26 +911,26 @@ namespace iosu } // namespace iosu template <> -void MemStreamWriter::writeBE(const iosu::fsa::FSAClient& v) +void MemStreamWriter::write(const iosu::fsa::FSAClient& v) { - writeBE(v.workingDirectory); + write(v.workingDirectory); writeBool(v.isAllocated); } template <> -void MemStreamReader::readBE(iosu::fsa::FSAClient& v) +void MemStreamReader::read(iosu::fsa::FSAClient& v) { - readBE(v.workingDirectory); + read(v.workingDirectory); readBool(v.isAllocated); } template <> -void MemStreamWriter::writeBE(const iosu::fsa::_FSAHandleTable& v) +void MemStreamWriter::write(const iosu::fsa::_FSAHandleTable& v) { - writeBE(v.m_currentCounter); + write(v.m_currentCounter); for (sint32 i = 0; i < v.m_handleTableSize; i++) { - writeBE(v.m_handleTable[i].handleCheckValue); + write(v.m_handleTable[i].handleCheckValue); writeBool(v.m_handleTable[i].isAllocated); writeBool(v.m_handleTable[i].fscFile != nullptr); @@ -939,12 +939,12 @@ void MemStreamWriter::writeBE(const iosu::fsa::_FSAHandleTable& v) } template <> -void MemStreamReader::readBE(iosu::fsa::_FSAHandleTable& v) +void MemStreamReader::read(iosu::fsa::_FSAHandleTable& v) { - readBE(v.m_currentCounter); + read(v.m_currentCounter); for (sint32 i = 0; i < v.m_handleTableSize; i++) { - readBE(v.m_handleTable[i].handleCheckValue); + read(v.m_handleTable[i].handleCheckValue); readBool(v.m_handleTable[i].isAllocated); if (readBool()) v.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); @@ -955,32 +955,32 @@ namespace iosu { namespace fsa { - void Save(MemStreamWriter& s) + void save(MemStreamWriter& s) { s.writeSection("iosu_fsa"); - s.writeBE(sFSAIoMsgQueue); + s.write(sFSAIoMsgQueue); s.writeMPTR(_m_sFSAIoMsgQueueMsgBuffer); for (sint32 i = 0; i < sFSAClientArraySize; i++) { - s.writeBE(sFSAClientArray[i]); + s.write(sFSAClientArray[i]); } - s.writeBE(sDirHandleTable); - s.writeBE(sFileHandleTable); + s.write(sDirHandleTable); + s.write(sFileHandleTable); } - void Restore(MemStreamReader& s) + void restore(MemStreamReader& s) { s.readSection("iosu_fsa"); - s.readBE(sFSAIoMsgQueue); + s.read(sFSAIoMsgQueue); s.readMPTR(_m_sFSAIoMsgQueueMsgBuffer); for (sint32 i = 0; i < sFSAClientArraySize; i++) { - s.readBE(sFSAClientArray[i]); + s.read(sFSAClientArray[i]); } - s.readBE(sDirHandleTable); - s.readBE(sFileHandleTable); + s.read(sDirHandleTable); + s.read(sFileHandleTable); } } // namespace fsa } // namespace iosu \ No newline at end of file diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.h b/src/Cafe/IOSU/fsa/iosu_fsa.h index d5fb2118..49c36a2d 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.h +++ b/src/Cafe/IOSU/fsa/iosu_fsa.h @@ -214,7 +214,7 @@ namespace iosu void Initialize(); void Shutdown(); - void Save(MemStreamWriter& writer); - void Restore(MemStreamReader& reader); + void save(MemStreamWriter& writer); + void restore(MemStreamReader& reader); } // namespace fsa } // namespace iosu diff --git a/src/Cafe/IOSU/kernel/iosu_kernel.cpp b/src/Cafe/IOSU/kernel/iosu_kernel.cpp index 680170bc..651b763f 100644 --- a/src/Cafe/IOSU/kernel/iosu_kernel.cpp +++ b/src/Cafe/IOSU/kernel/iosu_kernel.cpp @@ -217,11 +217,13 @@ namespace iosu /* IPC */ + static constexpr size_t IOCTLV_VECTOR_ARRAY_SIZE = 8; + struct IOSDispatchableCommand { // stores a copy of incoming IPC requests with some extra information required for replies IPCCommandBody body; // our dispatchable copy - IPCIoctlVector vecCopy[8]; // our copy of the Ioctlv vector array + IPCIoctlVector vecCopy[IOCTLV_VECTOR_ARRAY_SIZE]; // our copy of the Ioctlv vector array IPCCommandBody* originalBody; // the original command that was sent to us uint32 ppcCoreIndex; IOSDevHandle replyHandle; // handle for outgoing replies @@ -547,10 +549,138 @@ namespace iosu return IOS_ERROR_OK; } + + void Initialize() { _IPCInitDispatchablePool(); } } +} + +template <> +void MemStreamWriter::write(const iosu::kernel::IOSMessageQueue& v) +{ + write(v.ukn00); + write(v.ukn04); + write(v.numQueuedMessages); + write(v.readIndex); + write(v.msgArraySize); + writeMPTR(v.msgArray); + write(v.queueHandle); + write(v.ukn1C); +} + +template <> +void MemStreamReader::read(iosu::kernel::IOSMessageQueue& v) +{ + read(v.ukn00); + read(v.ukn04); + read(v.numQueuedMessages); + read(v.readIndex); + read(v.msgArraySize); + readMPTR(v.msgArray); + read(v.queueHandle); + read(v.ukn1C); +} + +template <> +void MemStreamWriter::write(const iosu::kernel::IOSResourceManager& v) +{ + writeBool(v.isSet); + write(v.path); + write(v.msgQueueId); +} + +template <> +void MemStreamReader::read(iosu::kernel::IOSResourceManager& v) +{ + readBool(v.isSet); + read(v.path); + read(v.msgQueueId); +} + +template <> +void MemStreamWriter::write(const iosu::kernel::IPCActiveDeviceHandle& v) +{ + writeBool(v.isSet); + write(v.handleCheckValue); + write(v.path); + write(v.msgQueueId); + writeBool(v.hasDispatchTargetHandle); + write(v.dispatchTargetHandle); +} + +template <> +void MemStreamReader::read(iosu::kernel::IPCActiveDeviceHandle& v) +{ + readBool(v.isSet); + read(v.handleCheckValue); + read(v.path); + read(v.msgQueueId); + readBool(v.hasDispatchTargetHandle); + read(v.dispatchTargetHandle); +} + +namespace iosu +{ + namespace kernel + { + void save(MemStreamWriter& s) + { + s.write(sMsgQueuePool.size()); + for (const auto& i : sMsgQueuePool) + s.write(i); + + s.write(sDeviceResources.size()); + for (const auto& i : sDeviceResources) + s.write(i); + + s.writeMPTR(sIPCDispatchableCommandPool); + + size_t sIPCFreeDispatchableCommandsSize = sIPCFreeDispatchableCommands.size(); + s.write(sIPCFreeDispatchableCommandsSize); + while (sIPCFreeDispatchableCommandsSize) + { + IOSDispatchableCommand* front = sIPCFreeDispatchableCommands.front(); + sIPCFreeDispatchableCommands.pop(); + s.writePTR(front); + sIPCFreeDispatchableCommands.push(front); + sIPCFreeDispatchableCommandsSize--; + } + + s.write(MAX_NUM_ACTIVE_DEV_HANDLES); + for (uint32 i = 0; i < MAX_NUM_ACTIVE_DEV_HANDLES; i++) + s.write(sActiveDeviceHandles[i]); + } + + void restore(MemStreamReader& s) + { + cemu_assert(s.read() == sMsgQueuePool.size()); + for (auto& i : sMsgQueuePool) + s.read(i); + + cemu_assert(s.read() == sDeviceResources.size()); + for (auto& i : sDeviceResources) + s.read(i); + + s.readMPTR(sIPCDispatchableCommandPool); + + size_t sIPCFreeDispatchableCommandsSize = s.read(); + cemu_assert(sIPCFreeDispatchableCommandsSize == sIPCFreeDispatchableCommands.size()); + while (!sIPCFreeDispatchableCommands.empty()) + sIPCFreeDispatchableCommands.pop(); + for (uint32 i = 0; i < sIPCFreeDispatchableCommandsSize; i++) + { + IOSDispatchableCommand* cmd = nullptr; + s.readPTR(cmd); + sIPCFreeDispatchableCommands.push(cmd); + } + + cemu_assert(s.read() == MAX_NUM_ACTIVE_DEV_HANDLES); + for (uint32 i = 0; i < MAX_NUM_ACTIVE_DEV_HANDLES; i++) + s.read(sActiveDeviceHandles[i]); + } + } } \ No newline at end of file diff --git a/src/Cafe/IOSU/kernel/iosu_kernel.h b/src/Cafe/IOSU/kernel/iosu_kernel.h index 2b82374e..5a7da791 100644 --- a/src/Cafe/IOSU/kernel/iosu_kernel.h +++ b/src/Cafe/IOSU/kernel/iosu_kernel.h @@ -18,6 +18,9 @@ namespace iosu void IPCSubmitFromCOS(uint32 ppcCoreIndex, IPCCommandBody* cmd); + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); + void Initialize(); } } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit.cpp b/src/Cafe/OS/libs/coreinit/coreinit.cpp index e573c11d..91f444d8 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit.cpp @@ -321,8 +321,8 @@ void coreinit_save(MemStreamWriter& s) s.writeSection("coreinit"); s.writeData(gCoreinitData, sizeof(coreinitData_t)); - s.writeBE(placeholderFont); - s.writeBE(placeholderFontSize); + s.write(placeholderFont); + s.write(placeholderFontSize); coreinit_Init_Save(s); coreinit::SysHeap_Save(s); @@ -353,8 +353,8 @@ void coreinit_restore(MemStreamReader& s) coreinit::__OSDeleteAllActivePPCThreads(); s.readData(gCoreinitData, sizeof(coreinitData_t)); - s.readBE(placeholderFont); - s.readBE(placeholderFontSize); + s.read(placeholderFont); + s.read(placeholderFontSize); coreinit_Init_Restore(s); coreinit::SysHeap_Restore(s); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index bfc975fc..d0b124dd 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -314,13 +314,13 @@ namespace coreinit s.writeMPTR(_g_alarmThreadStack); s.writeMPTR(_g_alarmThreadName); - s.writeBE(coreinit_getOSTime()); + s.write(coreinit_getOSTime()); - s.writeBE((uint64)g_activeAlarms.size()); + s.write((uint64)g_activeAlarms.size()); for (auto& itr : g_activeAlarms) { - s.writeBE(memory_getVirtualOffsetFromPointer(itr.first)); - s.writeBE(itr.second->getNextFire()); + s.write(memory_getVirtualOffsetFromPointer(itr.first)); + s.write(itr.second->getNextFire()); } } @@ -336,12 +336,12 @@ namespace coreinit s.readMPTR(_g_alarmThreadName); uint64 currentTime = coreinit_getOSTime(); - uint64_t timeOffset = currentTime - s.readBE(); + uint64_t timeOffset = currentTime - s.read(); - size_t alms = s.readBE(); + size_t alms = s.read(); for (size_t alm = 0; alm < alms; alm++) { - OSAlarm_t* alarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(s.readBE()); + OSAlarm_t* alarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(s.read()); uint64 startTime = _swapEndianU64(alarm->startTime) + timeOffset; uint64 nextTime = _swapEndianU64(alarm->nextTime) + timeOffset; @@ -360,7 +360,7 @@ namespace coreinit } alarm->nextTime = _swapEndianU64(nextTime); - uint64 nextFire = s.readBE() + timeOffset; + uint64 nextFire = s.read() + timeOffset; __OSLockScheduler(); g_activeAlarms[alarm] = OSHostAlarmCreate(nextFire, period, __OSHostAlarmTriggered, nullptr); __OSUnlockScheduler(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp index 35e1447c..b464ac45 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_DynLoad.cpp @@ -132,19 +132,19 @@ namespace coreinit void DynLoad_Save(MemStreamWriter& s) { s.writeSection("coreinit_DynLoad"); - s.writeBE(_osDynLoadFuncAlloc); - s.writeBE(_osDynLoadFuncFree); - s.writeBE(_osDynLoadTLSFuncAlloc); - s.writeBE(_osDynLoadTLSFuncFree); + s.write(_osDynLoadFuncAlloc); + s.write(_osDynLoadFuncFree); + s.write(_osDynLoadTLSFuncAlloc); + s.write(_osDynLoadTLSFuncFree); } void DynLoad_Restore(MemStreamReader& s) { s.readSection("coreinit_DynLoad"); - s.readBE(_osDynLoadFuncAlloc); - s.readBE(_osDynLoadFuncFree); - s.readBE(_osDynLoadTLSFuncAlloc); - s.readBE(_osDynLoadTLSFuncFree); + s.read(_osDynLoadFuncAlloc); + s.read(_osDynLoadFuncFree); + s.read(_osDynLoadTLSFuncAlloc); + s.read(_osDynLoadTLSFuncFree); } void InitializeDynLoad() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp index 0d7cb477..f75d45ff 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp @@ -220,16 +220,16 @@ void coreinit_Init_Save(MemStreamWriter& s) { s.writeSection("coreinit_Init"); s.writeData(_coreinitInfo, sizeof(coreinitInit_t)); - s.writeBE(argStorageIndex); + s.write(argStorageIndex); s.writeMPTR(g_preinitUserParam); - s.writeBE(_coreinitTitleEntryPoint); + s.write(_coreinitTitleEntryPoint); } void coreinit_Init_Restore(MemStreamReader& s) { s.readSection("coreinit_Init"); s.readData(_coreinitInfo, sizeof(coreinitInit_t)); - s.readBE(argStorageIndex); + s.read(argStorageIndex); s.readMPTR(g_preinitUserParam); - s.readBE(_coreinitTitleEntryPoint); + s.read(_coreinitTitleEntryPoint); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp index 05fd1645..a51dccf4 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_LockedCache.cpp @@ -276,7 +276,7 @@ namespace coreinit s.writeSection("coreinit_LockedCache"); s.writeData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); s.writeData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); - s.writeBE(_lcDisableErrorCounter); + s.write(_lcDisableErrorCounter); } void LockedCache_Restore(MemStreamReader& s) @@ -284,7 +284,7 @@ namespace coreinit s.readSection("coreinit_LockedCache"); s.readData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY); s.readData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT); - s.readBE(_lcDisableErrorCounter); + s.read(_lcDisableErrorCounter); } void InitializeLC() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp index e7594de1..dd2c3864 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MEM.cpp @@ -633,8 +633,8 @@ namespace coreinit void MEM_Save(MemStreamWriter& s) { s.writeSection("coreinit_MEM"); - s.writeBE(sysAreaAllocatorOffset); - s.writeBE(g_heapTableCount); + s.write(sysAreaAllocatorOffset); + s.write(g_heapTableCount); s.writeData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); s.writeBool(g_slockInitialized); s.writeBool(g_listsInitialized); @@ -651,8 +651,8 @@ namespace coreinit void MEM_Restore(MemStreamReader& s) { s.readSection("coreinit_MEM"); - s.readBE(sysAreaAllocatorOffset); - s.readBE(g_heapTableCount); + s.read(sysAreaAllocatorOffset); + s.read(g_heapTableCount); s.readData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE); s.readBool(g_slockInitialized); s.readBool(g_listsInitialized); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp index 626a4daa..0be5ce08 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp @@ -155,26 +155,25 @@ namespace coreinit void MemoryMapping_Save(MemStreamWriter& s) { - s.writeSection("coreinit_MemoryMapping "); - s.writeBE(s_allocatedVirtMemory.size()); + s.writeSection("coreinit_MemoryMapping"); + s.write(s_allocatedVirtMemory.size()); for (auto i : s_allocatedVirtMemory) { - s.writeBE(i.virtualAddress); - s.writeBE(i.size); - s.writeBE(i.alignment); + s.write(i.virtualAddress); + s.write(i.size); + s.write(i.alignment); } } void MemoryMapping_Restore(MemStreamReader& s) { - s.readSection("coreinit_MemoryMapping "); - s.readPODVector(s_allocatedVirtMemory); - uint32 s_allocatedVirtMemorySize = s.readBE(); + s.readSection("coreinit_MemoryMapping"); + uint32 s_allocatedVirtMemorySize = s.read(); s_allocatedVirtMemory.clear(); s_allocatedVirtMemory.reserve(s_allocatedVirtMemorySize); for (sint32 i = 0; i < s_allocatedVirtMemorySize; i++) { - s_allocatedVirtMemory.push_back(OSVirtMemoryEntry(s.readBE(), s.readBE(), s.readBE())); + s_allocatedVirtMemory.push_back(OSVirtMemoryEntry(s.read(), s.read(), s.read())); } } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp index 43d5bbf7..7603c513 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp @@ -36,16 +36,16 @@ namespace coreinit { s.writeSection("coreinit_SysHeap"); s.writeData(_sysHeapHandle, sizeof(MEMHeapBase)); - s.writeBE(_sysHeapAllocCounter); - s.writeBE(_sysHeapFreeCounter); + s.write(_sysHeapAllocCounter); + s.write(_sysHeapFreeCounter); } void SysHeap_Restore(MemStreamReader& s) { s.readSection("coreinit_SysHeap"); s.readData(_sysHeapHandle, sizeof(MEMHeapBase)); - s.readBE(_sysHeapAllocCounter); - s.readBE(_sysHeapFreeCounter); + s.read(_sysHeapAllocCounter); + s.read(_sysHeapFreeCounter); } void InitializeSysHeap() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index 3237cf61..bce0955c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -1335,19 +1335,19 @@ namespace coreinit { s.writeSection("coreinit_Thread"); - s.writeBE((uint8)sSchedulerActive.load()); + s.write((uint8)sSchedulerActive.load()); s.writeMPTR(g_activeThreadQueue); s.writeMPTR(g_coreRunQueue); - s.writeBE(activeThreadCount); + s.write(activeThreadCount); for (sint32 i = 0; i < activeThreadCount; i++) { - s.writeBE(activeThread[i]); + s.write(activeThread[i]); } for (sint32 i = 0; i < PPC_CORE_COUNT; i++) { s.writePTR(__currentCoreThread[i]); - s.writeBE(s_lehmer_lcg[i]); + s.write(s_lehmer_lcg[i]); s.writeMPTR(s_terminatorThreads[i].terminatorThread); s.writeMPTR(s_terminatorThreads[i].threadStack); s.writeMPTR(s_terminatorThreads[i].threadName); @@ -1362,14 +1362,14 @@ namespace coreinit { s.readSection("coreinit_Thread"); - sSchedulerActive.store(s.readBE()); + sSchedulerActive.store(s.read()); s.readMPTR(g_activeThreadQueue); s.readMPTR(g_coreRunQueue); - sint32 prevActiveThreadCount = s.readBE(); + sint32 prevActiveThreadCount = s.read(); for (sint32 i = 0; i < prevActiveThreadCount; i++) { - MPTR threadMPTR = s.readBE(); + MPTR threadMPTR = s.read(); if (recreate) { __OSLockScheduler(); @@ -1385,7 +1385,7 @@ namespace coreinit for (sint32 i = 0; i < PPC_CORE_COUNT; i++) { s.readPTR(__currentCoreThread[i]); - s.readBE(s_lehmer_lcg[i]); + s.read(s_lehmer_lcg[i]); s.readMPTR(s_terminatorThreads[i].terminatorThread); s.readMPTR(s_terminatorThreads[i].threadStack); s.readMPTR(s_terminatorThreads[i].threadName); diff --git a/src/Cafe/OS/libs/dmae/dmae.cpp b/src/Cafe/OS/libs/dmae/dmae.cpp index 1a02f61a..1d12328c 100644 --- a/src/Cafe/OS/libs/dmae/dmae.cpp +++ b/src/Cafe/OS/libs/dmae/dmae.cpp @@ -111,13 +111,13 @@ void dmaeExport_DMAEGetRetiredTimeStamp(PPCInterpreter_t* hCPU) void dmae_save(MemStreamWriter& s) { s.writeSection("dmae"); - s.writeBE(dmaeRetiredTimestamp); + s.write(dmaeRetiredTimestamp); } void dmae_restore(MemStreamReader& s) { s.readSection("dmae"); - s.readBE(dmaeRetiredTimestamp); + s.read(dmaeRetiredTimestamp); } void dmae_load() diff --git a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp index fafa21ed..c6545768 100644 --- a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp +++ b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp @@ -1357,7 +1357,7 @@ void export_curl_global_init_mem(PPCInterpreter_t* hCPU) void save(MemStreamWriter& s) { s.writeSection("nlibcurl"); - s.writeBE(g_nlibcurl.initialized); + s.write(g_nlibcurl.initialized); s.writeMPTR(g_nlibcurl.proxyConfig); s.writeMPTR(g_nlibcurl.malloc); s.writeMPTR(g_nlibcurl.free); @@ -1368,7 +1368,7 @@ void save(MemStreamWriter& s) void restore(MemStreamReader& s) { s.readSection("nlibcurl"); - s.readBE(g_nlibcurl.initialized); + s.read(g_nlibcurl.initialized); s.readMPTR(g_nlibcurl.proxyConfig); s.readMPTR(g_nlibcurl.malloc); s.readMPTR(g_nlibcurl.free); diff --git a/src/Cafe/OS/libs/nn_act/nn_act.cpp b/src/Cafe/OS/libs/nn_act/nn_act.cpp index f9b52871..ff465c88 100644 --- a/src/Cafe/OS/libs/nn_act/nn_act.cpp +++ b/src/Cafe/OS/libs/nn_act/nn_act.cpp @@ -667,14 +667,14 @@ void nnActExport_AcquirePrincipalIdByAccountId(PPCInterpreter_t* hCPU) void nnAct_save(MemStreamWriter& s) { s.writeSection("nn_act"); - s.writeBE(nn::act::g_initializeCount); - s.writeBE((uint32)g_isParentalControlCheckEnabled); + s.write(nn::act::g_initializeCount); + s.write((uint32)g_isParentalControlCheckEnabled); } void nnAct_restore(MemStreamReader& s) { s.readSection("nn_act"); - s.readBE(nn::act::g_initializeCount); - g_isParentalControlCheckEnabled = s.readBE(); + s.read(nn::act::g_initializeCount); + g_isParentalControlCheckEnabled = s.read(); } // register account functions diff --git a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp index 2071153a..dfd4df2f 100644 --- a/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp +++ b/src/Cafe/OS/libs/nn_aoc/nn_aoc.cpp @@ -152,10 +152,10 @@ namespace nn void save(MemStreamWriter& s) { s.writeSection("nn_aoc"); - s.writeBE(sAocCache.size()); + s.write(sAocCache.size()); for (auto i : sAocCache) { - s.writeBE(i.aocTitleId); + s.write(i.aocTitleId); } s.writeBool(sAocCacheGenerated); } @@ -163,12 +163,12 @@ namespace nn void restore(MemStreamReader& s) { s.readSection("nn_aoc"); - uint32 sAocCacheSize = s.readBE(); + uint32 sAocCacheSize = s.read(); sAocCache.clear(); sAocCache.reserve(sAocCacheSize); for (sint32 i = 0; i < sAocCacheSize; i++) { - sAocCache.emplace_back(s.readBE()); + sAocCache.emplace_back(s.read()); } s.readBool(sAocCacheGenerated); } diff --git a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp index f71be91f..67a0bb76 100644 --- a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp +++ b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp @@ -1718,7 +1718,7 @@ void nnBoss_save(MemStreamWriter& s) { s.writeSection("nn_boss"); s.writeMPTR(nn::boss::g_mutex); - s.writeBE(nn::boss::g_initCounter); + s.write(nn::boss::g_initCounter); s.writeBool(nn::boss::g_isInitialized); } @@ -1726,7 +1726,7 @@ void nnBoss_restore(MemStreamReader& s) { s.readSection("nn_boss"); s.readMPTR(nn::boss::g_mutex); - s.readBE(nn::boss::g_initCounter); + s.read(nn::boss::g_initCounter); s.readBool(nn::boss::g_isInitialized); } diff --git a/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp b/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp index c50641c4..b47fbf76 100644 --- a/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp +++ b/src/Cafe/OS/libs/nn_ndm/nn_ndm.cpp @@ -78,14 +78,14 @@ namespace nn { s.writeSection("nn_ndm"); s.writeData(s_daemonStatus, sizeof(DAEMON_STATUS) * NUM_DAEMONS); - s.writeBE(s_initializeRefCount); + s.write(s_initializeRefCount); } void restore(MemStreamReader& s) { s.readSection("nn_ndm"); s.readData(s_daemonStatus, sizeof(DAEMON_STATUS) * NUM_DAEMONS); - s.readBE(s_initializeRefCount); + s.read(s_initializeRefCount); } void load() diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp index 94223bb6..73e19175 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp @@ -118,7 +118,7 @@ namespace nn s.writeMPTR(s_OlvReleaseBgThreadName); s.writeData(&g_ParamPack, sizeof(ParamPackStorage)); s.writeData(&g_DiscoveryResults, sizeof(DiscoveryResultStorage)); - s.writeBE(g_ReportTypes); + s.write(g_ReportTypes); s.writeBool(g_IsInitialized); s.writeBool(g_IsOnlineMode); s.writeBool(g_IsOfflineDBMode); @@ -133,7 +133,7 @@ namespace nn s.readMPTR(s_OlvReleaseBgThreadName); s.readData(&g_ParamPack, sizeof(ParamPackStorage)); s.readData(&g_DiscoveryResults, sizeof(DiscoveryResultStorage)); - s.readBE(g_ReportTypes); + s.read(g_ReportTypes); s.readBool(g_IsInitialized); s.readBool(g_IsOnlineMode); s.readBool(g_IsOfflineDBMode); diff --git a/src/Cafe/OS/libs/nn_temp/nn_temp.cpp b/src/Cafe/OS/libs/nn_temp/nn_temp.cpp index b904f5b2..be0d7fe3 100644 --- a/src/Cafe/OS/libs/nn_temp/nn_temp.cpp +++ b/src/Cafe/OS/libs/nn_temp/nn_temp.cpp @@ -19,13 +19,13 @@ namespace nn::temp void save(MemStreamWriter& s) { s.writeSection("nn_temp"); - s.writeBE(tempIdGenerator); + s.write(tempIdGenerator); } void restore(MemStreamReader& s) { s.readSection("nn_temp"); - s.readBE(tempIdGenerator); + s.read(tempIdGenerator); } void Initialize() diff --git a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp index 129e5a93..62e4df8d 100644 --- a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp +++ b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp @@ -818,9 +818,9 @@ namespace nsyshid s.writeSection("nsyshid"); s.writeData(firstDevice, sizeof(HIDDeviceInfo_t)); s.writeData(firstHIDClient, sizeof(HIDClient_t)); - s.writeBE(_lastGeneratedHidHandle); + s.write(_lastGeneratedHidHandle); s.writeMPTR(_devicePool); - s.writeBE(_devicePoolMask.count()); + s.write(_devicePoolMask.count()); } void restore(MemStreamReader& s) @@ -828,10 +828,10 @@ namespace nsyshid s.readSection("nsyshid"); s.readData(firstDevice, sizeof(HIDDeviceInfo_t)); s.readData(firstHIDClient, sizeof(HIDClient_t)); - s.readBE(_lastGeneratedHidHandle); + s.read(_lastGeneratedHidHandle); s.readMPTR(_devicePool); _devicePoolMask.reset(); - for (size_t i = 0; i < s.readBE(); i++) + for (size_t i = 0; i < s.read(); i++) _devicePoolMask.set(i); } diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp index aa8d454f..b136df51 100644 --- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp @@ -2162,34 +2162,34 @@ namespace nsysnet } template<> -void MemStreamWriter::writeBE(const nsysnet::NSSLInternalState_t& v) +void MemStreamWriter::write(const nsysnet::NSSLInternalState_t& v) { writeBool(v.destroyed); - writeBE(v.sslVersion); - writeBE(v.clientPKI); + write(v.sslVersion); + write(v.clientPKI); - writeBE(v.serverPKIs.size()); + write(v.serverPKIs.size()); for (auto i : v.serverPKIs) - writeBE(i); + write(i); - writeBE(v.serverCustomPKIs.size()); + write(v.serverCustomPKIs.size()); for (auto i : v.serverCustomPKIs) writePODVector(i); } template<> -void MemStreamReader::readBE(nsysnet::NSSLInternalState_t& v) +void MemStreamReader::read(nsysnet::NSSLInternalState_t& v) { readBool(v.destroyed); - readBE(v.sslVersion); - readBE(v.clientPKI); + read(v.sslVersion); + read(v.clientPKI); - uint32 serverPKIsSize = readBE(); + uint32 serverPKIsSize = read(); v.serverPKIs.clear(); for (uint32 i = 0; i < serverPKIsSize; i++) - v.serverPKIs.insert(readBE()); + v.serverPKIs.insert(read()); - uint32 serverCustomPKIsSize = readBE(); + uint32 serverCustomPKIsSize = read(); v.serverCustomPKIs.clear(); v.serverCustomPKIs.resize(serverCustomPKIsSize); for (uint32 i = 0; i < serverCustomPKIsSize; i++) @@ -2208,9 +2208,9 @@ void nsysnet_save(MemStreamWriter& s) s.writeMPTR(_staticHostentName); s.writeMPTR(_staticHostentPtrList); s.writeMPTR(_staticHostentEntries); - s.writeBE(nsysnet::g_nsslInternalStates.size()); + s.write(nsysnet::g_nsslInternalStates.size()); for (auto i : nsysnet::g_nsslInternalStates) - s.writeBE(i); + s.write(i); s.writeBool(sockLibReady); s.writeData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); } @@ -2223,13 +2223,13 @@ void nsysnet_restore(MemStreamReader& s) s.readMPTR(_staticHostentName); s.readMPTR(_staticHostentPtrList); s.readMPTR(_staticHostentEntries); - uint32 g_nsslInternalStatesSize = s.readBE(); + uint32 g_nsslInternalStatesSize = s.read(); nsysnet::g_nsslInternalStates.clear(); nsysnet::g_nsslInternalStates.resize(g_nsslInternalStatesSize); for (uint32 i = 0; i < g_nsslInternalStatesSize; i++) { nsysnet::NSSLInternalState_t t; - s.readBE(t); + s.read(t); nsysnet::g_nsslInternalStates.push_back(t); } s.readBool(sockLibReady); diff --git a/src/Cafe/OS/libs/padscore/padscore.cpp b/src/Cafe/OS/libs/padscore/padscore.cpp index fb9e2cf4..f6531d32 100644 --- a/src/Cafe/OS/libs/padscore/padscore.cpp +++ b/src/Cafe/OS/libs/padscore/padscore.cpp @@ -754,9 +754,9 @@ namespace padscore s.writeBool(g_kpadIsInited); s.writeData(&g_padscore, sizeof(g_padscore_t)); s.writeData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); - s.writeBE(g_kpad_ringbuffer_length); + s.write(g_kpad_ringbuffer_length); s.writeBool(g_wpad_callback_by_kpad); - s.writeBE((uint32)g_wpad_state); + s.write((uint32)g_wpad_state); } void restore(MemStreamReader& s) @@ -766,9 +766,9 @@ namespace padscore s.readBool(g_kpadIsInited); s.readData(&g_padscore, sizeof(g_padscore_t)); s.readData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); - s.readBE(g_kpad_ringbuffer_length); + s.read(g_kpad_ringbuffer_length); s.readBool(g_wpad_callback_by_kpad); - g_wpad_state = (WPADState_t)s.readBE(); + g_wpad_state = (WPADState_t)s.read(); } void load() diff --git a/src/util/helpers/Serializer.cpp b/src/util/helpers/Serializer.cpp index 5a76337b..fd63b93c 100644 --- a/src/util/helpers/Serializer.cpp +++ b/src/util/helpers/Serializer.cpp @@ -1,5 +1,91 @@ #include "Serializer.h" +// read return + +template +T MemStreamReader::read() +{ + if (!reserveReadLength(sizeof(T))) + return 0; + const uint8* p = m_data + m_cursorPos; + T v; + std::memcpy(&v, p, sizeof(v)); + m_cursorPos += sizeof(T); + return v; +} + +template uint8 MemStreamReader::read(); +template uint16 MemStreamReader::read(); +template uint32 MemStreamReader::read(); +template uint32be MemStreamReader::read(); +template uint64 MemStreamReader::read(); +template int MemStreamReader::read(); + +template<> +std::string MemStreamReader::read() +{ + std::string s; + uint32 stringSize = read(); + if (hasError()) + return s; + if (stringSize >= (32 * 1024 * 1024)) + { + // out of bounds read or suspiciously large string + m_hasError = true; + return std::string(); + } + s.resize(stringSize); + readData(s.data(), stringSize); + return s; +} + +// read void + +template +void MemStreamReader::read(T& v) +{ + if (reserveReadLength(sizeof(T))) + { + const uint8* p = m_data + m_cursorPos; + std::memcpy(&v, p, sizeof(v)); + m_cursorPos += sizeof(T); + } +} + +template void MemStreamReader::read(uint8& v); +template void MemStreamReader::read(uint16& v); +template void MemStreamReader::read(uint32& v); +template void MemStreamReader::read(uint32be& v); +template void MemStreamReader::read(uint64& v); +template void MemStreamReader::read(int& v); + +template<> +void MemStreamReader::read(std::string& v) +{ + uint32 stringSize = read(); + if (!hasError()) + { + if (stringSize >= (32 * 1024 * 1024)) + { + // out of bounds read or suspiciously large string + m_hasError = true; + } + else + { + v.resize(stringSize); + readData(v.data(), stringSize); + } + } +} + +// readSection + +void MemStreamReader::readSection(const char* sec) +{ + std::string sec_str = std::string(sec); + cemu_assert_debug(read() == sec_str); +} + // readBE return template @@ -19,7 +105,6 @@ template uint8 MemStreamReader::readBE(); template uint16 MemStreamReader::readBE(); template uint32 MemStreamReader::readBE(); template uint64 MemStreamReader::readBE(); -template int MemStreamReader::readBE(); template<> std::string MemStreamReader::readBE() @@ -39,45 +124,6 @@ std::string MemStreamReader::readBE() return s; } -// readBE void - -template -void MemStreamReader::readBE(T& v) -{ - if (reserveReadLength(sizeof(T))) - { - const uint8* p = m_data + m_cursorPos; - std::memcpy(&v, p, sizeof(v)); - v = _BE(v); - m_cursorPos += sizeof(T); - } -} - -template void MemStreamReader::readBE(uint8& v); -template void MemStreamReader::readBE(uint16& v); -template void MemStreamReader::readBE(uint32& v); -template void MemStreamReader::readBE(uint64& v); -template void MemStreamReader::readBE(int& v); - -template<> -void MemStreamReader::readBE(std::string& v) -{ - uint32 stringSize = readBE(); - if (!hasError()) - { - if (stringSize >= (32 * 1024 * 1024)) - { - // out of bounds read or suspiciously large string - m_hasError = true; - } - else - { - v.resize(stringSize); - readData(v.data(), stringSize); - } - } -} - // readLE return template @@ -94,15 +140,39 @@ T MemStreamReader::readLE() } template uint8 MemStreamReader::readLE(); -template uint16 MemStreamReader::readLE(); template uint32 MemStreamReader::readLE(); +template uint64 MemStreamReader::readLE(); -// readSection +// write void -void MemStreamReader::readSection(const char* sec) +template +void MemStreamWriter::write(const T& v) +{ + m_buffer.resize(m_buffer.size() + sizeof(T)); + uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); + std::memcpy(p, &v, sizeof(v)); +} + +template void MemStreamWriter::write(const int& v); +template void MemStreamWriter::write(const uint64& v); +template void MemStreamWriter::write(const uint32be& v); +template void MemStreamWriter::write(const uint32& v); +template void MemStreamWriter::write(const uint16& v); +template void MemStreamWriter::write(const uint8& v); + +template<> +void MemStreamWriter::write(const std::string& v) +{ + write((uint32)v.size()); + writeData(v.data(), v.size()); +} + +// writeSection + +void MemStreamWriter::writeSection(const char* sec) { std::string sec_str = std::string(sec); - cemu_assert_debug(readBE() == sec_str); + write(sec_str); } // writeBE void @@ -116,11 +186,10 @@ void MemStreamWriter::writeBE(const T& v) std::memcpy(p, &tmp, sizeof(tmp)); } -template void MemStreamWriter::writeBE(const uint8& v); -template void MemStreamWriter::writeBE(const uint16& v); -template void MemStreamWriter::writeBE(const uint32& v); template void MemStreamWriter::writeBE(const uint64& v); -template void MemStreamWriter::writeBE(const int& v); +template void MemStreamWriter::writeBE(const uint32& v); +template void MemStreamWriter::writeBE(const uint16& v); +template void MemStreamWriter::writeBE(const uint8& v); template<> void MemStreamWriter::writeBE(const std::string& v) @@ -140,14 +209,6 @@ void MemStreamWriter::writeLE(const T& v) std::memcpy(p, &tmp, sizeof(tmp)); } -template void MemStreamWriter::writeLE(const uint8& v); -template void MemStreamWriter::writeLE(const uint16& v); +template void MemStreamWriter::writeLE(const uint64& v); template void MemStreamWriter::writeLE(const uint32& v); -// writeSection - -void MemStreamWriter::writeSection(const char* sec) -{ - std::string sec_str = std::string(sec); - writeBE(sec_str); -} \ No newline at end of file diff --git a/src/util/helpers/Serializer.h b/src/util/helpers/Serializer.h index 0e493254..5d854e48 100644 --- a/src/util/helpers/Serializer.h +++ b/src/util/helpers/Serializer.h @@ -8,14 +8,21 @@ public: m_cursorPos = 0; } + template T read(); + template void read(T& v); template T readBE(); template void readBE(T& v); template T readLE(); + void readAtomic(std::atomic& v) + { + v.store(readBool()); + } + template void readAtomic(std::atomic& v) { - v.store(readBE()); + v.store(read()); } template @@ -48,29 +55,29 @@ public: template void readPTR(T& v) { - v = (T)(memory_base + readBE()); + v = (T)(memory_base + read()); } template class C, typename T> void readMPTR(C& v) { - v = (T*)(memory_base + readBE()); + v = (T*)(memory_base + read()); } template class C, typename T, size_t c, size_t a> void readMPTR(C& v) { - v = (T*)(memory_base + readBE()); + v = (T*)(memory_base + read()); } void readBool(bool& v) { - v = readBE(); + v = read(); } bool readBool() { - return readBE(); + return read(); } void readSection(const char* sec); @@ -212,13 +219,19 @@ public: } } + template void write(const T& v); template void writeBE(const T& v); template void writeLE(const T& v); + void writeAtomic(const std::atomic& v) + { + writeBool(v.load()); + } + template void writeAtomic(const std::atomic& v) { - writeBE(v.load()); + write(v.load()); } template @@ -232,18 +245,18 @@ public: template void writePTR(const T& v) { - writeBE((uint32)((uint8*)v - (uint8*)memory_base)); + write((uint32)((uint8*)v - (uint8*)memory_base)); } template void writeMPTR(const T& v) { - writeBE(v.GetMPTR()); + write(v.GetMPTR()); } void writeBool(const bool& v) { - writeBE((uint8)v); + write((uint8)v); } void writeSection(const char* sec); From f44e12f4d845126eb7b9ffa3cae69bc5a73e2fcb Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Tue, 10 Oct 2023 21:55:54 -0400 Subject: [PATCH 7/9] Fix various issues --- src/Cafe/CafeSystem.cpp | 25 +++-- src/Cafe/OS/libs/coreinit/coreinit.cpp | 12 +-- .../OS/libs/coreinit/coreinit_CodeGen.cpp | 15 ++- src/Cafe/OS/libs/coreinit/coreinit_FS.cpp | 4 +- src/Cafe/OS/libs/coreinit/coreinit_Init.cpp | 4 +- .../OS/libs/coreinit/coreinit_SysHeap.cpp | 4 +- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 36 ++++++- src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 2 +- src/Cafe/OS/libs/nn_fp/nn_fp.cpp | 6 +- src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp | 36 ++++++- src/Cafe/OS/libs/nn_olv/nn_olv.cpp | 4 + src/Cafe/OS/libs/nn_uds/nn_uds.cpp | 4 +- src/Cafe/OS/libs/nsyshid/nsyshid.cpp | 8 +- src/Cafe/OS/libs/nsysnet/nsysnet.cpp | 2 + src/Cafe/OS/libs/padscore/padscore.cpp | 100 +++++++++++++----- src/util/helpers/Serializer.h | 38 ++++--- 16 files changed, 216 insertions(+), 84 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 66d76ef5..f89c66a0 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -1003,10 +1003,7 @@ namespace CafeSystem PauseTitle(); // memory memory_Serialize(writer); - // gpu - writer.writeData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); - writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); - writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); + nn::temp::save(writer); nn::aoc::save(writer); @@ -1015,6 +1012,11 @@ namespace CafeSystem iosu::fsa::save(writer); iosu::odm::save(writer); + // gpu + writer.writeData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); + writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); + writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); + FileStream* stream = FileStream::createFile(path); stream->writeData(writer.getResult().data(), writer.getResult().size_bytes()); delete stream; @@ -1025,8 +1027,10 @@ namespace CafeSystem void LoadState(std::string path) { - PauseTitle(); + //coreinit::__OSDeleteAllActivePPCThreads(); + DestroyMemorySpace(); + cemuLog_log(LogType::SaveStates, "Loading state...", path); auto data = FileStream::LoadIntoMemory(path); @@ -1034,12 +1038,8 @@ namespace CafeSystem MemStreamReader reader(data->data(), data->size()); // memory - DestroyMemorySpace(); + memory_Deserialize(reader); - // gpu - reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); - reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); - reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); nn::temp::restore(reader); nn::aoc::restore(reader); @@ -1048,6 +1048,11 @@ namespace CafeSystem iosu::fsa::restore(reader); iosu::odm::restore(reader); + // gpu + reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister)); + reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); + reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); + cemuLog_log(LogType::SaveStates, "Loaded state from {}.", path); ResumeTitle(/*isThreadRunning*/); diff --git a/src/Cafe/OS/libs/coreinit/coreinit.cpp b/src/Cafe/OS/libs/coreinit/coreinit.cpp index 91f444d8..28601333 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit.cpp @@ -319,8 +319,7 @@ namespace coreinit void coreinit_save(MemStreamWriter& s) { s.writeSection("coreinit"); - - s.writeData(gCoreinitData, sizeof(coreinitData_t)); + s.writeNullableData(gCoreinitData, sizeof(coreinitData_t)); s.write(placeholderFont); s.write(placeholderFontSize); @@ -347,18 +346,13 @@ void coreinit_save(MemStreamWriter& s) void coreinit_restore(MemStreamReader& s) { s.readSection("coreinit"); - - bool recreate = false; - if (recreate) - coreinit::__OSDeleteAllActivePPCThreads(); - - s.readData(gCoreinitData, sizeof(coreinitData_t)); + s.readNullableData(gCoreinitData, sizeof(coreinitData_t)); s.read(placeholderFont); s.read(placeholderFontSize); coreinit_Init_Restore(s); coreinit::SysHeap_Restore(s); - coreinit::Thread_Restore(s, recreate); + coreinit::Thread_Restore(s); coreinit::MEM_Restore(s); coreinit::FG_Restore(s); coreinit::OverlayArena_Restore(s); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp index 7fea2b46..d4d70bc0 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_CodeGen.cpp @@ -25,9 +25,10 @@ namespace coreinit } } + static constexpr uint32 const codegenSize = 0x01000000; // todo: Read from cos.xml + void OSGetCodegenVirtAddrRange(betype* rangeStart, betype* rangeSize) { - uint32 codegenSize = 0x01000000; // todo: Read from cos.xml //debug_printf("OSGetCodegenVirtAddrRange(0x%08x,0x%08x)\n", hCPU->gpr[3], hCPU->gpr[4]); // on first call, allocate range if( coreinitCodeGen.rangeIsAllocated == false ) @@ -139,13 +140,21 @@ namespace coreinit void CodeGen_Save(MemStreamWriter& s) { s.writeSection("coreinit_CodeGen"); - s.writeData(&coreinitCodeGen, sizeof(coreinitCodeGen)); + s.writeBool(coreinitCodeGen.rangeIsAllocated); + s.write(coreinitCodeGen.rangeStart); + s.write(coreinitCodeGen.rangeSize); + s.write(codegenSize); + s.writeNullableData(coreinitCodeGen.cacheStateCopy, codegenSize); } void CodeGen_Restore(MemStreamReader& s) { s.readSection("coreinit_CodeGen"); - s.readData(&coreinitCodeGen, sizeof(coreinitCodeGen)); + s.readBool(coreinitCodeGen.rangeIsAllocated); + s.read(coreinitCodeGen.rangeStart); + s.read(coreinitCodeGen.rangeSize); + cemu_assert(s.read() == codegenSize); + s.readNullableData(coreinitCodeGen.cacheStateCopy, codegenSize); } void InitializeCodeGen() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp index ca840517..e0115dd3 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_FS.cpp @@ -2641,7 +2641,7 @@ namespace coreinit void FS_Save(MemStreamWriter& s) { s.writeSection("coreinit_FS"); - s.writeData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + s.writePTR(g_fsRegisteredClientBodies); s.writeBool(_sdCard01Mounted); s.writeBool(_mlc01Mounted); s.writeMPTR(_tempFSSpace); @@ -2654,7 +2654,7 @@ namespace coreinit void FS_Restore(MemStreamReader& s) { s.readSection("coreinit_FS"); - s.readData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t)); + s.readPTR(g_fsRegisteredClientBodies); s.readBool(_sdCard01Mounted); s.readBool(_mlc01Mounted); s.readMPTR(_tempFSSpace); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp index f75d45ff..508d6aa5 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp @@ -219,7 +219,7 @@ void coreinit_start(PPCInterpreter_t* hCPU) void coreinit_Init_Save(MemStreamWriter& s) { s.writeSection("coreinit_Init"); - s.writeData(_coreinitInfo, sizeof(coreinitInit_t)); + s.writeNullableData(_coreinitInfo, sizeof(coreinitInit_t)); s.write(argStorageIndex); s.writeMPTR(g_preinitUserParam); s.write(_coreinitTitleEntryPoint); @@ -228,7 +228,7 @@ void coreinit_Init_Save(MemStreamWriter& s) void coreinit_Init_Restore(MemStreamReader& s) { s.readSection("coreinit_Init"); - s.readData(_coreinitInfo, sizeof(coreinitInit_t)); + s.readNullableData(_coreinitInfo, sizeof(coreinitInit_t)); s.read(argStorageIndex); s.readMPTR(g_preinitUserParam); s.read(_coreinitTitleEntryPoint); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp index 7603c513..85e71bf8 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_SysHeap.cpp @@ -35,7 +35,7 @@ namespace coreinit void SysHeap_Save(MemStreamWriter& s) { s.writeSection("coreinit_SysHeap"); - s.writeData(_sysHeapHandle, sizeof(MEMHeapBase)); + s.writePTR(_sysHeapHandle); s.write(_sysHeapAllocCounter); s.write(_sysHeapFreeCounter); } @@ -43,7 +43,7 @@ namespace coreinit void SysHeap_Restore(MemStreamReader& s) { s.readSection("coreinit_SysHeap"); - s.readData(_sysHeapHandle, sizeof(MEMHeapBase)); + s.readPTR(_sysHeapHandle); s.read(_sysHeapAllocCounter); s.read(_sysHeapFreeCounter); } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index bce0955c..5f608f9d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -13,6 +13,7 @@ #include "util/Fiber/Fiber.h" #include "util/helpers/helpers.h" +#include "Common/FileStream.h" SlimRWLock srwlock_activeThreadList; @@ -1331,11 +1332,27 @@ namespace coreinit } } + void DumpActiveThreads(std::string v) + { + for (auto& thr : activeThread) + { + if (thr != MPTR_NULL) + { + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); + MemStreamWriter writer(0); + writer.writeData(ptr, sizeof(OSThread_t)); + FileStream* stream = FileStream::createFile(std::to_string(thr) + "_" + v + ".bin"); + stream->writeData(writer.getResult().data(), writer.getResult().size_bytes()); + delete stream; + } + } + } + void Thread_Save(MemStreamWriter& s) { s.writeSection("coreinit_Thread"); - s.write((uint8)sSchedulerActive.load()); + s.writeAtomic(sSchedulerActive); s.writeMPTR(g_activeThreadQueue); s.writeMPTR(g_coreRunQueue); @@ -1343,6 +1360,8 @@ namespace coreinit for (sint32 i = 0; i < activeThreadCount; i++) { s.write(activeThread[i]); + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(activeThread[i]); + //s.write((uint8)ptr->state.value()); } for (sint32 i = 0; i < PPC_CORE_COUNT; i++) { @@ -1356,25 +1375,32 @@ namespace coreinit } s.writeMPTR(s_defaultThreads); s.writeMPTR(s_stack); + + DumpActiveThreads("save"); } - void Thread_Restore(MemStreamReader& s, bool recreate) + void Thread_Restore(MemStreamReader& s) { s.readSection("coreinit_Thread"); - sSchedulerActive.store(s.read()); + s.readAtomic(sSchedulerActive); s.readMPTR(g_activeThreadQueue); s.readMPTR(g_coreRunQueue); + bool recreate = false; + sint32 prevActiveThreadCount = s.read(); for (sint32 i = 0; i < prevActiveThreadCount; i++) { MPTR threadMPTR = s.read(); if (recreate) { + auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(threadMPTR); + __OSLockScheduler(); - __OSActivateThread((OSThread_t*)memory_getPointerFromVirtualOffset(threadMPTR)); + __OSActivateThread(ptr); __OSUnlockScheduler(); + //ptr->state = betype((OSThread_t::THREAD_STATE)s.read()); } else { @@ -1394,6 +1420,8 @@ namespace coreinit } s.readMPTR(s_defaultThreads); s.readMPTR(s_stack); + + DumpActiveThreads("restore"); } void SuspendActiveThreads() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index de042da6..b524e158 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -497,7 +497,7 @@ static_assert(sizeof(OSThread_t) == 0x6A0-4); // todo - determine correct size namespace coreinit { void Thread_Save(MemStreamWriter& s); - void Thread_Restore(MemStreamReader& s, bool recreate); + void Thread_Restore(MemStreamReader& s); void SuspendActiveThreads(); void ResumeActiveThreads(); diff --git a/src/Cafe/OS/libs/nn_fp/nn_fp.cpp b/src/Cafe/OS/libs/nn_fp/nn_fp.cpp index 79e67f08..148ffd6d 100644 --- a/src/Cafe/OS/libs/nn_fp/nn_fp.cpp +++ b/src/Cafe/OS/libs/nn_fp/nn_fp.cpp @@ -742,13 +742,15 @@ namespace nn void save(MemStreamWriter& s) { s.writeSection("nn_fp"); - s.writeData(&g_fp, sizeof(g_fp)); + s.writeBool(g_fp.isAdminMode); + s.writeBool(g_fp.isInitialized); } void restore(MemStreamReader& s) { s.readSection("nn_fp"); - s.readData(&g_fp, sizeof(g_fp)); + s.readBool(g_fp.isAdminMode); + s.readBool(g_fp.isInitialized); } void load() diff --git a/src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp b/src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp index 1d7a2466..5d7b80af 100644 --- a/src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp +++ b/src/Cafe/OS/libs/nn_nfp/nn_nfp.cpp @@ -1018,13 +1018,45 @@ namespace nn::nfp void save(MemStreamWriter& s) { s.writeSection("nn_nfp"); - s.writeData(&nfp_data, sizeof(nfp_data)); + s.writeBool(nfp_data.nfpIsInitialized); + s.write(nfp_data.activateEvent); + s.write(nfp_data.deactivateEvent); + s.writeBool(nfp_data.isDetecting); + s.writeBool(nfp_data.isMounted); + s.writeBool(nfp_data.isReadOnly); + s.writeBool(nfp_data.hasOpenApplicationArea); + s.writeBool(nfp_data.hasActiveAmiibo); + + s.writeBool(nfp_data.hasInvalidHMAC); + s.write(nfp_data.amiiboTouchTime); + s.write(sizeof(AmiiboRawNFCData)); + s.writeData(&nfp_data.amiiboNFCData, sizeof(AmiiboRawNFCData)); + s.write(sizeof(AmiiboInternal)); + s.writeData(&nfp_data.amiiboInternal, sizeof(AmiiboInternal)); + s.write(sizeof(AmiiboProcessedData)); + s.writeData(&nfp_data.amiiboProcessedData, sizeof(AmiiboProcessedData)); } void restore(MemStreamReader& s) { s.readSection("nn_nfp"); - s.readData(&nfp_data, sizeof(nfp_data)); + s.readBool(nfp_data.nfpIsInitialized); + s.read(nfp_data.activateEvent); + s.read(nfp_data.deactivateEvent); + s.readBool(nfp_data.isDetecting); + s.readBool(nfp_data.isMounted); + s.readBool(nfp_data.isReadOnly); + s.readBool(nfp_data.hasOpenApplicationArea); + s.readBool(nfp_data.hasActiveAmiibo); + + s.readBool(nfp_data.hasInvalidHMAC); + s.read(nfp_data.amiiboTouchTime); + cemu_assert(s.read() == sizeof(AmiiboRawNFCData)); + s.readData(&nfp_data.amiiboNFCData, sizeof(AmiiboRawNFCData)); + cemu_assert(s.read() == sizeof(AmiiboInternal)); + s.readData(&nfp_data.amiiboInternal, sizeof(AmiiboInternal)); + cemu_assert(s.read() == sizeof(AmiiboProcessedData)); + s.readData(&nfp_data.amiiboProcessedData, sizeof(AmiiboProcessedData)); } void load() diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp index 73e19175..e866013d 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp @@ -116,7 +116,9 @@ namespace nn s.writeMPTR(s_OlvReleaseBgThread); s.writeMPTR(s_OlvReleaseBgThreadStack); s.writeMPTR(s_OlvReleaseBgThreadName); + s.write(sizeof(ParamPackStorage)); s.writeData(&g_ParamPack, sizeof(ParamPackStorage)); + s.write(sizeof(DiscoveryResultStorage)); s.writeData(&g_DiscoveryResults, sizeof(DiscoveryResultStorage)); s.write(g_ReportTypes); s.writeBool(g_IsInitialized); @@ -131,7 +133,9 @@ namespace nn s.readMPTR(s_OlvReleaseBgThread); s.readMPTR(s_OlvReleaseBgThreadStack); s.readMPTR(s_OlvReleaseBgThreadName); + cemu_assert(s.read() == sizeof(ParamPackStorage)); s.readData(&g_ParamPack, sizeof(ParamPackStorage)); + cemu_assert(s.read() == sizeof(DiscoveryResultStorage)); s.readData(&g_DiscoveryResults, sizeof(DiscoveryResultStorage)); s.read(g_ReportTypes); s.readBool(g_IsInitialized); diff --git a/src/Cafe/OS/libs/nn_uds/nn_uds.cpp b/src/Cafe/OS/libs/nn_uds/nn_uds.cpp index 7062df0e..6b7ad841 100644 --- a/src/Cafe/OS/libs/nn_uds/nn_uds.cpp +++ b/src/Cafe/OS/libs/nn_uds/nn_uds.cpp @@ -18,13 +18,13 @@ void nnUdsExport___sti___11_uds_Api_cpp_f5d9abb2(PPCInterpreter_t* hCPU) void nnUds_save(MemStreamWriter& s) { s.writeSection("nn_uds"); - s.writeData(udsWorkspace, sizeof(udsWorkspace_t)); + s.writeNullableData(udsWorkspace, sizeof(udsWorkspace_t)); } void nnUds_restore(MemStreamReader& s) { s.readSection("nn_uds"); - s.readData(udsWorkspace, sizeof(udsWorkspace_t)); + s.readNullableData(udsWorkspace, sizeof(udsWorkspace_t)); } /* diff --git a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp index 62e4df8d..febc2a91 100644 --- a/src/Cafe/OS/libs/nsyshid/nsyshid.cpp +++ b/src/Cafe/OS/libs/nsyshid/nsyshid.cpp @@ -816,8 +816,8 @@ namespace nsyshid void save(MemStreamWriter& s) { s.writeSection("nsyshid"); - s.writeData(firstDevice, sizeof(HIDDeviceInfo_t)); - s.writeData(firstHIDClient, sizeof(HIDClient_t)); + s.writePTR(firstDevice); + s.writeNullableData(firstHIDClient, sizeof(HIDClient_t)); s.write(_lastGeneratedHidHandle); s.writeMPTR(_devicePool); s.write(_devicePoolMask.count()); @@ -826,8 +826,8 @@ namespace nsyshid void restore(MemStreamReader& s) { s.readSection("nsyshid"); - s.readData(firstDevice, sizeof(HIDDeviceInfo_t)); - s.readData(firstHIDClient, sizeof(HIDClient_t)); + s.readPTR(firstDevice); + s.readNullableData(firstHIDClient, sizeof(HIDClient_t)); s.read(_lastGeneratedHidHandle); s.readMPTR(_devicePool); _devicePoolMask.reset(); diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp index b136df51..95fe0522 100644 --- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp +++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp @@ -2212,6 +2212,7 @@ void nsysnet_save(MemStreamWriter& s) for (auto i : nsysnet::g_nsslInternalStates) s.write(i); s.writeBool(sockLibReady); + s.write(sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); s.writeData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); } @@ -2233,6 +2234,7 @@ void nsysnet_restore(MemStreamReader& s) nsysnet::g_nsslInternalStates.push_back(t); } s.readBool(sockLibReady); + cemu_assert(s.read() == sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); s.readData(virtualSocketTable, sizeof(virtualSocket_t) * WU_SOCKET_LIMIT); } diff --git a/src/Cafe/OS/libs/padscore/padscore.cpp b/src/Cafe/OS/libs/padscore/padscore.cpp index f6531d32..e3d4b6b1 100644 --- a/src/Cafe/OS/libs/padscore/padscore.cpp +++ b/src/Cafe/OS/libs/padscore/padscore.cpp @@ -53,7 +53,7 @@ namespace padscore WPADState_t g_wpad_state = kWPADStateMaster; - struct g_padscore_t + typedef struct _g_padscore_t { SysAllocator alarm; bool kpad_initialized = false; @@ -72,7 +72,9 @@ namespace padscore } controller_data[InputManager::kMaxWPADControllers] = {}; int max_controllers = kWPADMaxControllers; // max bt controllers? - } g_padscore; + } g_padscore_t; + + g_padscore_t g_padscore; } @@ -747,30 +749,6 @@ namespace padscore OSSetPeriodicAlarm(&g_padscore.alarm, start_tick, period_tick, handler); } - void save(MemStreamWriter& s) - { - s.writeSection("padscore"); - s.writeBool(debugUseDRC1); - s.writeBool(g_kpadIsInited); - s.writeData(&g_padscore, sizeof(g_padscore_t)); - s.writeData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); - s.write(g_kpad_ringbuffer_length); - s.writeBool(g_wpad_callback_by_kpad); - s.write((uint32)g_wpad_state); - } - - void restore(MemStreamReader& s) - { - s.readSection("padscore"); - s.readBool(debugUseDRC1); - s.readBool(g_kpadIsInited); - s.readData(&g_padscore, sizeof(g_padscore_t)); - s.readData(g_kpad_ringbuffer, sizeof(KPADUnifiedWpadStatus_t)); - s.read(g_kpad_ringbuffer_length); - s.readBool(g_wpad_callback_by_kpad); - g_wpad_state = (WPADState_t)s.read(); - } - void load() { cafeExportRegister("padscore", WPADIsMplsAttached, LogType::InputAPI); @@ -813,3 +791,73 @@ namespace padscore } } + +template<> +void MemStreamWriter::write(const padscore::g_padscore_t& v) +{ + writeMPTR(v.alarm); + writeBool(v.kpad_initialized); + write(InputManager::kMaxWPADControllers); + for (auto i : v.controller_data) + { + writeMPTR(i.extension_callback); + writeMPTR(i.connectCallback); + writeMPTR(i.sampling_callback); + writeMPTR(i.dpd_callback); + writeBool(i.dpd_enabled); + writeBool(i.disconnectCalled); + writeBool(i.disconnectCalled); + write(i.btn_repeat.delay); + write(i.btn_repeat.pulse); + } + write(v.max_controllers); +} + +template <> +void MemStreamReader::read(padscore::g_padscore_t& v) +{ + readMPTR(v.alarm); + readBool(v.kpad_initialized); + cemu_assert(read() == InputManager::kMaxWPADControllers); + for (auto i : v.controller_data) + { + readMPTR(i.extension_callback); + readMPTR(i.connectCallback); + readMPTR(i.sampling_callback); + readMPTR(i.dpd_callback); + readBool(i.dpd_enabled); + readBool(i.disconnectCalled); + readBool(i.disconnectCalled); + read(i.btn_repeat.delay); + read(i.btn_repeat.pulse); + } + read(v.max_controllers); +} + +namespace padscore +{ + void save(MemStreamWriter& s) + { + s.writeSection("padscore"); + s.writeBool(debugUseDRC1); + s.writeBool(g_kpadIsInited); + s.write(g_padscore); + s.writePTR(g_kpad_ringbuffer); + s.write(g_kpad_ringbuffer_length); + s.writeBool(g_wpad_callback_by_kpad); + s.write((uint32)g_wpad_state); + } + + void restore(MemStreamReader& s) + { + s.readSection("padscore"); + s.readBool(debugUseDRC1); + s.readBool(g_kpadIsInited); + s.read(g_padscore); + s.readPTR(g_kpad_ringbuffer); + s.read(g_kpad_ringbuffer_length); + s.readBool(g_wpad_callback_by_kpad); + g_wpad_state = (WPADState_t)s.read(); + } +} + diff --git a/src/util/helpers/Serializer.h b/src/util/helpers/Serializer.h index 5d854e48..f5d474c4 100644 --- a/src/util/helpers/Serializer.h +++ b/src/util/helpers/Serializer.h @@ -125,6 +125,19 @@ public: } bool readData(void* ptr, size_t size) + { + if (m_cursorPos + size > m_size) + { + m_cursorPos = m_size; + m_hasError = true; + return false; + } + memcpy(ptr, m_data + m_cursorPos, size); + m_cursorPos += (sint32)size; + return true; + } + + bool readNullableData(void* ptr, size_t size) { if (readBE()) { @@ -133,16 +146,8 @@ public: } else { - if (m_cursorPos + size > m_size) - { - m_cursorPos = m_size; - m_hasError = true; - return false; - } - memcpy(ptr, m_data + m_cursorPos, size); - m_cursorPos += (sint32)size; - return true; - } + return readData(ptr, size); + } } std::span readDataNoCopy(size_t size) @@ -209,14 +214,17 @@ public: } void writeData(const void* ptr, size_t size) + { + m_buffer.resize(m_buffer.size() + size); + uint8* p = m_buffer.data() + m_buffer.size() - size; + memcpy(p, ptr, size); + } + + void writeNullableData(void* ptr, size_t size) { writeBE((uint8)(ptr == NULL)); if (ptr) - { - m_buffer.resize(m_buffer.size() + size); - uint8* p = m_buffer.data() + m_buffer.size() - size; - memcpy(p, ptr, size); - } + writeData(ptr, size); } template void write(const T& v); From 7529383861ab8145da6d3187e296a30d7dd19552 Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sat, 5 Apr 2025 23:48:15 -0400 Subject: [PATCH 8/9] Minor changes. --- src/Cafe/HW/MMU/MMU.cpp | 56 +++++++++---------- src/Cafe/IOSU/fsa/iosu_fsa.cpp | 13 ++++- .../libs/coreinit/coreinit_MemoryMapping.cpp | 2 +- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 3c05c805..8793d8c4 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -80,33 +80,6 @@ MMURange* memory_getMMURangeByAddress(MPTR address) return nullptr; } -template<> -void MemStreamWriter::write(const MMURange& v) -{ - writeBool(v.m_isMapped); - write(v.baseAddress); - write((uint8)v.areaId); - write((uint8)v.flags); - write(v.name); - write(v.size); - write(v.initSize); -} - -template <> -void MemStreamReader::read(MMURange& mmuRange) -{ - bool needsMapped = readBool(); - mmuRange.m_isMapped = false; - mmuRange.baseAddress = read(); - mmuRange.areaId = (MMU_MEM_AREA_ID)read(); - mmuRange.flags = (MMURange::MFLAG)read(); - mmuRange.name = read(); - mmuRange.size = read(); - mmuRange.initSize = read(); - if (needsMapped) - mmuRange.mapMem(); -} - MMURange::MMURange(const uint32 baseAddress, const uint32 size, MMU_MEM_AREA_ID areaId, const std::string_view name, MFLAG flags) : baseAddress(baseAddress), size(size), initSize(size), areaId(areaId), name(name), flags(flags) { g_mmuRanges.emplace_back(this); @@ -439,6 +412,33 @@ void memory_createDump() } } +template<> +void MemStreamWriter::write(const MMURange& v) +{ + writeBool(v.m_isMapped); + write(v.baseAddress); + write((uint8)v.areaId); + write((uint8)v.flags); + write(v.name); + write(v.size); + write(v.initSize); +} + +template <> +void MemStreamReader::read(MMURange& v) +{ + bool needsMapped = readBool(); + v.m_isMapped = false; + read(v.baseAddress); + v.areaId = (MMU_MEM_AREA_ID)read(); + v.flags = (MMURange::MFLAG)read(); + read(v.name); + read(v.size); + read(v.initSize); + if (needsMapped) + v.mapMem(); +} + void memory_Serialize(MemStreamWriter& s) { for (auto& itr : g_mmuRanges) @@ -455,7 +455,7 @@ void memory_Deserialize(MemStreamReader& s) { for (auto& itr : g_mmuRanges) { - s.read(*itr); + s.read(*itr); if (itr->isMapped()) { s.readData(memory_base + itr->getBase(), itr->getSize()); diff --git a/src/Cafe/IOSU/fsa/iosu_fsa.cpp b/src/Cafe/IOSU/fsa/iosu_fsa.cpp index b24607a3..138d8d39 100644 --- a/src/Cafe/IOSU/fsa/iosu_fsa.cpp +++ b/src/Cafe/IOSU/fsa/iosu_fsa.cpp @@ -928,7 +928,7 @@ template <> void MemStreamWriter::write(const iosu::fsa::_FSAHandleTable& v) { write(v.m_currentCounter); - for (sint32 i = 0; i < v.m_handleTableSize; i++) + for (sint32 i = 0; i < v.m_handleTable.size(); i++) { write(v.m_handleTable[i].handleCheckValue); writeBool(v.m_handleTable[i].isAllocated); @@ -942,12 +942,19 @@ template <> void MemStreamReader::read(iosu::fsa::_FSAHandleTable& v) { read(v.m_currentCounter); - for (sint32 i = 0; i < v.m_handleTableSize; i++) + for (sint32 i = 0; i < v.m_handleTable.size(); i++) { read(v.m_handleTable[i].handleCheckValue); readBool(v.m_handleTable[i].isAllocated); - if (readBool()) v.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); + if (readBool()) + { + v.m_handleTable[i].fscFile = FSCVirtualFile::Restore(*this); + } + else + { + v.m_handleTable[i].fscFile = nullptr; + } } } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp index 0be5ce08..cfce570f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_MemoryMapping.cpp @@ -173,7 +173,7 @@ namespace coreinit s_allocatedVirtMemory.reserve(s_allocatedVirtMemorySize); for (sint32 i = 0; i < s_allocatedVirtMemorySize; i++) { - s_allocatedVirtMemory.push_back(OSVirtMemoryEntry(s.read(), s.read(), s.read())); + s_allocatedVirtMemory.emplace_back(s.read(), s.read(), s.read()); } } From cbfb5c519bc363738085b9f9ab146b05b9b9f1de Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sun, 6 Apr 2025 00:37:50 -0400 Subject: [PATCH 9/9] Rename functions. --- src/Cafe/OS/common/OSCommon.cpp | 4 ++-- src/Cafe/OS/libs/proc_ui/proc_ui.cpp | 4 ++-- src/Cafe/OS/libs/proc_ui/proc_ui.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Cafe/OS/common/OSCommon.cpp b/src/Cafe/OS/common/OSCommon.cpp index 81612e3f..69e4bad0 100644 --- a/src/Cafe/OS/common/OSCommon.cpp +++ b/src/Cafe/OS/common/OSCommon.cpp @@ -205,7 +205,7 @@ void osLib_save(MemStreamWriter& s) nlibcurl::save(s); nsyshid::save(s); camera::save(s); - procui_save(s); + proc_ui::save(s); } void osLib_restore(MemStreamReader& s) { @@ -225,7 +225,7 @@ void osLib_restore(MemStreamReader& s) nlibcurl::restore(s); nsyshid::restore(s); camera::restore(s); - procui_restore(s); + proc_ui::restore(s); } void osLib_load() diff --git a/src/Cafe/OS/libs/proc_ui/proc_ui.cpp b/src/Cafe/OS/libs/proc_ui/proc_ui.cpp index 4cf4c20d..156f5046 100644 --- a/src/Cafe/OS/libs/proc_ui/proc_ui.cpp +++ b/src/Cafe/OS/libs/proc_ui/proc_ui.cpp @@ -875,12 +875,12 @@ namespace proc_ui s_driverInBackground = false; } - void ProcUISave(MemStreamWriter& s) + void save(MemStreamWriter& s) { s.writeSection("proc_ui"); } - void ProcUIRestore(MemStreamReader& s) + void restore(MemStreamReader& s) { s.readSection("proc_ui"); } diff --git a/src/Cafe/OS/libs/proc_ui/proc_ui.h b/src/Cafe/OS/libs/proc_ui/proc_ui.h index 6063b7c6..2bbdabb3 100644 --- a/src/Cafe/OS/libs/proc_ui/proc_ui.h +++ b/src/Cafe/OS/libs/proc_ui/proc_ui.h @@ -39,8 +39,8 @@ namespace proc_ui void ProcUIDrawDoneRelease(); ProcUIStatus ProcUIProcessMessages(bool isBlockingInBackground); ProcUIStatus ProcUISubProcessMessages(bool isBlockingInBackground); - void ProcUISave(MemStreamWriter& s); - void ProcUIRestore(MemStreamReader& s); + void save(MemStreamWriter& s); + void restore(MemStreamReader& s); void load(); } \ No newline at end of file