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);