From 51072b510c74e078350f70f31386802f2e78159f Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Wed, 3 Apr 2024 01:45:05 +0200 Subject: [PATCH] nn_boss: Large rework with various improvements Lots of internal changes. On the surface this only fixes a crash in Mario & Sonic Rio 2016 (at least what I saw from my testing) but it may affect more games. Summary of changes: - Rewrite code to use newer cafeExportRegisterFunc - Simplify code by merging namespaces and structs of the same types - Correctly set ppc vtables for the virtual boss classes - Fix some wrong function definitions and implement a little bit more of the boss API (mainly constructors and destructors) --- src/Cafe/OS/libs/nn_boss/nn_boss.cpp | 2710 +++++++++++++------------- src/Cemu/Logging/CemuLogging.cpp | 1 + src/Cemu/Logging/CemuLogging.h | 1 + src/gui/MainWindow.cpp | 1 + 4 files changed, 1325 insertions(+), 1388 deletions(-) diff --git a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp index c2d65a5f..f53a6d79 100644 --- a/src/Cafe/OS/libs/nn_boss/nn_boss.cpp +++ b/src/Cafe/OS/libs/nn_boss/nn_boss.cpp @@ -27,13 +27,244 @@ bossBufferVector->buffer = (uint8*)bossRequest; sint32 g_initCounter = 0; bool g_isInitialized = false; - void freeMem(void* mem) + struct VTableEntry { - if(mem) - coreinit::default_MEMFreeToDefaultHeap((uint8*)mem - 8); + uint16be offsetA{0}; + uint16be offsetB{0}; + MEMPTR ptr; + }; + static_assert(sizeof(VTableEntry) == 8); + + #define DTOR_WRAPPER(__TYPE) RPLLoader_MakePPCCallable([](PPCInterpreter_t* hCPU) { dtor(MEMPTR<__TYPE>(hCPU->gpr[3]), hCPU->gpr[4]); osLib_returnFromFunction(hCPU, 0); }) + + constexpr uint32 BOSS_MEM_MAGIC = 0xCAFE4321; + + template + MEMPTR boss_new() + { + uint32 objSize = sizeof(T); + uint32be* basePtr = (uint32be*)coreinit::_weak_MEMAllocFromDefaultHeapEx(objSize + 8, 0x8); + basePtr[0] = BOSS_MEM_MAGIC; + basePtr[1] = objSize; + return (T*)(basePtr+2); } - struct TaskSetting_t + void boss_delete(MEMPTR mem) + { + if(!mem) + return; + uint32be* basePtr = (uint32be*)mem.GetPtr() - 2; + if(basePtr[0] != BOSS_MEM_MAGIC) + { + cemuLog_log(LogType::Force, "nn_boss: Detected memory corruption"); + cemu_assert_suspicious(); + } + coreinit::_weak_MEMFreeToDefaultHeap(basePtr); + } + + Result Initialize() // Initialize__Q2_2nn4bossFv + { + coreinit::OSLockMutex(&g_mutex); + Result result = 0; + if(g_initCounter == 0) + { + g_isInitialized = true; + // IPC init here etc. + result = 0x200080; // init result + } + g_initCounter++; + coreinit::OSUnlockMutex(&g_mutex); + return NN_RESULT_IS_SUCCESS(result) ? 0 : result; + } + + uint32 IsInitialized() // IsInitialized__Q2_2nn4bossFv + { + return g_isInitialized; + } + + void Finalize() // Finalize__Q2_2nn4bossFv + { + coreinit::OSLockMutex(&g_mutex); + if(g_initCounter == 0) + cemuLog_log(LogType::Force, "nn_boss: Finalize() called without corresponding Initialize()"); + if(g_initCounter == 1) + { + g_isInitialized = false; + // IPC deinit here etc. + } + g_initCounter--; + coreinit::OSUnlockMutex(&g_mutex); + } + + uint32 GetBossState(PPCInterpreter_t* hCPU) + { + cemuLog_logDebug(LogType::Force, "nn_boss.GetBossState() - stub"); + return 7; + } + + struct TitleId + { + uint64be u64{}; + + static TitleId* ctor(TitleId* _thisptr, uint64 titleId) + { + if (!_thisptr) + _thisptr = boss_new(); + _thisptr->u64 = titleId; + return _thisptr; + } + + static TitleId* ctor(TitleId* _thisptr) + { + return ctor(_thisptr, 0); + } + + static bool IsValid(TitleId* _thisptr) + { + return _thisptr->u64 != 0; + } + + static TitleId* ctor1(TitleId* _thisptr, uint32 filler, uint64 titleId) + { + return ctor(_thisptr); + } + + static TitleId* ctor2(TitleId* _thisptr, uint32 filler, uint64 titleId) + { + cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_ctor2(0x{:x})", MEMPTR(_thisptr).GetMPTR()); + if (!_thisptr) + { + // _thisptr = new Task_t + assert_dbg(); + } + + _thisptr->u64 = titleId; + return _thisptr; + } + + static TitleId* ctor3(TitleId* _thisptr, TitleId* titleId) + { + cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_cctor(0x{:x})", MEMPTR(_thisptr).GetMPTR()); + if (!_thisptr) + _thisptr = boss_new(); + _thisptr->u64 = titleId->u64; + return _thisptr; + } + + static bool operator_ne(TitleId* _thisptr, TitleId* titleId) + { + cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_operator_ne(0x{:x})", MEMPTR(_thisptr).GetMPTR()); + return _thisptr->u64 != titleId->u64; + } + }; + static_assert(sizeof(TitleId) == 8); + + struct TaskId + { + char id[0x8]{}; + + static TaskId* ctor(TaskId* _thisptr) + { + if(!_thisptr) + _thisptr = boss_new(); + _thisptr->id[0] = '\0'; + return _thisptr; + } + }; + static_assert(sizeof(TaskId) == 8); + + struct Title + { + uint32be accountId{}; // 0x00 + TitleId titleId{}; // 0x8 + MEMPTR vTablePtr{}; // 0x10 + + struct VTable + { + VTableEntry rtti; + VTableEntry dtor; + }; + static inline SysAllocator s_titleVTable; + + static Title* ctor(Title* _this) + { + if (!_this) + _this = boss_new(); + *_this = {}; + _this->vTablePtr = s_titleVTable; + return _this; + } + + static void dtor(Title* _this, uint32 options) + { + if (_this && (options & 1)) + boss_delete(_this); + } + + static void InitVTable() + { + s_titleVTable->rtti.ptr = nullptr; // todo + s_titleVTable->dtor.ptr = DTOR_WRAPPER(Title); + } + }; + static_assert(sizeof(Title) == 0x18); + + struct DirectoryName + { + char name[0x8]{}; + + static DirectoryName* ctor(DirectoryName* _thisptr) + { + if (!_thisptr) + _thisptr = boss_new<DirectoryName>(); + memset(_thisptr->name, 0x00, 0x8); + return _thisptr; + } + + static const char* operator_const_char(DirectoryName* _thisptr) + { + return _thisptr->name; + } + }; + static_assert(sizeof(DirectoryName) == 8); + + struct BossAccount // the actual class name is "Account" and while the boss namespace helps us separate this from Account(.h) we use an alternative name to avoid confusion + { + struct VTable + { + VTableEntry rtti; + VTableEntry dtor; + }; + static inline SysAllocator<VTable> s_VTable; + + uint32be accountId; + MEMPTR<void> vTablePtr; + + static BossAccount* ctor(BossAccount* _this, uint32 accountId) + { + if (!_this) + _this = boss_new<BossAccount>(); + _this->accountId = accountId; + _this->vTablePtr = s_VTable; + return _this; + } + + static void dtor(BossAccount* _this, uint32 options) + { + if(_this && options & 1) + boss_delete(_this); + } + + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(BossAccount); + } + + }; + static_assert(sizeof(BossAccount) == 8); + + struct TaskSetting { static const uint32 kBossCode = 0x7C0; static const uint32 kBossCodeLen = 0x20; @@ -46,8 +277,6 @@ bossBufferVector->buffer = (uint8*)bossRequest; static const uint32 kNbdlFileName = 0x7F8; static const uint32 kFileNameLen = 0x20; - - static const uint32 kURL = 0x48; static const uint32 kURLLen = 0x100; @@ -57,245 +286,75 @@ bossBufferVector->buffer = (uint8*)bossRequest; static const uint32 kServiceToken = 0x590; static const uint32 kServiceTokenLen = 0x200; - uint8 settings[0x1000]; - uint32be uknExt_vTableProbably; // +0x1000 - }; - static_assert(sizeof(TaskSetting_t) == 0x1004); - static_assert(offsetof(TaskSetting_t, uknExt_vTableProbably) == 0x1000, "offsetof(TaskSetting_t, uknExt)"); + MEMPTR<void> vTablePtr; // +0x1000 - struct NetTaskSetting_t : TaskSetting_t + struct VTableTaskSetting + { + VTableEntry rtti; + VTableEntry dtor; + VTableEntry RegisterPreprocess; + VTableEntry unk1; + }; + static inline SysAllocator<VTableTaskSetting> s_VTable; + + static TaskSetting* ctor(TaskSetting* _thisptr) + { + if(!_thisptr) + _thisptr = boss_new<TaskSetting>(); + _thisptr->vTablePtr = s_VTable; + InitializeSetting(_thisptr); + return _thisptr; + } + + static void dtor(TaskSetting* _this, uint32 options) + { + cemuLog_logDebug(LogType::Force, "nn::boss::TaskSetting::dtor(0x{:08x}, 0x{:08x})", MEMPTR(_this).GetMPTR(), options); + if(options & 1) + boss_delete(_this); + } + + static bool IsPrivileged(TaskSetting* _thisptr) + { + const uint16 value = *(uint16be*)&_thisptr->settings[0x28]; + return value == 1 || value == 9 || value == 5; + } + + static void InitializeSetting(TaskSetting* _thisptr) + { + memset(_thisptr, 0x00, sizeof(TaskSetting::settings)); + *(uint32*)&_thisptr->settings[0x0C] = 0; + *(uint8*)&_thisptr->settings[0x2A] = 0x7D; // timeout? + *(uint32*)&_thisptr->settings[0x30] = 0x7080; + *(uint32*)&_thisptr->settings[0x8] = 0; + *(uint32*)&_thisptr->settings[0x38] = 0; + *(uint32*)&_thisptr->settings[0x3C] = 0x76A700; + *(uint32*)&_thisptr->settings[0] = 0x76A700; + } + + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(TaskSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + } + }; + static_assert(sizeof(TaskSetting) == 0x1004); + static_assert(offsetof(TaskSetting, vTablePtr) == 0x1000); + + struct NetTaskSetting : TaskSetting { // 0x188 cert1 + 0x188 cert2 + 0x188 cert3 // 0x190 AddCaCert (3times) char cert[0x80]; // SetConnectionSetting // SetFirstLastModifiedTime - }; - static_assert(sizeof(NetTaskSetting_t) == 0x1004); - struct NbdlTaskSetting_t : NetTaskSetting_t - { - //char fileName[0x20]; // @0x7F8 - }; - static_assert(sizeof(NbdlTaskSetting_t) == 0x1004); + struct VTableNetTaskSetting : public VTableTaskSetting + { }; + static inline SysAllocator<VTableNetTaskSetting> s_VTable; - struct RawUlTaskSetting_t : NetTaskSetting_t - { - static const uint32 kType = 0x12340000; - uint32be ukRaw1; // 0x1004 - uint32be ukRaw2; // 0x1008 - uint32be ukRaw3; // 0x100C - uint8 rawSpace[0x200]; // 0x1010 - }; - static_assert(sizeof(RawUlTaskSetting_t) == 0x1210); - - struct PlayReportSetting_t : RawUlTaskSetting_t - { - static const uint32 kType = 0x12340001; - MEMPTR<void*> ukPlay1; // 0x1210 - uint32be ukPlay2; // 0x1214 - uint32be ukPlay3; // 0x1218 - uint32be ukPlay4; // 0x121C - }; - static_assert(sizeof(PlayReportSetting_t) == 0x1220); - - struct RawDlTaskSetting_t : NetTaskSetting_t - { - static const uint32 kType = 0x12340002; - //char fileName[0x20]; // 0x7F8 - }; - static_assert(sizeof(RawDlTaskSetting_t) == 0x1004); - - struct TitleId_t - { - uint64be u64{}; - }; - static_assert(sizeof(TitleId_t) == 8); - - struct TaskId_t - { - char id[0x8]{}; - }; - static_assert(sizeof(TaskId_t) == 8); - - struct Title_t - { - uint32be accountId{}; // 0x00 - TitleId_t titleId{}; // 0x8 - uint32be someValue = 0x12341000; // 0x10 - }; - static_assert(sizeof(Title_t) == 0x18); - - struct DirectoryName_t - { - char name[0x8]{}; - }; - static_assert(sizeof(DirectoryName_t) == 8); - - struct Account_t - { - uint32be accountId; - uint32be uk1; // global struct - }; - static_assert(sizeof(Account_t) == 8); - - struct Task_t - { - uint32be accountId; // 0x00 - uint32be uk2; // 0x04 - TaskId_t taskId; // 0x08 - TitleId_t titleId; // 0x10 - uint32be ext; // 0x18 - uint32be padding; // 0x1C - }; - static_assert(sizeof(Task_t) == 0x20, "sizeof(Task_t)"); - - namespace TaskId - { - TaskId_t* ctor(TaskId_t* thisptr) - { - if(!thisptr) - { - // thisptr = new TaskId_t - assert_dbg(); - } - - if(thisptr) - { - thisptr->id[0] = 0; - } - - return thisptr; - } - } - - namespace Account - { - Account_t* ctor(Account_t* thisptr, uint32 accountId) - { - if (!thisptr) - { - // thisptr = new TaskId_t - assert_dbg(); - } - - thisptr->accountId = accountId; - thisptr->uk1 = 0x12340010; - return thisptr; - } - } - - namespace TitleId - { - TitleId_t* ctor(TitleId_t* thisptr, uint64 titleId) - { - if (!thisptr) - { - // thisptr = new TaskId_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->u64 = titleId; - } - - return thisptr; - } - - TitleId_t* ctor(TitleId_t* thisptr) - { - return ctor(thisptr, 0); - } - - bool IsValid(TitleId_t* thisptr) - { - return thisptr->u64 != 0; - } - - TitleId_t* ctor1(TitleId_t* thisptr, uint32 filler, uint64 titleId) - { - return ctor(thisptr); - } - - TitleId_t* ctor2(TitleId_t* thisptr, uint32 filler, uint64 titleId) - { - cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_ctor2(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - thisptr->u64 = titleId; - return thisptr; - } - - - TitleId_t* cctor(TitleId_t* thisptr, TitleId_t* titleId) - { - cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_cctor(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - thisptr->u64 = titleId->u64; - - return thisptr; - } - - bool operator_ne(TitleId_t* thisptr, TitleId_t* titleId) - { - cemuLog_logDebug(LogType::Force, "nn_boss_TitleId_operator_ne(0x{:x})", MEMPTR(thisptr).GetMPTR()); - return thisptr->u64 != titleId->u64; - } - } - - namespace TaskSetting - { - bool IsPrivilegedTaskSetting(TaskSetting_t* thisptr) - { - const uint16 value = *(uint16*)&thisptr->settings[0x28]; - return value == 1 || value == 9 || value == 5; - } - - void InitializeSetting(TaskSetting_t* thisptr) - { - memset(thisptr, 0x00, sizeof(TaskSetting_t::settings)); - *(uint32*)&thisptr->settings[0x0C] = 0; - *(uint8*)&thisptr->settings[0x2A] = 0x7D; // timeout? - *(uint32*)&thisptr->settings[0x30] = 0x7080; - *(uint32*)&thisptr->settings[0x8] = 0; - *(uint32*)&thisptr->settings[0x38] = 0; - *(uint32*)&thisptr->settings[0x3C] = 0x76A700; - *(uint32*)&thisptr->settings[0] = 0x76A700; - } - - TaskSetting_t* ctor(TaskSetting_t* thisptr) - { - if(!thisptr) - { - // thisptr = new TaskSetting_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->uknExt_vTableProbably = 0; - InitializeSetting(thisptr); - } - - return thisptr; - } - - - } - - namespace NetTaskSetting - { - Result AddCaCert(NetTaskSetting_t* thisptr, const char* name) + static Result AddCaCert(NetTaskSetting* _thisptr, const char* name) { if(name == nullptr || strnlen(name, 0x80) == 0x80) { @@ -308,1505 +367,1380 @@ bossBufferVector->buffer = (uint8*)bossRequest; return 0xA0220D00; } - NetTaskSetting_t* ctor(NetTaskSetting_t* thisptr) + static NetTaskSetting* ctor(NetTaskSetting* _thisptr) { - if (!thisptr) - { - // thisptr = new NetTaskSetting_t - assert_dbg(); - } - - if (thisptr) - { - TaskSetting::ctor(thisptr); - *(uint32*)&thisptr->settings[0x18C] = 0x78; - thisptr->uknExt_vTableProbably = 0; - } - - return thisptr; + if (!_thisptr) + _thisptr = boss_new<NetTaskSetting>(); + TaskSetting::ctor(_thisptr); + *(uint32*)&_thisptr->settings[0x18C] = 0x78; + _thisptr->vTablePtr = s_VTable; + return _thisptr; } - Result SetServiceToken(NetTaskSetting_t* thisptr, const uint8* serviceToken) + static Result SetServiceToken(NetTaskSetting* _thisptr, const uint8* serviceToken) { - cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_SetServiceToken(0x{:x}, 0x{:x})", MEMPTR(thisptr).GetMPTR(), MEMPTR(serviceToken).GetMPTR()); + cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_SetServiceToken(0x{:x}, 0x{:x})", MEMPTR(_thisptr).GetMPTR(), MEMPTR(serviceToken).GetMPTR()); cemuLog_logDebug(LogType::Force, "\t->{}", fmt::ptr(serviceToken)); - memcpy(&thisptr->settings[TaskSetting_t::kServiceToken], serviceToken, TaskSetting_t::kServiceTokenLen); + memcpy(&_thisptr->settings[TaskSetting::kServiceToken], serviceToken, TaskSetting::kServiceTokenLen); return 0x200080; } - Result AddInternalCaCert(NetTaskSetting_t* thisptr, char certId) + static Result AddInternalCaCert(NetTaskSetting* _thisptr, char certId) { - cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_AddInternalCaCert(0x{:x}, 0x{:x})", MEMPTR(thisptr).GetMPTR(), (int)certId); + cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_AddInternalCaCert(0x{:x}, 0x{:x})", MEMPTR(_thisptr).GetMPTR(), (int)certId); - uint32 location = TaskSetting_t::kCACert; + uint32 location = TaskSetting::kCACert; for(int i = 0; i < 3; ++i) { - if(thisptr->settings[location] == 0) + if(_thisptr->settings[location] == 0) { - thisptr->settings[location] = (uint8)certId; + _thisptr->settings[location] = (uint8)certId; return 0x200080; } - location += TaskSetting_t::kCACert; + location += TaskSetting::kCACert; } - + cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_AddInternalCaCert: can't store certificate"); return 0xA0220D00; } - void SetInternalClientCert(NetTaskSetting_t* thisptr, char certId) + static void SetInternalClientCert(NetTaskSetting* _thisptr, char certId) { - cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_SetInternalClientCert(0x{:x}, 0x{:x})", MEMPTR(thisptr).GetMPTR(), (int)certId); - thisptr->settings[TaskSetting_t::kClientCert] = (uint8)certId; + cemuLog_logDebug(LogType::Force, "nn_boss_NetTaskSetting_SetInternalClientCert(0x{:x}, 0x{:x})", MEMPTR(_thisptr).GetMPTR(), (int)certId); + _thisptr->settings[TaskSetting::kClientCert] = (uint8)certId; } - } - namespace NbdlTaskSetting // : NetTaskSetting + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(NetTaskSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + } + }; + static_assert(sizeof(NetTaskSetting) == 0x1004); + + struct NbdlTaskSetting : NetTaskSetting { - NbdlTaskSetting_t* ctor(NbdlTaskSetting_t* thisptr) + struct VTableNbdlTaskSetting : public VTableNetTaskSetting { - if (!thisptr) - { - // thisptr = new NbdlTaskSetting_t - assert_dbg(); - } + VTableEntry rttiNetTaskSetting; // unknown + }; + static_assert(sizeof(VTableNbdlTaskSetting) == 8*5); + static inline SysAllocator<VTableNbdlTaskSetting> s_VTable; - if (thisptr) - { - NetTaskSetting::ctor(thisptr); - thisptr->uknExt_vTableProbably = 0; - } - - return thisptr; + static NbdlTaskSetting* ctor(NbdlTaskSetting* _thisptr) + { + if (!_thisptr) + _thisptr = boss_new<NbdlTaskSetting>(); + NetTaskSetting::ctor(_thisptr); + _thisptr->vTablePtr = s_VTable; + return _thisptr; } - void export_ctor(PPCInterpreter_t* hCPU) + static Result Initialize(NbdlTaskSetting* _thisptr, const char* bossCode, uint64 directorySizeLimit, const char* directoryName) // Initialize__Q3_2nn4boss15NbdlTaskSettingFPCcLT1 { - ppcDefineParamMEMPTR(thisptr, NbdlTaskSetting_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss_NbdlTaskSetting_ctor"); - ctor(thisptr.GetPtr()); - osLib_returnFromFunction(hCPU, thisptr.GetMPTR()); - } - - void export_Initialize(PPCInterpreter_t* hCPU) - { - ppcDefineParamMEMPTR(thisptr, NbdlTaskSetting_t, 0); - ppcDefineParamMEMPTR(bossCode, const char, 1); - ppcDefineParamU64(directorySizeLimit, 2); - ppcDefineParamMEMPTR(directoryName, const char, 4); - cemuLog_logDebug(LogType::Force, "nn_boss_NbdlTaskSetting_Initialize(0x{:08x}, {}, 0x{:x}, 0x{:08x})", thisptr.GetMPTR(), bossCode.GetPtr(), directorySizeLimit, directoryName.GetMPTR()); - - if(!bossCode || strnlen(bossCode.GetPtr(), 0x20) == 0x20) - { - osLib_returnFromFunction(hCPU, BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780)); - return; - } - - if (directoryName && strnlen(directoryName.GetPtr(), 0x8) == 0x8) - { - osLib_returnFromFunction(hCPU, BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780)); - return; - } - - strncpy((char*)&thisptr->settings[TaskSetting_t::kBossCode], bossCode.GetPtr(), TaskSetting_t::kBossCodeLen); - - *(uint64be*)&thisptr->settings[TaskSetting_t::kDirectorySizeLimit] = directorySizeLimit; // uint64be - if(directoryName) - strncpy((char*)&thisptr->settings[TaskSetting_t::kDirectoryName], directoryName.GetPtr(), TaskSetting_t::kDirectoryNameLen); - - osLib_returnFromFunction(hCPU, BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_BOSS, 0x80)); - } - - Result SetFileName(NbdlTaskSetting_t* thisptr, const char* fileName) - { - cemuLog_logDebug(LogType::Force, "nn_boss_NbdlTaskSetting_t_SetFileName(0x{:08x}, {})", MEMPTR(thisptr).GetMPTR(), fileName ? fileName : "\"\""); - - if (!fileName || strnlen(fileName, TaskSetting_t::kFileNameLen) == TaskSetting_t::kFileNameLen) - { + if(!bossCode || strnlen(bossCode, TaskSetting::kBossCodeLen) == TaskSetting::kBossCodeLen) return BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780); - } - - strncpy((char*)&thisptr->settings[TaskSetting_t::kNbdlFileName], fileName, TaskSetting_t::kFileNameLen); + + if (directoryName && strnlen(directoryName, TaskSetting::kDirectoryNameLen) == TaskSetting::kDirectoryNameLen) + return BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780); + + strncpy((char*)&_thisptr->settings[TaskSetting::kBossCode], bossCode, TaskSetting::kBossCodeLen); + + *(uint64be*)&_thisptr->settings[TaskSetting::kDirectorySizeLimit] = directorySizeLimit; // uint64be + if(directoryName) + strncpy((char*)&_thisptr->settings[TaskSetting::kDirectoryName], directoryName, TaskSetting::kDirectoryNameLen); + return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_BOSS, 0x80); } - } - - namespace RawUlTaskSetting - { - RawUlTaskSetting_t* ctor(RawUlTaskSetting_t* thisptr) + static Result SetFileName(NbdlTaskSetting* _thisptr, const char* fileName) { - cemuLog_logDebug(LogType::Force, "nn_boss_RawUlTaskSetting_ctor(0x{:x}) TODO", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new RawUlTaskSetting_t - assert_dbg(); - } + cemuLog_logDebug(LogType::Force, "nn_boss_NbdlTaskSetting_t_SetFileName(0x{:08x}, {})", MEMPTR(_thisptr).GetMPTR(), fileName ? fileName : "\"\""); + if (!fileName || strnlen(fileName, TaskSetting::kFileNameLen) == TaskSetting::kFileNameLen) + return BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780); - if (thisptr) - { - NetTaskSetting::ctor(thisptr); - thisptr->uknExt_vTableProbably = RawUlTaskSetting_t::kType; - thisptr->ukRaw1 = 0; - thisptr->ukRaw2 = 0; - thisptr->ukRaw3 = 0; - memset(thisptr->rawSpace, 0x00, 0x200); - } - - return thisptr; - } - } - - namespace RawDlTaskSetting - { - RawDlTaskSetting_t* ctor(RawDlTaskSetting_t* thisptr) - { - cemuLog_logDebug(LogType::Force, "nn_boss_RawDlTaskSetting_ctor(0x{:x}) TODO", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new RawDlTaskSetting_t - assert_dbg(); - } - - if (thisptr) - { - NetTaskSetting::ctor(thisptr); - thisptr->uknExt_vTableProbably = RawDlTaskSetting_t::kType; - } - - return thisptr; + strncpy((char*)&_thisptr->settings[TaskSetting::kNbdlFileName], fileName, TaskSetting::kFileNameLen); + // also sets byte at +0x817 to zero? + return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_BOSS, 0x80); } - Result Initialize(RawDlTaskSetting_t* thisptr, const char* url, bool newArrival, bool led, const char* fileName, const char* directoryName) + static void InitVTable() { - cemuLog_logDebug(LogType::Force, "nn_boss_RawDlTaskSetting_Initialize(0x{:x}, 0x{:x}, {}, {}, 0x{:x}, 0x{:x})", MEMPTR(thisptr).GetMPTR(), MEMPTR(url).GetMPTR(), newArrival, led, MEMPTR(fileName).GetMPTR(), MEMPTR(directoryName).GetMPTR()); + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(NbdlTaskSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + s_VTable->rttiNetTaskSetting.ptr = nullptr; // todo + } + }; + static_assert(sizeof(NbdlTaskSetting) == 0x1004); + + struct RawUlTaskSetting : NetTaskSetting + { + uint32be ukRaw1; // 0x1004 + uint32be ukRaw2; // 0x1008 + uint32be ukRaw3; // 0x100C + uint8 rawSpace[0x200]; // 0x1010 + + struct VTableRawUlTaskSetting : public VTableNetTaskSetting + { + VTableEntry rttiNetTaskSetting; // unknown + }; + static_assert(sizeof(VTableRawUlTaskSetting) == 8*5); + static inline SysAllocator<VTableRawUlTaskSetting> s_VTable; + + static RawUlTaskSetting* ctor(RawUlTaskSetting* _thisptr) + { + if (!_thisptr) + _thisptr = boss_new<RawUlTaskSetting>(); + NetTaskSetting::ctor(_thisptr); + _thisptr->vTablePtr = s_VTable; + _thisptr->ukRaw1 = 0; + _thisptr->ukRaw2 = 0; + _thisptr->ukRaw3 = 0; + memset(_thisptr->rawSpace, 0x00, 0x200); + return _thisptr; + } + + static void dtor(RawUlTaskSetting* _this, uint32 options) + { + cemuLog_logDebug(LogType::Force, "nn::boss::RawUlTaskSetting::dtor() is todo"); + } + + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(RawUlTaskSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + s_VTable->rttiNetTaskSetting.ptr = nullptr; // todo + } + }; + static_assert(sizeof(RawUlTaskSetting) == 0x1210); + + struct RawDlTaskSetting : NetTaskSetting + { + struct VTableRawDlTaskSetting : public VTableNetTaskSetting + { + VTableEntry rttiNetTaskSetting; // unknown + }; + static_assert(sizeof(VTableRawDlTaskSetting) == 8*5); + static inline SysAllocator<VTableRawDlTaskSetting> s_VTable; + + static RawDlTaskSetting* ctor(RawDlTaskSetting* _thisptr) + { + cemuLog_logDebug(LogType::Force, "nn_boss_RawDlTaskSetting_ctor(0x{:x}) TODO", MEMPTR(_thisptr).GetMPTR()); + if (!_thisptr) + _thisptr = boss_new<RawDlTaskSetting>(); + NetTaskSetting::ctor(_thisptr); + _thisptr->vTablePtr = s_VTable; + return _thisptr; + } + + static Result Initialize(RawDlTaskSetting* _thisptr, const char* url, bool newArrival, bool led, const char* fileName, const char* directoryName) + { + cemuLog_logDebug(LogType::Force, "nn_boss_RawDlTaskSetting_Initialize(0x{:x}, 0x{:x}, {}, {}, 0x{:x}, 0x{:x})", MEMPTR(_thisptr).GetMPTR(), MEMPTR(url).GetMPTR(), newArrival, led, MEMPTR(fileName).GetMPTR(), MEMPTR(directoryName).GetMPTR()); if (!url) { return 0xC0203780; } - if (strnlen(url, TaskSetting_t::kURLLen) == TaskSetting_t::kURLLen) + if (strnlen(url, TaskSetting::kURLLen) == TaskSetting::kURLLen) { return 0xC0203780; } cemuLog_logDebug(LogType::Force, "\t-> url: {}", url); - if (fileName && strnlen(fileName, TaskSetting_t::kFileNameLen) == TaskSetting_t::kFileNameLen) + if (fileName && strnlen(fileName, TaskSetting::kFileNameLen) == TaskSetting::kFileNameLen) { return 0xC0203780; } - if (directoryName && strnlen(directoryName, TaskSetting_t::kDirectoryNameLen) == TaskSetting_t::kDirectoryNameLen) + if (directoryName && strnlen(directoryName, TaskSetting::kDirectoryNameLen) == TaskSetting::kDirectoryNameLen) { return 0xC0203780; } - strncpy((char*)thisptr + TaskSetting_t::kURL, url, TaskSetting_t::kURLLen); - thisptr->settings[0x147] = '\0'; + strncpy((char*)_thisptr + TaskSetting::kURL, url, TaskSetting::kURLLen); + _thisptr->settings[0x147] = '\0'; if (fileName) - strncpy((char*)thisptr + 0x7D0, fileName, TaskSetting_t::kFileNameLen); + strncpy((char*)_thisptr + 0x7D0, fileName, TaskSetting::kFileNameLen); else - strncpy((char*)thisptr + 0x7D0, "rawcontent.dat", TaskSetting_t::kFileNameLen); - thisptr->settings[0x7EF] = '\0'; + strncpy((char*)_thisptr + 0x7D0, "rawcontent.dat", TaskSetting::kFileNameLen); + _thisptr->settings[0x7EF] = '\0'; - cemuLog_logDebug(LogType::Force, "\t-> filename: {}", (char*)thisptr + 0x7D0); + cemuLog_logDebug(LogType::Force, "\t-> filename: {}", (char*)_thisptr + 0x7D0); if (directoryName) { - strncpy((char*)thisptr + 0x7C8, directoryName, TaskSetting_t::kDirectoryNameLen); - thisptr->settings[0x7CF] = '\0'; - cemuLog_logDebug(LogType::Force, "\t-> directoryName: {}", (char*)thisptr + 0x7C8); + strncpy((char*)_thisptr + 0x7C8, directoryName, TaskSetting::kDirectoryNameLen); + _thisptr->settings[0x7CF] = '\0'; + cemuLog_logDebug(LogType::Force, "\t-> directoryName: {}", (char*)_thisptr + 0x7C8); } - thisptr->settings[0x7C0] = newArrival; - thisptr->settings[0x7C1] = led; - *(uint16be*)&thisptr->settings[0x28] = 0x3; + _thisptr->settings[0x7C0] = newArrival; + _thisptr->settings[0x7C1] = led; + *(uint16be*)&_thisptr->settings[0x28] = 0x3; return 0x200080; } - } - namespace PlayReportSetting // : NetTaskSetting - { - void export_ctor(PPCInterpreter_t* hCPU) + static void InitVTable() { - ppcDefineParamMEMPTR(thisptr, PlayReportSetting_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss_PlayReportSetting_ctor TODO"); - if (!thisptr) - { - assert_dbg(); - } + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(RawDlTaskSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + s_VTable->rttiNetTaskSetting.ptr = nullptr; // todo + } + }; + static_assert(sizeof(RawDlTaskSetting) == 0x1004); - if (thisptr) - { - RawUlTaskSetting::ctor(thisptr.GetPtr()); - thisptr->uknExt_vTableProbably = PlayReportSetting_t::kType; - thisptr->ukPlay1 = nullptr; - thisptr->ukPlay2 = 0; - thisptr->ukPlay3 = 0; - thisptr->ukPlay4 = 0; - } + struct PlayReportSetting : RawUlTaskSetting + { + MEMPTR<uint8> ukn1210_ptr; // 0x1210 + uint32be ukn1214_size; // 0x1214 + uint32be ukPlay3; // 0x1218 + uint32be ukPlay4; // 0x121C - osLib_returnFromFunction(hCPU, thisptr.GetMPTR()); + struct VTablePlayReportSetting : public VTableRawUlTaskSetting + {}; + static_assert(sizeof(VTablePlayReportSetting) == 8*5); + static inline SysAllocator<VTablePlayReportSetting> s_VTable; + + static PlayReportSetting* ctor(PlayReportSetting* _this) + { + if(!_this) + _this = boss_new<PlayReportSetting>(); + RawUlTaskSetting::ctor(_this); + _this->vTablePtr = s_VTable; + _this->ukn1210_ptr = nullptr; + _this->ukn1214_size = 0; + _this->ukPlay3 = 0; + _this->ukPlay4 = 0; + return _this; } - void export_Initialize(PPCInterpreter_t* hCPU) + static void dtor(PlayReportSetting* _this, uint32 options) { - ppcDefineParamMEMPTR(thisptr, PlayReportSetting_t, 0); - ppcDefineParamMEMPTR(ptr, void*, 1); - ppcDefineParamU32(value, 2); - ppcDefineParamMEMPTR(directoryName, const char, 4); - //cemuLog_logDebug(LogType::Force, "nn_boss_PlayReportSetting_Initialize(0x{:08x}, {}, 0x{:x}, 0x{:08x})", thisptr.GetMPTR(), ptr.GetPtr(), directorySizeLimit, directoryName.GetMPTR()); + RawUlTaskSetting::dtor(_this, 0); + if(options&1) + boss_delete(_this->ukn1210_ptr.GetPtr()); + } - if(!ptr || value == 0 || value > 0x19000) + static void Initialize(PlayReportSetting* _this, uint8* ptr, uint32 size) + { + if(!ptr || size == 0 || size > 0x19000) { - cemuLog_logDebug(LogType::Force, "nn_boss_PlayReportSetting_Initialize: invalid parameter"); - osLib_returnFromFunction(hCPU, 0); + cemuLog_logDebug(LogType::Force, "nn::boss::PlayReportSetting::Initialize: invalid parameter"); + return; } - *ptr.GetPtr<uint8>() = 0; + *ptr = 0; - *(uint16be*)&thisptr->settings[0x28] = 6; - *(uint16be*)&thisptr->settings[0x2B] |= 0x3; - *(uint16be*)&thisptr->settings[0x2C] |= 0xA; - *(uint32be*)&thisptr->settings[0x7C0] |= 2; - - thisptr->ukPlay1 = ptr; - thisptr->ukPlay2 = value; - thisptr->ukPlay3 = 0; - thisptr->ukPlay4 = 0; + *(uint16be*)&_this->settings[0x28] = 6; + *(uint16be*)&_this->settings[0x2B] |= 0x3; + *(uint16be*)&_this->settings[0x2C] |= 0xA; + *(uint32be*)&_this->settings[0x7C0] |= 2; + + _this->ukn1210_ptr = ptr; + _this->ukn1214_size = size; + _this->ukPlay3 = 0; + _this->ukPlay4 = 0; // TODO - osLib_returnFromFunction(hCPU, 0); } - void export_Set(PPCInterpreter_t* hCPU) + static bool Set(PlayReportSetting* _this, const char* keyname, uint32 value) { - ppcDefineParamMEMPTR(thisptr, PlayReportSetting_t, 0); - ppcDefineParamMEMPTR(key, const char, 1); - ppcDefineParamU32(value, 2); - // TODO - cemuLog_logDebug(LogType::Force, "nn_boss_PlayReportSetting_Set(0x{:08x}, {}, 0x{:x}) TODO", thisptr.GetMPTR(), key.GetPtr(), value); - - osLib_returnFromFunction(hCPU, 1); + return true; } - - } - - namespace Title - { - Title_t* ctor(Title_t* thisptr) + static void InitVTable() { - cemuLog_logDebug(LogType::Force, "nn_boss_Title_ctor(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - *thisptr = {}; - - return thisptr; + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(PlayReportSetting); + s_VTable->RegisterPreprocess.ptr = nullptr; // todo + s_VTable->unk1.ptr = nullptr; // todo + s_VTable->rttiNetTaskSetting.ptr = nullptr; // todo } - } + }; + static_assert(sizeof(PlayReportSetting) == 0x1220); - namespace DirectoryName + struct Task { - DirectoryName_t* ctor(DirectoryName_t* thisptr) + struct VTableTask { - cemuLog_logDebug(LogType::Force, "nn_boss_DirectoryName_ctor(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } + VTableEntry rtti; + VTableEntry dtor; + }; + static inline SysAllocator<VTableTask> s_vTable; - memset(thisptr->name, 0x00, 0x8); + uint32be accountId; // 0x00 + uint32be uk2; // 0x04 + TaskId taskId; // 0x08 + TitleId titleId; // 0x10 + MEMPTR<VTableTask> vTablePtr; // 0x18 + uint32be padding; // 0x1C - return thisptr; - } - - const char* operator_const_char(DirectoryName_t* thisptr) - { - cemuLog_logDebug(LogType::Force, "nn_boss_DirectoryName_operator_const_char(0x{:x})", MEMPTR(thisptr).GetMPTR()); - return thisptr->name; - } - } - - namespace Task - { - - Result Initialize(Task_t* thisptr, const char* taskId, uint32 accountId) + static Result Initialize1(Task* _thisptr, const char* taskId, uint32 accountId) // Initialize__Q3_2nn4boss4TaskFPCcUi { if(!taskId || strnlen(taskId, 0x8) == 8) { return BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780); } - - thisptr->accountId = accountId; - strncpy(thisptr->taskId.id, taskId, 0x08); + _thisptr->accountId = accountId; + strncpy(_thisptr->taskId.id, taskId, 0x08); return BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_BOSS, 0x80); } - Result Initialize(Task_t* thisptr, uint8 slot, const char* taskId) + static Result Initialize2(Task* _thisptr, uint8 slot, const char* taskId) // Initialize__Q3_2nn4boss4TaskFUcPCc { const uint32 accountId = slot == 0 ? 0 : act::GetPersistentIdEx(slot); - return Initialize(thisptr, taskId, accountId); + return Initialize1(_thisptr, taskId, accountId); } - Result Initialize(Task_t* thisptr, const char* taskId) + static Result Initialize3(Task* _thisptr, const char* taskId) // Initialize__Q3_2nn4boss4TaskFPCc { - return Initialize(thisptr, taskId, 0); + return Initialize1(_thisptr, taskId, 0); } - void export_Initialize3(PPCInterpreter_t* hCPU) + static Task* ctor2(Task* _thisptr, const char* taskId, uint32 accountId) // __ct__Q3_2nn4boss4TaskFPCcUi { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(taskId, const char, 1); - ppcDefineParamU32(accountId, 2); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Initialize3(0x{:08x}, {}, 0x{:x})", thisptr.GetMPTR(), taskId.GetPtr(), accountId); - const Result result = Initialize(thisptr.GetPtr(), taskId.GetPtr(), accountId); - osLib_returnFromFunction(hCPU, result); + if (!_thisptr) + _thisptr = boss_new<Task>(); + _thisptr->accountId = 0; + _thisptr->vTablePtr = s_vTable; + TaskId::ctor(&_thisptr->taskId); + TitleId::ctor(&_thisptr->titleId, 0); + auto r = Initialize1(_thisptr, taskId, accountId); + cemu_assert_debug(NN_RESULT_IS_SUCCESS(r)); + return _thisptr; } - void export_Initialize2(PPCInterpreter_t* hCPU) + static Task* ctor1(Task* _thisptr, uint8 slot, const char* taskId) // __ct__Q3_2nn4boss4TaskFUcPCc { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamU8(slotId, 1); - ppcDefineParamMEMPTR(taskId, const char, 2); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Initialize2(0x{:08x}, {}, {})", thisptr.GetMPTR(), slotId, taskId.GetPtr()); - const Result result = Initialize(thisptr.GetPtr(), slotId, taskId.GetPtr()); - osLib_returnFromFunction(hCPU, result); - } - - void export_Initialize1(PPCInterpreter_t* hCPU) - { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(taskId, const char, 1); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Initialize1(0x{:08x}, {})", thisptr.GetMPTR(), taskId.GetPtr()); - const Result result = Initialize(thisptr.GetPtr(), taskId.GetPtr()); - osLib_returnFromFunction(hCPU, result); + if (!_thisptr) + _thisptr = boss_new<Task>(); + _thisptr->accountId = 0; + _thisptr->vTablePtr = s_vTable; + TaskId::ctor(&_thisptr->taskId); + TitleId::ctor(&_thisptr->titleId, 0); + auto r = Initialize2(_thisptr, slot, taskId); + cemu_assert_debug(NN_RESULT_IS_SUCCESS(r)); + return _thisptr; } - - Task_t* ctor(Task_t* thisptr, const char* taskId, uint32 accountId) + static Task* ctor3(Task* _thisptr, const char* taskId) // __ct__Q3_2nn4boss4TaskFPCc { - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->accountId = 0; - thisptr->ext = 0; // dword_10002174 - TaskId::ctor(&thisptr->taskId); - TitleId::ctor(&thisptr->titleId, 0); - cemu_assert_debug(NN_RESULT_IS_SUCCESS(Initialize(thisptr, taskId, accountId))); - } - - return thisptr; + if (!_thisptr) + _thisptr = boss_new<Task>(); + _thisptr->accountId = 0; + _thisptr->vTablePtr = s_vTable; + TaskId::ctor(&_thisptr->taskId); + TitleId::ctor(&_thisptr->titleId, 0); + auto r = Initialize3(_thisptr, taskId); + cemu_assert_debug(NN_RESULT_IS_SUCCESS(r)); + return _thisptr; } - Task_t* ctor(Task_t* thisptr, uint8 slot, const char* taskId) + static Task* ctor4(Task* _thisptr) // __ct__Q3_2nn4boss4TaskFv { - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->accountId = 0; - thisptr->ext = 0; // dword_10002174 - TaskId::ctor(&thisptr->taskId); - TitleId::ctor(&thisptr->titleId, 0); - cemu_assert_debug(NN_RESULT_IS_SUCCESS(Initialize(thisptr, slot, taskId))); - } - - return thisptr; + if (!_thisptr) + _thisptr = boss_new<Task>(); + _thisptr->accountId = 0; + _thisptr->vTablePtr = s_vTable; + TaskId::ctor(&_thisptr->taskId); + TitleId::ctor(&_thisptr->titleId, 0); + memset(&_thisptr->taskId, 0x00, sizeof(TaskId)); + return _thisptr; } - Task_t* ctor(Task_t* thisptr, const char* taskId) + static void dtor(Task* _this, uint32 options) // __dt__Q3_2nn4boss4TaskFv { - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->accountId = 0; - thisptr->ext = 0; // dword_10002174 - TaskId::ctor(&thisptr->taskId); - TitleId::ctor(&thisptr->titleId, 0); - cemu_assert_debug(NN_RESULT_IS_SUCCESS(Initialize(thisptr, taskId))); - } - - return thisptr; + cemuLog_logDebug(LogType::Force, "nn::boss::Task::dtor(0x{:08x}, 0x{:08x})", MEMPTR(_this).GetMPTR(), options); + // todo - Task::Finalize + if(options & 1) + boss_delete(_this); } - Task_t* ctor(Task_t* thisptr) + static Result Run(Task* _thisptr, bool isForegroundRun) { - if (!thisptr) - { - // thisptr = new Task_t - assert_dbg(); - } - - if (thisptr) - { - thisptr->accountId = 0; - thisptr->ext = 0; // dword_10002174 - TaskId::ctor(&thisptr->taskId); - TitleId::ctor(&thisptr->titleId, 0); - memset(&thisptr->taskId, 0x00, sizeof(TaskId_t)); - } - - return thisptr; - } - - void export_ctor(PPCInterpreter_t* hCPU) - { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_ctor(0x{:08x})", thisptr.GetMPTR()); - ctor(thisptr.GetPtr()); - osLib_returnFromFunction(hCPU, thisptr.GetMPTR()); - } - - void export_Run(PPCInterpreter_t* hCPU) - { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamU8(isForegroundRun, 1); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Run(0x{:08x}, {})", thisptr.GetMPTR(), isForegroundRun); if (isForegroundRun != 0) { - //peterBreak(); cemuLog_logDebug(LogType::Force, "export_Run foreground run"); } bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_RUN; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->titleId = _thisptr->titleId.u64; bossRequest->bool_parameter = isForegroundRun != 0; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, 0); + return 0; } - void export_StartScheduling(PPCInterpreter_t* hCPU) + static Result StartScheduling(Task* _thisptr, uint8 executeImmediately) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamU8(executeImmediately, 1); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_StartScheduling(0x{:08x}, {})", thisptr.GetMPTR(), executeImmediately); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_START_SCHEDULING; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->titleId = _thisptr->titleId.u64; bossRequest->bool_parameter = executeImmediately != 0; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, 0); + return 0; } - void export_StopScheduling(PPCInterpreter_t* hCPU) + static Result StopScheduling(Task* _thisptr) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_StopScheduling(0x{:08x})", thisptr.GetMPTR()); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_STOP_SCHEDULING; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->titleId = _thisptr->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, 0); + return 0; } - void export_IsRegistered(PPCInterpreter_t* hCPU) + static Result IsRegistered(Task* _thisptr) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_IS_REGISTERED; - bossRequest->accountId = thisptr->accountId; - bossRequest->titleId = thisptr->titleId.u64; - bossRequest->taskId = thisptr->taskId.id; + bossRequest->accountId = _thisptr->accountId; + bossRequest->titleId = _thisptr->titleId.u64; + bossRequest->taskId = _thisptr->taskId.id; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_IsRegistered(0x{:08x}) -> {}", thisptr.GetMPTR(), bossRequest->returnCode); - - osLib_returnFromFunction(hCPU, bossRequest->returnCode); + return bossRequest->returnCode; } - void export_Wait(PPCInterpreter_t* hCPU) + static Result Wait(Task* _thisptr, uint32 timeout, uint32 waitState) // Wait__Q3_2nn4boss4TaskFUiQ3_2nn4boss13TaskWaitState { - // Wait__Q3_2nn4boss4TaskFUiQ3_2nn4boss13TaskWaitState - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamU32(timeout, 1); - ppcDefineParamU32(waitState, 2); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Wait(0x{:08x}, 0x{:x}, {})", thisptr.GetMPTR(), timeout, waitState); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_WAIT; - bossRequest->titleId = thisptr->titleId.u64; - bossRequest->taskId = thisptr->taskId.id; + bossRequest->titleId = _thisptr->titleId.u64; + bossRequest->taskId = _thisptr->taskId.id; bossRequest->timeout = timeout; bossRequest->waitState = waitState; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, bossRequest->returnCode); - - //osLib_returnFromFunction(hCPU, 1); // 0 -> timeout, 1 -> wait condition met + return bossRequest->returnCode; } - void export_RegisterForImmediateRun(PPCInterpreter_t* hCPU) + static Result RegisterForImmediateRun(Task* _thisptr, TaskSetting* settings) // RegisterForImmediateRun__Q3_2nn4boss4TaskFRCQ3_2nn4boss11TaskSetting { - // RegisterForImmediateRun__Q3_2nn4boss4TaskFRCQ3_2nn4boss11TaskSetting - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(settings, TaskSetting_t, 1); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_RegisterForImmediateRun(0x{:08x}, 0x{:08x})", thisptr.GetMPTR(), settings.GetMPTR()); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_REGISTER; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->settings = settings.GetPtr(); + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->settings = settings; bossRequest->uk1 = 0xC00; - if (TaskSetting::IsPrivilegedTaskSetting(settings.GetPtr())) - bossRequest->titleId = thisptr->titleId.u64; + if (TaskSetting::IsPrivileged(settings)) + bossRequest->titleId = _thisptr->titleId.u64; - const sint32 result = __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, result); + Result result = __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); + return result; } - void export_Unregister(PPCInterpreter_t* hCPU) + static Result Unregister(Task* _thisptr) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Unregister(0x{:08x})", thisptr.GetMPTR()); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_UNREGISTER; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->titleId = _thisptr->titleId.u64; const sint32 result = __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, result); + return result; } - void export_Register(PPCInterpreter_t* hCPU) + static Result Register(Task* _thisptr, TaskSetting* settings) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(settings, TaskSetting_t, 1); - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Register(0x{:08x}, 0x{:08x})", thisptr.GetMPTR(), settings.GetMPTR()); - - if (hCPU->gpr[4] == 0) + if (!settings) { - cemuLog_logDebug(LogType::Force, "nn_boss_Task_Register - crash workaround (fix me)"); - osLib_returnFromFunction(hCPU, 0); - return; + cemuLog_logDebug(LogType::Force, "nn_boss_Task_Register - crash workaround (fix me)"); // settings should never be zero + return 0; } bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_REGISTER_FOR_IMMEDIATE_RUN; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->settings = settings.GetPtr(); + bossRequest->accountId = _thisptr->accountId; + bossRequest->taskId = _thisptr->taskId.id; + bossRequest->settings = settings; bossRequest->uk1 = 0xC00; - if(TaskSetting::IsPrivilegedTaskSetting(settings.GetPtr())) - bossRequest->titleId = thisptr->titleId.u64; + if(TaskSetting::IsPrivileged(settings)) + bossRequest->titleId = _thisptr->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - osLib_returnFromFunction(hCPU, bossRequest->returnCode); + return bossRequest->returnCode; } - - - void export_GetTurnState(PPCInterpreter_t* hCPU) + + static uint32 GetTurnState(Task* _this, uint32be* executionCountOut) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(execCount, uint32be, 1); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_GET_TURN_STATE; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _this->accountId; + bossRequest->taskId = _this->taskId.id; + bossRequest->titleId = _this->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - if (execCount) - *execCount = bossRequest->u32.exec_count; + if (executionCountOut) + *executionCountOut = bossRequest->u32.exec_count; - cemuLog_logDebug(LogType::Force, "nn_boss_Task_GetTurnState(0x{:08x}, 0x{:08x}) -> {}", thisptr.GetMPTR(), execCount.GetMPTR(), bossRequest->u32.result); - - osLib_returnFromFunction(hCPU, bossRequest->u32.result); - //osLib_returnFromFunction(hCPU, 7); // 7 -> finished? 0x11 -> Error (Splatoon doesn't like it when we return 0x11 for Nbdl tasks) RETURN FINISHED + return bossRequest->u32.result; + // 7 -> finished? 0x11 -> Error (Splatoon doesn't like it when we return 0x11 for Nbdl tasks) } - void export_GetContentLength(PPCInterpreter_t* hCPU) + static uint64 GetContentLength(Task* _this, uint32be* executionCountOut) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(execCount, uint32be, 1); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_GET_CONTENT_LENGTH; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _this->accountId; + bossRequest->taskId = _this->taskId.id; + bossRequest->titleId = _this->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - if (execCount) - *execCount = bossRequest->u64.exec_count; + if (executionCountOut) + *executionCountOut = bossRequest->u64.exec_count; - cemuLog_logDebug(LogType::Force, "nn_boss_Task_GetContentLength(0x{:08x}, 0x{:08x}) -> 0x{:x}", thisptr.GetMPTR(), execCount.GetMPTR(), bossRequest->u64.result); - - osLib_returnFromFunction64(hCPU, bossRequest->u64.result); + return bossRequest->u64.result; } - void export_GetProcessedLength(PPCInterpreter_t* hCPU) + static uint64 GetProcessedLength(Task* _this, uint32be* executionCountOut) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(execCount, uint32be, 1); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_GET_PROCESSED_LENGTH; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _this->accountId; + bossRequest->taskId = _this->taskId.id; + bossRequest->titleId = _this->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - if (execCount) - *execCount = bossRequest->u64.exec_count; - - cemuLog_logDebug(LogType::Force, "nn_boss_Task_GetProcessedLength(0x{:08x}, 0x{:08x}) -> 0x{:x}", thisptr.GetMPTR(), execCount.GetMPTR(), bossRequest->u64.result); - - osLib_returnFromFunction64(hCPU, bossRequest->u64.result); + if (executionCountOut) + *executionCountOut = bossRequest->u64.exec_count; + return bossRequest->u64.result; } - void export_GetHttpStatusCode(PPCInterpreter_t* hCPU) + static uint32 GetHttpStatusCode(Task* _this, uint32be* executionCountOut) { - ppcDefineParamMEMPTR(thisptr, Task_t, 0); - ppcDefineParamMEMPTR(execCount, uint32be, 1); - bossPrepareRequest(); bossRequest->requestCode = IOSU_NN_BOSS_TASK_GET_HTTP_STATUS_CODE; - bossRequest->accountId = thisptr->accountId; - bossRequest->taskId = thisptr->taskId.id; - bossRequest->titleId = thisptr->titleId.u64; + bossRequest->accountId = _this->accountId; + bossRequest->taskId = _this->taskId.id; + bossRequest->titleId = _this->titleId.u64; __depr__IOS_Ioctlv(IOS_DEVICE_BOSS, IOSU_BOSS_REQUEST_CEMU, 1, 1, bossBufferVector); - if (execCount) - *execCount = bossRequest->u32.exec_count; + if (executionCountOut) + *executionCountOut = bossRequest->u32.exec_count; - cemuLog_logDebug(LogType::Force, "nn_boss_Task_GetHttpStatusCode(0x{:08x}, 0x{:08x}) -> {}", thisptr.GetMPTR(), execCount.GetMPTR(), bossRequest->u32.result); - - osLib_returnFromFunction(hCPU, bossRequest->u32.result); + return bossRequest->u32.result; } - } - struct PrivilegedTask_t : Task_t - { - + static void InitVTable() + { + s_vTable->rtti.ptr = nullptr; // todo + s_vTable->dtor.ptr = RPLLoader_MakePPCCallable([](PPCInterpreter_t* hCPU) { Task::dtor(MEMPTR<Task>(hCPU->gpr[3]), hCPU->gpr[4]); osLib_returnFromFunction(hCPU, 0); }); + } }; - static_assert(sizeof(PrivilegedTask_t) == 0x20); - - struct AlmightyTask_t : PrivilegedTask_t + + static_assert(sizeof(Task) == 0x20); + + struct PrivilegedTask : Task { - + struct VTablePrivilegedTask : public VTableTask + { + VTableEntry rttiTask; + }; + static_assert(sizeof(VTablePrivilegedTask) == 8*3); + static inline SysAllocator<VTablePrivilegedTask> s_VTable; + + static PrivilegedTask* ctor(PrivilegedTask* _thisptr) + { + if (!_thisptr) + _thisptr = boss_new<PrivilegedTask>(); + Task::ctor4(_thisptr); + _thisptr->vTablePtr = s_VTable; + return _thisptr; + } + + static void dtor(PrivilegedTask* _this, uint32 options) + { + if(!_this) + return; + Task::dtor(_this, 0); + if(options & 1) + boss_delete(_this); + } + + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(PrivilegedTask); + s_VTable->rttiTask.ptr = nullptr; // todo + } }; - static_assert(sizeof(AlmightyTask_t) == 0x20); - - namespace PrivilegedTask - { - PrivilegedTask_t* ctor(PrivilegedTask_t*thisptr) - { - if (!thisptr) - assert_dbg(); // new - - Task::ctor(thisptr); - thisptr->ext = 0x10003a50; - return thisptr; - } - } + static_assert(sizeof(PrivilegedTask) == 0x20); - namespace AlmightyTask + struct AlmightyTask : PrivilegedTask { - AlmightyTask_t* ctor(AlmightyTask_t* thisptr) - { - if (!thisptr) - assert_dbg(); // new + struct VTableAlmightyTask : public VTablePrivilegedTask + {}; + static_assert(sizeof(VTableAlmightyTask) == 8*3); + static inline SysAllocator<VTableAlmightyTask> s_VTable; - PrivilegedTask::ctor(thisptr); - thisptr->ext = 0x10002a0c; - return thisptr; - } - void dtor(AlmightyTask_t* thisptr) + static AlmightyTask* ctor(AlmightyTask* _thisptr) { - if (thisptr) - freeMem(thisptr); + if (!_thisptr) + _thisptr = boss_new<AlmightyTask>(); + PrivilegedTask::ctor(_thisptr); + _thisptr->vTablePtr = s_VTable; + return _thisptr; } - - uint32 Initialize(AlmightyTask_t* thisptr, TitleId_t* titleId, const char* taskId, uint32 accountId) + + static void dtor(AlmightyTask* _thisptr, uint32 options) { - if (!thisptr) + if (!_thisptr) + return; + PrivilegedTask::dtor(_thisptr, 0); + if(options&1) + boss_delete(_thisptr); + } + + static uint32 Initialize(AlmightyTask* _thisptr, TitleId* titleId, const char* taskId, uint32 accountId) + { + if (!_thisptr) return 0xc0203780; - thisptr->accountId = accountId; - thisptr->titleId.u64 = titleId->u64; - strncpy(thisptr->taskId.id, taskId, 8); - thisptr->taskId.id[7] = 0x00; - + _thisptr->accountId = accountId; + _thisptr->titleId.u64 = titleId->u64; + strncpy(_thisptr->taskId.id, taskId, 8); + _thisptr->taskId.id[7] = 0x00; + return 0x200080; } - } - Result InitializeImpl() - { - // if( Initialize(IpcClientCafe*) ) ... - g_isInitialized = true; - return 0; - } - - void export_IsInitialized(PPCInterpreter_t* hCPU) - { - osLib_returnFromFunction(hCPU, (uint32)g_isInitialized); - } - - Result Initialize() - { - Result result; - coreinit::OSLockMutex(&g_mutex); - - if(g_initCounter != 0 || NN_RESULT_IS_SUCCESS((result=InitializeImpl()))) + static void InitVTable() { - g_initCounter++; - result = 0; + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(AlmightyTask); + s_VTable->rttiTask.ptr = nullptr; // todo + } + }; + static_assert(sizeof(AlmightyTask) == 0x20); + + struct DataName + { + char name[32]; + + static DataName* ctor(DataName* _this) // __ct__Q3_2nn4boss8DataNameFv + { + if(!_this) + _this = boss_new<DataName>(); + memset(_this->name, 0, sizeof(name)); + return _this; } - coreinit::OSUnlockMutex(&g_mutex); - return result; - } + static const char* operator_const_char(DataName* _this) // __opPCc__Q3_2nn4boss8DataNameCFv + { + return _this->name; + } + }; + static_assert(sizeof(DataName) == 0x20); - void export_Initialize(PPCInterpreter_t* hCPU) + struct BossStorageFadEntry { - cemuLog_logDebug(LogType::Force, "nn_boss_Initialize()"); - osLib_returnFromFunction(hCPU, Initialize()); - } - - void export_GetBossState(PPCInterpreter_t* hCPU) - { - cemuLog_logDebug(LogType::Force, "nn_boss.GetBossState() - stub"); - osLib_returnFromFunction(hCPU, 7); - } - - enum StorageKind - { - kStorageKind_NBDL, - kStorageKind_RawDl, + char name[32]; + uint32be fileNameId; + uint32 ukn24; + uint32 ukn28; + uint32 ukn2C; + uint32 ukn30; + uint32be timestampRelated; // guessed }; - namespace Storage +#define FAD_ENTRY_MAX_COUNT 512 + + struct Storage { - struct bossStorage_t + struct VTableStorage { - /* +0x00 */ uint32be accountId; - /* +0x04 */ uint32be storageKind; - /* +0x08 */ uint8 ukn08Array[3]; - /* +0x0B */ char storageName[8]; - uint8 ukn13; - uint8 ukn14; - uint8 ukn15; - uint8 ukn16; - uint8 ukn17; - /* +0x18 */ - nn::boss::TitleId_t titleId; - uint32be ukn20; // pointer to some global struct - uint32be ukn24; + VTableEntry rtti; + VTableEntry dtor; }; - - static_assert(sizeof(bossStorage_t) == 0x28); - static_assert(offsetof(bossStorage_t, storageKind) == 0x04); - static_assert(offsetof(bossStorage_t, ukn08Array) == 0x08); - static_assert(offsetof(bossStorage_t, storageName) == 0x0B); - static_assert(offsetof(bossStorage_t, titleId) == 0x18); + static inline SysAllocator<VTableStorage> s_vTable; - bossStorage_t* ctor(bossStorage_t* thisptr) + enum StorageKind { - cemuLog_logDebug(LogType::Force, "nn_boss_Storage_ctor(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - { - // thisptr = new RawDlTaskSetting_t - assert_dbg(); - } + kStorageKind_NBDL, + kStorageKind_RawDl, + }; - if (thisptr) - { - thisptr->titleId.u64 = 0; - thisptr->ukn20 = 0x10000a64; - } + /* +0x00 */ uint32be accountId; + /* +0x04 */ uint32be storageKind; + /* +0x08 */ uint8 ukn08Array[3]; + /* +0x0B */ char storageName[8]; + uint8 ukn13; + uint8 ukn14; + uint8 ukn15; + uint8 ukn16; + uint8 ukn17; + /* +0x18 */ nn::boss::TitleId titleId; + /* +0x20 */ MEMPTR<VTableStorage> vTablePtr; + /* +0x24 */ uint32be ukn24; - return thisptr; + static nn::boss::Storage* ctor1(nn::boss::Storage* _this) // __ct__Q3_2nn4boss7StorageFv + { + if(!_this) + _this = boss_new<nn::boss::Storage>(); + _this->vTablePtr = s_vTable; + _this->titleId.u64 = 0; + return _this; } - void nnBossStorage_prepareTitleId(bossStorage_t* storage) + static void dtor(nn::boss::Storage* _this, uint32 options) // __dt__Q3_2nn4boss7StorageFv + { + cemuLog_logDebug(LogType::Force, "nn::boss::Storage::dtor(0x{:08x}, 0x{:08x})", MEMPTR(_this).GetMPTR(), options); + Finalize(_this); + if(options & 1) + boss_delete(_this); + } + + static void nnBossStorage_prepareTitleId(Storage* storage) { if (storage->titleId.u64 != 0) return; storage->titleId.u64 = CafeSystem::GetForegroundTitleId(); } - Result Initialize(bossStorage_t* thisptr, const char* dirName, uint32 accountId, StorageKind type) + static Result Initialize(Storage* _thisptr, const char* dirName, uint32 accountId, StorageKind type) { if (!dirName) return 0xC0203780; cemuLog_logDebug(LogType::Force, "boss::Storage::Initialize({}, 0x{:08x}, {})", dirName, accountId, type); - thisptr->storageKind = type; - thisptr->titleId.u64 = 0; + _thisptr->storageKind = type; + _thisptr->titleId.u64 = 0; - memset(thisptr->storageName, 0, 0x8); - strncpy(thisptr->storageName, dirName, 0x8); - thisptr->storageName[7] = '\0'; + memset(_thisptr->storageName, 0, 0x8); + strncpy(_thisptr->storageName, dirName, 0x8); + _thisptr->storageName[7] = '\0'; - thisptr->accountId = accountId; + _thisptr->accountId = accountId; - nnBossStorage_prepareTitleId(thisptr); // usually not done like this + nnBossStorage_prepareTitleId(_thisptr); // usually not done like this return 0x200080; } - Result Initialize2(bossStorage_t* thisptr, const char* dirName, StorageKind type) + static Result Initialize2(Storage* _thisptr, const char* dirName, StorageKind type) { - return Initialize(thisptr, dirName, 0, type); + return Initialize(_thisptr, dirName, 0, type); } - } - using Storage_t = Storage::bossStorage_t; - struct AlmightyStorage_t : Storage_t - { - }; - static_assert(sizeof(AlmightyStorage_t) == 0x28); - - namespace AlmightyStorage - { - AlmightyStorage_t* ctor(AlmightyStorage_t* thisptr) + static void Finalize(Storage* _this) { - cemuLog_logDebug(LogType::Force, "nn_boss_AlmightyStorage_ctor(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) + memset(_this, 0, sizeof(Storage)); // todo - not all fields might be cleared + } + + static Result GetDataList(nn::boss::Storage* storage, DataName* dataList, sint32 maxEntries, uint32be* outputEntryCount, uint32 startIndex) // GetDataList__Q3_2nn4boss7StorageCFPQ3_2nn4boss8DataNameUiPUiT2 + { + // initialize titleId of storage if not already done + nnBossStorage_prepareTitleId(storage); + + cemu_assert_debug(startIndex == 0); // non-zero index is todo + + // load fad.db + BossStorageFadEntry* fadTable = nnBossStorageFad_getTable(storage); + if (fadTable) { - // thisptr = new RawDlTaskSetting_t - assert_dbg(); + sint32 validEntryCount = 0; + for (sint32 i = 0; i < FAD_ENTRY_MAX_COUNT; i++) + { + if( fadTable[i].name[0] == '\0' ) + continue; + memcpy(dataList[validEntryCount].name, fadTable[i].name, 0x20); + validEntryCount++; + if (validEntryCount >= maxEntries) + break; + } + *outputEntryCount = validEntryCount; + free(fadTable); } - - if (thisptr) + else { - Storage::ctor(thisptr); - thisptr->ukn20 = 0x100028a4; + // could not load fad table + *outputEntryCount = 0; } - - return thisptr; + return 0; // todo } - uint32 Initialize(AlmightyStorage_t* thisptr, TitleId_t* titleId, const char* storageName, uint32 accountId, StorageKind storageKind) + static bool Exist(nn::boss::Storage* storage) { - cemuLog_logDebug(LogType::Force, "nn_boss_AlmightyStorage_Initialize(0x{:x})", MEMPTR(thisptr).GetMPTR()); - if (!thisptr) - return 0xc0203780; - - thisptr->accountId = accountId; - thisptr->storageKind = storageKind; - thisptr->titleId.u64 = titleId->u64; - - strncpy(thisptr->storageName, storageName, 8); - thisptr->storageName[0x7] = 0x00; - - return 0x200080; - } - } -} -} - -// Storage - -struct bossDataName_t -{ - char name[32]; -}; - -static_assert(sizeof(bossDataName_t) == 0x20); - -struct bossStorageFadEntry_t -{ - char name[32]; - uint32be fileNameId; - uint32 ukn24; - uint32 ukn28; - uint32 ukn2C; - uint32 ukn30; - uint32be timestampRelated; // guessed -}; - -// __ct__Q3_2nn4boss8DataNameFv -void nnBossDataNameExport_ct(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(dataName, bossDataName_t, 0); - memset(dataName, 0, sizeof(bossDataName_t)); - osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(dataName)); -} - -// __opPCc__Q3_2nn4boss8DataNameCFv -void nnBossDataNameExport_opPCc(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(dataName, bossDataName_t, 0); - osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(dataName->name)); -} - -void nnBossStorageExport_ct(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(storage, nn::boss::Storage::bossStorage_t, 0); - cemuLog_logDebug(LogType::Force, "Constructor for boss storage called"); - // todo - memset(storage, 0, sizeof(nn::boss::Storage::bossStorage_t)); - osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(storage)); -} - -void nnBossStorageExport_exist(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(storage, nn::boss::Storage::bossStorage_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss.Storage_Exist(...) TODO"); - - // todo - osLib_returnFromFunction(hCPU, 1); -} - -#define FAD_ENTRY_MAX_COUNT 512 - -FSCVirtualFile* nnBossStorageFile_open(nn::boss::Storage::bossStorage_t* storage, uint32 fileNameId) -{ - char storageFilePath[1024]; - sprintf(storageFilePath, "/cemuBossStorage/%08x/%08x/user/common/data/%s/%08x", (uint32)(storage->titleId.u64 >> 32), (uint32)(storage->titleId.u64), storage->storageName, fileNameId); - sint32 fscStatus; - FSCVirtualFile* fscStorageFile = fsc_open(storageFilePath, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION, &fscStatus); - return fscStorageFile; -} - -bossStorageFadEntry_t* nnBossStorageFad_getTable(nn::boss::Storage::bossStorage_t* storage) -{ - const auto accountId = ActiveSettings::GetPersistentId(); - char fadPath[1024]; - sprintf(fadPath, "/cemuBossStorage/%08x/%08x/user/common/%08x/%s/fad.db", (uint32)(storage->titleId.u64 >> 32), (uint32)(storage->titleId.u64), accountId, storage->storageName); - - sint32 fscStatus; - FSCVirtualFile* fscFadFile = fsc_open(fadPath, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); - if (!fscFadFile) - { - return nullptr; - } - // skip first 8 bytes - fsc_setFileSeek(fscFadFile, 8); - // read entries - bossStorageFadEntry_t* fadTable = (bossStorageFadEntry_t*)malloc(sizeof(bossStorageFadEntry_t)*FAD_ENTRY_MAX_COUNT); - memset(fadTable, 0, sizeof(bossStorageFadEntry_t)*FAD_ENTRY_MAX_COUNT); - fsc_readFile(fscFadFile, fadTable, sizeof(bossStorageFadEntry_t)*FAD_ENTRY_MAX_COUNT); - fsc_close(fscFadFile); - return fadTable; -} - -// Find index of entry by name. Returns -1 if not found -sint32 nnBossStorageFad_getIndexByName(bossStorageFadEntry_t* fadTable, char* name) -{ - for (sint32 i = 0; i < FAD_ENTRY_MAX_COUNT; i++) - { - if (fadTable[i].name[0] == '\0') - continue; - if (strncmp(name, fadTable[i].name, 0x20) == 0) - { - return i; - } - } - return -1; -} - -bool nnBossStorageFad_getEntryByName(nn::boss::Storage::bossStorage_t* storage, char* name, bossStorageFadEntry_t* fadEntry) -{ - bossStorageFadEntry_t* fadTable = nnBossStorageFad_getTable(storage); - if (fadTable) - { - sint32 entryIndex = nnBossStorageFad_getIndexByName(fadTable, name); - if (entryIndex >= 0) - { - memcpy(fadEntry, fadTable + entryIndex, sizeof(bossStorageFadEntry_t)); - free(fadTable); + cemuLog_logDebug(LogType::Force, "nn_boss::Storage::Exist() TODO"); return true; } - free(fadTable); - } - return false; -} -void nnBossStorageExport_getDataList(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(storage, nn::boss::Storage::bossStorage_t, 0); - ppcDefineParamStructPtr(dataList, bossDataName_t, 1); - ppcDefineParamS32(maxEntries, 2); - ppcDefineParamU32BEPtr(outputEntryCount, 3); - cemuLog_logDebug(LogType::Force, "boss storage getDataList()"); + /* FAD access */ - // initialize titleId of storage if not already done - nnBossStorage_prepareTitleId(storage); - - // load fad.db - bossStorageFadEntry_t* fadTable = nnBossStorageFad_getTable(storage); - if (fadTable) - { - sint32 validEntryCount = 0; - for (sint32 i = 0; i < FAD_ENTRY_MAX_COUNT; i++) + static FSCVirtualFile* nnBossStorageFile_open(nn::boss::Storage* storage, uint32 fileNameId) { - if( fadTable[i].name[0] == '\0' ) - continue; - memcpy(dataList[validEntryCount].name, fadTable[i].name, 0x20); - validEntryCount++; - if (validEntryCount >= maxEntries) - break; + char storageFilePath[1024]; + sprintf(storageFilePath, "/cemuBossStorage/%08x/%08x/user/common/data/%s/%08x", (uint32)(storage->titleId.u64 >> 32), (uint32)(storage->titleId.u64), storage->storageName, fileNameId); + sint32 fscStatus; + FSCVirtualFile* fscStorageFile = fsc_open(storageFilePath, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION | FSC_ACCESS_FLAG::WRITE_PERMISSION, &fscStatus); + return fscStorageFile; } - *outputEntryCount = validEntryCount; - free(fadTable); - } - else - { - // could not load fad table - *outputEntryCount = 0; - } - osLib_returnFromFunction(hCPU, 0); // error code -} -// NsData - -typedef struct -{ - /* +0x00 */ char name[0x20]; - /* +0x20 */ nn::boss::Storage::bossStorage_t storage; - /* +0x48 */ uint64 readIndex; - /* +0x50 */ uint32 ukn50; // some pointer to a global struct - /* +0x54 */ uint32 ukn54; -}nsData_t; - -void nnBossNsDataExport_ct(PPCInterpreter_t* hCPU) -{ - cemuLog_logDebug(LogType::Force, "nnBossNsDataExport_ct"); - ppcDefineParamStructPtr(nsData, nsData_t, 0); - if (!nsData) - assert_dbg(); - - - nsData->ukn50 = 0x10000530; - - memset(nsData->name, 0, 0x20); - - nsData->storage.ukn20 = 0x10000798; - nsData->storage.titleId.u64 = 0; - - nsData->readIndex = 0; - - osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(nsData)); -} - -void nnBossNsDataExport_initialize(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - ppcDefineParamStructPtr(storage, nn::boss::Storage::bossStorage_t, 1); - ppcDefineParamStr(dataName, 2); - - if(dataName == nullptr) - { - if (storage->storageKind != 1) + static BossStorageFadEntry* nnBossStorageFad_getTable(nn::boss::Storage* storage) { - osLib_returnFromFunction(hCPU, 0xC0203780); - return; + const auto accountId = ActiveSettings::GetPersistentId(); + char fadPath[1024]; + sprintf(fadPath, "/cemuBossStorage/%08x/%08x/user/common/%08x/%s/fad.db", (uint32)(storage->titleId.u64 >> 32), (uint32)(storage->titleId.u64), accountId, storage->storageName); + + sint32 fscStatus; + FSCVirtualFile* fscFadFile = fsc_open(fadPath, FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); + if (!fscFadFile) + { + return nullptr; + } + // skip first 8 bytes + fsc_setFileSeek(fscFadFile, 8); + // read entries + BossStorageFadEntry* fadTable = (BossStorageFadEntry*)malloc(sizeof(BossStorageFadEntry)*FAD_ENTRY_MAX_COUNT); + memset(fadTable, 0, sizeof(BossStorageFadEntry)*FAD_ENTRY_MAX_COUNT); + fsc_readFile(fscFadFile, fadTable, sizeof(BossStorageFadEntry)*FAD_ENTRY_MAX_COUNT); + fsc_close(fscFadFile); + return fadTable; } - } - - nsData->storage.accountId = storage->accountId; - nsData->storage.storageKind = storage->storageKind; - memcpy(nsData->storage.ukn08Array, storage->ukn08Array, 3); - memcpy(nsData->storage.storageName, storage->storageName, 8); - - nsData->storage.titleId.u64 = storage->titleId.u64; - - nsData->storage = *storage; - - if (dataName != nullptr || storage->storageKind != 1) - strncpy(nsData->name, dataName, 0x20); - else - strncpy(nsData->name, "rawcontent.dat", 0x20); - nsData->name[0x1F] = '\0'; - - nsData->readIndex = 0; - - cemuLog_logDebug(LogType::Force, "nnBossNsDataExport_initialize: {}", nsData->name); - - osLib_returnFromFunction(hCPU, 0x200080); -} - -std::string nnBossNsDataExport_GetPath(nsData_t* nsData) -{ - uint32 accountId = nsData->storage.accountId; - if (accountId == 0) - accountId = iosuAct_getAccountIdOfCurrentAccount(); - - uint64 title_id = nsData->storage.titleId.u64; - if (title_id == 0) - title_id = CafeSystem::GetForegroundTitleId(); - - fs::path path = fmt::format("cemuBossStorage/{:08x}/{:08x}/user/{:08x}", (uint32)(title_id >> 32), (uint32)(title_id & 0xFFFFFFFF), accountId); - path /= nsData->storage.storageName; - path /= nsData->name; - return path.string(); -} - -void nnBossNsDataExport_DeleteRealFileWithHistory(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - cemuLog_logDebug(LogType::Force, "nn_boss.NsData_DeleteRealFileWithHistory(...)"); - - if (nsData->storage.storageKind == nn::boss::kStorageKind_NBDL) - { - // todo - cemuLog_log(LogType::Force, "BOSS NBDL: Unsupported delete"); - } - else - { - sint32 fscStatus = FSC_STATUS_OK; - std::string filePath = nnBossNsDataExport_GetPath(nsData).c_str(); - fsc_remove((char*)filePath.c_str(), &fscStatus); - if (fscStatus != 0) - cemuLog_log(LogType::Force, "Unhandeled FSC status in BOSS DeleteRealFileWithHistory()"); - } - osLib_returnFromFunction(hCPU, 0); -} - -void nnBossNsDataExport_Exist(PPCInterpreter_t* hCPU) -{ - cemuLog_logDebug(LogType::Force, "nn_boss.NsData_Exist(...)"); - ppcDefineParamStructPtr(nsData, nsData_t, 0); - - bool fileExists = false; - if(nsData->storage.storageKind == nn::boss::kStorageKind_NBDL) - { - // check if name is present in fad table - bossStorageFadEntry_t* fadTable = nnBossStorageFad_getTable(&nsData->storage); - if (fadTable) + // Find index of entry by name. Returns -1 if not found + static sint32 nnBossStorageFad_getIndexByName(BossStorageFadEntry* fadTable, char* name) { - fileExists = nnBossStorageFad_getIndexByName(fadTable, nsData->name) >= 0; - cemuLog_logDebug(LogType::Force, "\t({}) -> {}", nsData->name, fileExists); - free(fadTable); + for (sint32 i = 0; i < FAD_ENTRY_MAX_COUNT; i++) + { + if (fadTable[i].name[0] == '\0') + continue; + if (strncmp(name, fadTable[i].name, 0x20) == 0) + { + return i; + } + } + return -1; } - } - else - { - sint32 fscStatus; - auto fscStorageFile = fsc_open((char*)nnBossNsDataExport_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE, &fscStatus); - if (fscStorageFile != nullptr) + + static bool nnBossStorageFad_getEntryByName(nn::boss::Storage* storage, char* name, BossStorageFadEntry* fadEntry) { - fileExists = true; + BossStorageFadEntry* fadTable = nnBossStorageFad_getTable(storage); + if (fadTable) + { + sint32 entryIndex = nnBossStorageFad_getIndexByName(fadTable, name); + if (entryIndex >= 0) + { + memcpy(fadEntry, fadTable + entryIndex, sizeof(BossStorageFadEntry)); + free(fadTable); + return true; + } + free(fadTable); + } + return false; + } + + static void InitVTable() + { + s_vTable->rtti.ptr = nullptr; // todo + s_vTable->dtor.ptr = DTOR_WRAPPER(Storage); + } + }; + + static_assert(sizeof(Storage) == 0x28); + static_assert(offsetof(Storage, storageKind) == 0x04); + static_assert(offsetof(Storage, ukn08Array) == 0x08); + static_assert(offsetof(Storage, storageName) == 0x0B); + static_assert(offsetof(Storage, titleId) == 0x18); + + struct AlmightyStorage : Storage + { + struct VTableAlmightyStorage : public VTableStorage + { + VTableEntry rttiStorage; + }; + static_assert(sizeof(VTableAlmightyStorage) == 8*3); + static inline SysAllocator<VTableAlmightyStorage> s_VTable; + + static AlmightyStorage* ctor(AlmightyStorage* _thisptr) + { + cemuLog_logDebug(LogType::Force, "nn_boss_AlmightyStorage_ctor(0x{:x})", MEMPTR(_thisptr).GetMPTR()); + if (!_thisptr) + _thisptr = boss_new<AlmightyStorage>(); + Storage::ctor1(_thisptr); + _thisptr->vTablePtr = s_VTable; + return _thisptr; + } + + static uint32 Initialize(AlmightyStorage* _thisptr, TitleId* titleId, const char* storageName, uint32 accountId, StorageKind storageKind) + { + cemuLog_logDebug(LogType::Force, "nn_boss_AlmightyStorage_Initialize(0x{:x})", MEMPTR(_thisptr).GetMPTR()); + if (!_thisptr) + return 0xc0203780; + + _thisptr->accountId = accountId; + _thisptr->storageKind = storageKind; + _thisptr->titleId.u64 = titleId->u64; + + strncpy(_thisptr->storageName, storageName, 8); + _thisptr->storageName[0x7] = 0x00; + + return 0x200080; + } + + static void InitVTable() + { + s_VTable->rtti.ptr = nullptr; // todo + s_VTable->dtor.ptr = DTOR_WRAPPER(AlmightyStorage); + s_VTable->rttiStorage.ptr = nullptr; // todo + } + }; + static_assert(sizeof(AlmightyStorage) == 0x28); + + // NsData + + struct NsData + { + struct VTableNsData + { + VTableEntry rtti; + VTableEntry dtor; + }; + static inline SysAllocator<VTableNsData> s_vTable; + + /* +0x00 */ char name[0x20]; // DataName ? + /* +0x20 */ nn::boss::Storage storage; + /* +0x48 */ uint64 readIndex; + /* +0x50 */ MEMPTR<void> vTablePtr; + /* +0x54 */ uint32 ukn54; + + static NsData* ctor(NsData* _this) + { + if (!_this) + _this = boss_new<NsData>(); + _this->vTablePtr = s_vTable; + memset(_this->name, 0, sizeof(_this->name)); + _this->storage.ctor1(&_this->storage); + _this->readIndex = 0; + return _this; + } + + static void dtor(NsData* _this, uint32 options) // __dt__Q3_2nn4boss6NsDataFv + { + _this->storage.dtor(&_this->storage, 0); + // todo + if(options & 1) + boss_delete(_this); + } + + static Result Initialize(NsData* _this, nn::boss::Storage* storage, const char* dataName) + { + if(dataName == nullptr) + { + if (storage->storageKind != 1) + { + return 0xC0203780; + } + } + + _this->storage.accountId = storage->accountId; + _this->storage.storageKind = storage->storageKind; + + memcpy(_this->storage.ukn08Array, storage->ukn08Array, 3); + memcpy(_this->storage.storageName, storage->storageName, 8); + + _this->storage.titleId.u64 = storage->titleId.u64; + + _this->storage = *storage; + + if (dataName != nullptr || storage->storageKind != 1) + strncpy(_this->name, dataName, 0x20); + else + strncpy(_this->name, "rawcontent.dat", 0x20); + _this->name[0x1F] = '\0'; + + _this->readIndex = 0; + + cemuLog_logDebug(LogType::Force, "initialize: {}", _this->name); + + return 0x200080; + } + + static std::string _GetPath(NsData* nsData) + { + uint32 accountId = nsData->storage.accountId; + if (accountId == 0) + accountId = iosuAct_getAccountIdOfCurrentAccount(); + + uint64 title_id = nsData->storage.titleId.u64; + if (title_id == 0) + title_id = CafeSystem::GetForegroundTitleId(); + + fs::path path = fmt::format("cemuBossStorage/{:08x}/{:08x}/user/{:08x}", (uint32)(title_id >> 32), (uint32)(title_id & 0xFFFFFFFF), accountId); + path /= nsData->storage.storageName; + path /= nsData->name; + return path.string(); + } + + static Result DeleteRealFileWithHistory(NsData* nsData) + { + if (nsData->storage.storageKind == nn::boss::Storage::kStorageKind_NBDL) + { + // todo + cemuLog_log(LogType::Force, "BOSS NBDL: Unsupported delete"); + } + else + { + sint32 fscStatus = FSC_STATUS_OK; + std::string filePath = _GetPath(nsData).c_str(); + fsc_remove((char*)filePath.c_str(), &fscStatus); + if (fscStatus != 0) + cemuLog_log(LogType::Force, "Unhandeled FSC status in BOSS DeleteRealFileWithHistory()"); + } + return 0; + } + + static uint32 Exist(NsData* nsData) + { + bool fileExists = false; + if(nsData->storage.storageKind == nn::boss::Storage::kStorageKind_NBDL) + { + // check if name is present in fad table + BossStorageFadEntry* fadTable = nn::boss::Storage::nnBossStorageFad_getTable(&nsData->storage); + if (fadTable) + { + fileExists = nn::boss::Storage::nnBossStorageFad_getIndexByName(fadTable, nsData->name) >= 0; + cemuLog_logDebug(LogType::Force, "\t({}) -> {}", nsData->name, fileExists); + free(fadTable); + } + } + else + { + sint32 fscStatus; + auto fscStorageFile = fsc_open(_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE, &fscStatus); + if (fscStorageFile != nullptr) + { + fileExists = true; + fsc_close(fscStorageFile); + } + } + return fileExists?1:0; + } + + static uint64 GetSize(NsData* nsData) + { + FSCVirtualFile* fscStorageFile = nullptr; + if (nsData->storage.storageKind == nn::boss::Storage::kStorageKind_NBDL) + { + BossStorageFadEntry fadEntry; + if (nn::boss::Storage::nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + { + cemuLog_log(LogType::Force, "BOSS storage cant find file {}", nsData->name); + return 0; + } + // open file + fscStorageFile = nn::boss::Storage::nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); + } + else + { + sint32 fscStatus; + fscStorageFile = fsc_open(_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); + } + + if (fscStorageFile == nullptr) + { + cemuLog_log(LogType::Force, "BOSS storage cant open file alias {}", nsData->name); + return 0; + } + + // get size + const sint32 fileSize = fsc_getFileSize(fscStorageFile); + // close file fsc_close(fscStorageFile); + return fileSize; } - } - osLib_returnFromFunction(hCPU, fileExists?1:0); -} - -void nnBossNsDataExport_getSize(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - - FSCVirtualFile* fscStorageFile = nullptr; - if (nsData->storage.storageKind == nn::boss::kStorageKind_NBDL) - { - bossStorageFadEntry_t fadEntry; - if (nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + static uint64 GetCreatedTime(NsData* nsData) { - cemuLog_log(LogType::Force, "BOSS storage cant find file {}", nsData->name); - osLib_returnFromFunction(hCPU, 0); - return; + cemuLog_logDebug(LogType::Force, "nn_boss.NsData_GetCreatedTime() not implemented. Returning 0"); + uint64 createdTime = 0; + return createdTime; } - // open file - fscStorageFile = nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); - } - else - { - sint32 fscStatus; - fscStorageFile = fsc_open((char*)nnBossNsDataExport_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); - } - if (fscStorageFile == nullptr) - { - cemuLog_log(LogType::Force, "BOSS storage cant open file alias {}", nsData->name); - osLib_returnFromFunction(hCPU, 0); - return; - } - - // get size - const sint32 fileSize = fsc_getFileSize(fscStorageFile); - // close file - fsc_close(fscStorageFile); - osLib_returnFromFunction64(hCPU, fileSize); -} - -uint64 nnBossNsData_GetCreatedTime(nsData_t* nsData) -{ - cemuLog_logDebug(LogType::Force, "nn_boss.NsData_GetCreatedTime() not implemented. Returning 0"); - uint64 createdTime = 0; - return createdTime; -} - -uint32 nnBossNsData_read(nsData_t* nsData, uint64* sizeOutBE, void* buffer, sint32 length) -{ - FSCVirtualFile* fscStorageFile = nullptr; - if (nsData->storage.storageKind == nn::boss::kStorageKind_NBDL) - { - bossStorageFadEntry_t fadEntry; - if (nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + static uint32 nnBossNsData_read(NsData* nsData, uint64be* sizeOutBE, void* buffer, sint32 length) { - cemuLog_log(LogType::Force, "BOSS storage cant find file {} for reading", nsData->name); - return 0x80000000; // todo - proper error code + FSCVirtualFile* fscStorageFile = nullptr; + if (nsData->storage.storageKind == nn::boss::Storage::kStorageKind_NBDL) + { + BossStorageFadEntry fadEntry; + if (nn::boss::Storage::nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + { + cemuLog_log(LogType::Force, "BOSS storage cant find file {} for reading", nsData->name); + return 0x80000000; // todo - proper error code + } + // open file + fscStorageFile = nn::boss::Storage::nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); + } + else + { + sint32 fscStatus; + fscStorageFile = fsc_open(_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); + } + + if (!fscStorageFile) + { + cemuLog_log(LogType::Force, "BOSS storage cant open file alias {} for reading", nsData->name); + return 0x80000000; // todo - proper error code + } + // get size + sint32 fileSize = fsc_getFileSize(fscStorageFile); + // verify read is within bounds + sint32 readEndOffset = (sint32)_swapEndianU64(nsData->readIndex) + length; + sint32 readBytes = length; + if (readEndOffset > fileSize) + { + readBytes = fileSize - (sint32)_swapEndianU64(nsData->readIndex); + cemu_assert_debug(readBytes != 0); + } + // read + fsc_setFileSeek(fscStorageFile, (uint32)_swapEndianU64(nsData->readIndex)); + fsc_readFile(fscStorageFile, buffer, readBytes); + nsData->readIndex = _swapEndianU64((sint32)_swapEndianU64(nsData->readIndex) + readBytes); + + // close file + fsc_close(fscStorageFile); + if (sizeOutBE) + *sizeOutBE = readBytes; + return 0; } - // open file - fscStorageFile = nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); - } - else - { - sint32 fscStatus; - fscStorageFile = fsc_open((char*)nnBossNsDataExport_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); - } - - if (!fscStorageFile) - { - cemuLog_log(LogType::Force, "BOSS storage cant open file alias {} for reading", nsData->name); - return 0x80000000; // todo - proper error code - } - // get size - sint32 fileSize = fsc_getFileSize(fscStorageFile); - // verify read is within bounds - sint32 readEndOffset = (sint32)_swapEndianU64(nsData->readIndex) + length; - sint32 readBytes = length; - if (readEndOffset > fileSize) - { - readBytes = fileSize - (sint32)_swapEndianU64(nsData->readIndex); - cemu_assert_debug(readBytes != 0); - } - // read - fsc_setFileSeek(fscStorageFile, (uint32)_swapEndianU64(nsData->readIndex)); - fsc_readFile(fscStorageFile, buffer, readBytes); - nsData->readIndex = _swapEndianU64((sint32)_swapEndianU64(nsData->readIndex) + readBytes); - - // close file - fsc_close(fscStorageFile); - if (sizeOutBE) - *sizeOutBE = _swapEndianU64(readBytes); - return 0; -} #define NSDATA_SEEK_MODE_BEGINNING (0) -uint32 nnBossNsData_seek(nsData_t* nsData, uint64 seek, uint32 mode) -{ - FSCVirtualFile* fscStorageFile = nullptr; - if (nsData->storage.storageKind == nn::boss::kStorageKind_NBDL) - { - bossStorageFadEntry_t fadEntry; - if (nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + static uint32 nnBossNsData_seek(NsData* nsData, uint64 seek, uint32 mode) { - cemuLog_log(LogType::Force, "BOSS storage cant find file {} for reading", nsData->name); - return 0x80000000; // todo - proper error code + FSCVirtualFile* fscStorageFile = nullptr; + if (nsData->storage.storageKind == nn::boss::Storage::kStorageKind_NBDL) + { + BossStorageFadEntry fadEntry; + if (nn::boss::Storage::nnBossStorageFad_getEntryByName(&nsData->storage, nsData->name, &fadEntry) == false) + { + cemuLog_log(LogType::Force, "BOSS storage cant find file {} for reading", nsData->name); + return 0x80000000; // todo - proper error code + } + // open file + fscStorageFile = nn::boss::Storage::nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); + } + else + { + sint32 fscStatus; + fscStorageFile = fsc_open(_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); + } + + if (fscStorageFile == nullptr) + { + cemuLog_log(LogType::Force, "BOSS storage cant open file alias {} for reading", nsData->name); + return 0x80000000; // todo - proper error code + } + // get size + sint32 fileSize = fsc_getFileSize(fscStorageFile); + // handle seek + if (mode == NSDATA_SEEK_MODE_BEGINNING) + { + seek = std::min(seek, (uint64)fileSize); + nsData->readIndex = _swapEndianU64((uint64)seek); + } + else + { + cemu_assert_unimplemented(); + } + fsc_close(fscStorageFile); + return 0; } - // open file - fscStorageFile = nnBossStorageFile_open(&nsData->storage, fadEntry.fileNameId); - } - else - { - sint32 fscStatus; - fscStorageFile = fsc_open((char*)nnBossNsDataExport_GetPath(nsData).c_str(), FSC_ACCESS_FLAG::OPEN_FILE | FSC_ACCESS_FLAG::READ_PERMISSION, &fscStatus); - } - if (fscStorageFile == nullptr) - { - cemuLog_log(LogType::Force, "BOSS storage cant open file alias {} for reading", nsData->name); - return 0x80000000; // todo - proper error code - } - // get size - sint32 fileSize = fsc_getFileSize(fscStorageFile); - // handle seek - if (mode == NSDATA_SEEK_MODE_BEGINNING) - { - seek = std::min(seek, (uint64)fileSize); - nsData->readIndex = _swapEndianU64((uint64)seek); - } - else - { - cemu_assert_unimplemented(); - } - fsc_close(fscStorageFile); - return 0; + static sint32 Read(NsData* nsData, uint8* buffer, sint32 length) + { + cemuLog_logDebug(LogType::Force, "nsData read (filename {})", nsData->name); + return nnBossNsData_read(nsData, nullptr, buffer, length); + } + + static sint32 ReadWithSizeOut(NsData* nsData, uint64be* sizeOut, uint8* buffer, sint32 length) + { + uint32 r = nnBossNsData_read(nsData, sizeOut, buffer, length); + cemuLog_logDebug(LogType::Force, "nsData readWithSizeOut (filename {} length 0x{:x}) Result: {} Sizeout: {:x}", nsData->name, length, r, _swapEndianU64(*sizeOut)); + return r; + } + + static Result Seek(NsData* nsData, uint64 seekPos, uint32 mode) + { + uint32 r = nnBossNsData_seek(nsData, seekPos, mode); + cemuLog_logDebug(LogType::Force, "nsData seek (filename {} seek 0x{:x}) Result: {}", nsData->name, (uint32)seekPos, r); + return r; + } + + static void InitVTable() + { + s_vTable->rtti.ptr = nullptr; // todo + s_vTable->dtor.ptr = DTOR_WRAPPER(NsData); + } + }; + static_assert(sizeof(NsData) == 0x58); + +} } - -void nnBossNsDataExport_read(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - ppcDefineParamStr(buffer, 1); - ppcDefineParamS32(length, 2); - - cemuLog_logDebug(LogType::Force, "nsData read (filename {})", nsData->name); - - uint32 r = nnBossNsData_read(nsData, nullptr, buffer, length); - - osLib_returnFromFunction(hCPU, r); -} - -void nnBossNsDataExport_readWithSizeOut(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - ppcDefineParamTypePtr(sizeOut, uint64, 1); - ppcDefineParamStr(buffer, 2); - ppcDefineParamS32(length, 3); - - uint32 r = nnBossNsData_read(nsData, sizeOut, buffer, length); - cemuLog_logDebug(LogType::Force, "nsData readWithSizeOut (filename {} length 0x{:x}) Result: {} Sizeout: {:x}", nsData->name, length, r, _swapEndianU64(*sizeOut)); - - osLib_returnFromFunction(hCPU, r); -} - -void nnBossNsDataExport_seek(PPCInterpreter_t* hCPU) -{ - ppcDefineParamStructPtr(nsData, nsData_t, 0); - ppcDefineParamU64(seekPos, 2); - ppcDefineParamU32(mode, 4); - - uint32 r = nnBossNsData_seek(nsData, seekPos, mode); - - cemuLog_logDebug(LogType::Force, "nsData seek (filename {} seek 0x{:x}) Result: {}", nsData->name, (uint32)seekPos, r); - - osLib_returnFromFunction(hCPU, r); -} - void nnBoss_load() { OSInitMutexEx(&nn::boss::g_mutex, nullptr); - osLib_addFunction("nn_boss", "Initialize__Q2_2nn4bossFv", nn::boss::export_Initialize); - osLib_addFunction("nn_boss", "GetBossState__Q2_2nn4bossFv", nn::boss::export_GetBossState); - + nn::boss::g_initCounter = 0; + nn::boss::g_isInitialized = false; + + cafeExportRegisterFunc(nn::boss::GetBossState, "nn_boss", "GetBossState__Q2_2nn4bossFv", LogType::NN_BOSS); + + // boss lib + cafeExportRegisterFunc(nn::boss::Initialize, "nn_boss", "Initialize__Q2_2nn4bossFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::IsInitialized, "nn_boss", "IsInitialized__Q2_2nn4bossFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Finalize, "nn_boss", "Finalize__Q2_2nn4bossFv", LogType::NN_BOSS); + // task - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss4TaskFv", nn::boss::Task::export_ctor); - osLib_addFunction("nn_boss", "Run__Q3_2nn4boss4TaskFb", nn::boss::Task::export_Run); - osLib_addFunction("nn_boss", "Wait__Q3_2nn4boss4TaskFUiQ3_2nn4boss13TaskWaitState", nn::boss::Task::export_Wait); - osLib_addFunction("nn_boss", "GetTurnState__Q3_2nn4boss4TaskCFPUi", nn::boss::Task::export_GetTurnState); - osLib_addFunction("nn_boss", "GetHttpStatusCode__Q3_2nn4boss4TaskCFPUi", nn::boss::Task::export_GetHttpStatusCode); - osLib_addFunction("nn_boss", "GetContentLength__Q3_2nn4boss4TaskCFPUi", nn::boss::Task::export_GetContentLength); - osLib_addFunction("nn_boss", "GetProcessedLength__Q3_2nn4boss4TaskCFPUi", nn::boss::Task::export_GetProcessedLength); - osLib_addFunction("nn_boss", "Register__Q3_2nn4boss4TaskFRQ3_2nn4boss11TaskSetting", nn::boss::Task::export_Register); - osLib_addFunction("nn_boss", "Unregister__Q3_2nn4boss4TaskFv", nn::boss::Task::export_Unregister); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss4TaskFPCc", nn::boss::Task::export_Initialize1); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss4TaskFUcPCc", nn::boss::Task::export_Initialize2); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss4TaskFPCcUi", nn::boss::Task::export_Initialize3); - osLib_addFunction("nn_boss", "IsRegistered__Q3_2nn4boss4TaskCFv", nn::boss::Task::export_IsRegistered); - osLib_addFunction("nn_boss", "RegisterForImmediateRun__Q3_2nn4boss4TaskFRCQ3_2nn4boss11TaskSetting", nn::boss::Task::export_RegisterForImmediateRun); - osLib_addFunction("nn_boss", "StartScheduling__Q3_2nn4boss4TaskFb", nn::boss::Task::export_StartScheduling); - osLib_addFunction("nn_boss", "StopScheduling__Q3_2nn4boss4TaskFv", nn::boss::Task::export_StopScheduling); + nn::boss::Task::InitVTable(); + cafeExportRegisterFunc(nn::boss::Task::ctor1, "nn_boss", "__ct__Q3_2nn4boss4TaskFUcPCc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::ctor2, "nn_boss", "__ct__Q3_2nn4boss4TaskFPCcUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::ctor3, "nn_boss", "__ct__Q3_2nn4boss4TaskFPCc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::ctor4, "nn_boss", "__ct__Q3_2nn4boss4TaskFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::dtor, "nn_boss", "__dt__Q3_2nn4boss4TaskFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Initialize1, "nn_boss", "Initialize__Q3_2nn4boss4TaskFPCcUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Initialize2, "nn_boss", "Initialize__Q3_2nn4boss4TaskFUcPCc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Initialize3, "nn_boss", "Initialize__Q3_2nn4boss4TaskFPCc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Run, "nn_boss", "Run__Q3_2nn4boss4TaskFb", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Wait, "nn_boss", "Wait__Q3_2nn4boss4TaskFUiQ3_2nn4boss13TaskWaitState", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::GetTurnState, "nn_boss", "GetTurnState__Q3_2nn4boss4TaskCFPUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::GetHttpStatusCode, "nn_boss", "GetHttpStatusCode__Q3_2nn4boss4TaskCFPUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::GetContentLength, "nn_boss", "GetContentLength__Q3_2nn4boss4TaskCFPUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::GetProcessedLength, "nn_boss", "GetProcessedLength__Q3_2nn4boss4TaskCFPUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Register, "nn_boss", "Register__Q3_2nn4boss4TaskFRQ3_2nn4boss11TaskSetting", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::Unregister, "nn_boss", "Unregister__Q3_2nn4boss4TaskFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::IsRegistered, "nn_boss", "IsRegistered__Q3_2nn4boss4TaskCFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::RegisterForImmediateRun, "nn_boss", "RegisterForImmediateRun__Q3_2nn4boss4TaskFRCQ3_2nn4boss11TaskSetting", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::StartScheduling, "nn_boss", "StartScheduling__Q3_2nn4boss4TaskFb", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Task::StopScheduling, "nn_boss", "StopScheduling__Q3_2nn4boss4TaskFv", LogType::NN_BOSS); - // Nbdl task setting - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss15NbdlTaskSettingFv", nn::boss::NbdlTaskSetting::export_ctor); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss15NbdlTaskSettingFPCcLT1", nn::boss::NbdlTaskSetting::export_Initialize); - //osLib_addFunction("nn_boss", "SetFileName__Q3_2nn4boss15NbdlTaskSettingFPCc", nn::boss::NbdlTaskSetting::export_SetFileName); - cafeExportRegisterFunc(nn::boss::NbdlTaskSetting::SetFileName, "nn_boss", "SetFileName__Q3_2nn4boss15NbdlTaskSettingFPCc", LogType::Placeholder); + // TaskSetting + nn::boss::TaskSetting::InitVTable(); + cafeExportRegisterFunc(nn::boss::TaskSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss11TaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::TaskSetting::dtor, "nn_boss", "__dt__Q3_2nn4boss11TaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::TaskSetting::IsPrivileged, "nn_boss", "Initialize__Q3_2nn4boss11TaskSettingFPCcUi", LogType::NN_BOSS); + + // NbdlTaskSetting + nn::boss::NbdlTaskSetting::InitVTable(); + cafeExportRegisterFunc(nn::boss::NbdlTaskSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss15NbdlTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NbdlTaskSetting::dtor, "nn_boss", "__dt__Q3_2nn4boss15NbdlTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NbdlTaskSetting::Initialize, "nn_boss", "Initialize__Q3_2nn4boss15NbdlTaskSettingFPCcLT1", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NbdlTaskSetting::SetFileName, "nn_boss", "SetFileName__Q3_2nn4boss15NbdlTaskSettingFPCc", LogType::NN_BOSS); - // play task setting - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss17PlayReportSettingFv", nn::boss::PlayReportSetting::export_ctor); - osLib_addFunction("nn_boss", "Set__Q3_2nn4boss17PlayReportSettingFPCcUi", nn::boss::PlayReportSetting::export_Set); - //osLib_addFunction("nn_boss", "Set__Q3_2nn4boss17PlayReportSettingFUiT1", nn::boss::PlayReportSetting::export_Set); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss17PlayReportSettingFPvUi", nn::boss::PlayReportSetting::export_Initialize); + // PlayReportSetting + nn::boss::PlayReportSetting::InitVTable(); + cafeExportRegisterFunc(nn::boss::PlayReportSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss17PlayReportSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::PlayReportSetting::dtor, "nn_boss", "__dt__Q3_2nn4boss17PlayReportSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::PlayReportSetting::Initialize, "nn_boss", "Initialize__Q3_2nn4boss17PlayReportSettingFPvUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::PlayReportSetting::Set, "nn_boss", "Set__Q3_2nn4boss17PlayReportSettingFPCcUi", LogType::NN_BOSS); - cafeExportRegisterFunc(nn::boss::RawDlTaskSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss16RawDlTaskSettingFv", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::RawDlTaskSetting::Initialize, "nn_boss", "Initialize__Q3_2nn4boss16RawDlTaskSettingFPCcbT2N21", LogType::Placeholder); + // RawDlTaskSetting + nn::boss::RawDlTaskSetting::InitVTable(); + cafeExportRegisterFunc(nn::boss::RawDlTaskSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss16RawDlTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::RawDlTaskSetting::dtor, "nn_boss", "__dt__Q3_2nn4boss16RawDlTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::RawDlTaskSetting::Initialize, "nn_boss", "Initialize__Q3_2nn4boss16RawDlTaskSettingFPCcbT2N21", LogType::NN_BOSS); - cafeExportRegisterFunc(nn::boss::NetTaskSetting::SetServiceToken, "nn_boss", "SetServiceToken__Q3_2nn4boss14NetTaskSettingFPCUc", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::NetTaskSetting::AddInternalCaCert, "nn_boss", "AddInternalCaCert__Q3_2nn4boss14NetTaskSettingFSc", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::NetTaskSetting::SetInternalClientCert, "nn_boss", "SetInternalClientCert__Q3_2nn4boss14NetTaskSettingFSc", LogType::Placeholder); + // NetTaskSetting + nn::boss::NetTaskSetting::InitVTable(); + cafeExportRegisterFunc(nn::boss::NetTaskSetting::ctor, "nn_boss", "__ct__Q3_2nn4boss14NetTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NetTaskSetting::dtor, "nn_boss", "__dt__Q3_2nn4boss14NetTaskSettingFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NetTaskSetting::SetServiceToken, "nn_boss", "SetServiceToken__Q3_2nn4boss14NetTaskSettingFPCUc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NetTaskSetting::AddInternalCaCert, "nn_boss", "AddInternalCaCert__Q3_2nn4boss14NetTaskSettingFSc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NetTaskSetting::SetInternalClientCert, "nn_boss", "SetInternalClientCert__Q3_2nn4boss14NetTaskSettingFSc", LogType::NN_BOSS); // Title - cafeExportRegisterFunc(nn::boss::Title::ctor, "nn_boss", "__ct__Q3_2nn4boss5TitleFv", LogType::Placeholder); + nn::boss::Title::InitVTable(); + cafeExportRegisterFunc(nn::boss::Title::ctor, "nn_boss", "__ct__Q3_2nn4boss5TitleFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Title::dtor, "nn_boss", "__dt__Q3_2nn4boss5TitleFv", LogType::NN_BOSS); // cafeExportMakeWrapper<nn::boss::Title::SetNewArrivalFlagOff>("nn_boss", "SetNewArrivalFlagOff__Q3_2nn4boss5TitleFv"); SMM bookmarks // TitleId - cafeExportRegisterFunc(nn::boss::TitleId::ctor1, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFv", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::TitleId::ctor2, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFUL", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::TitleId::cctor, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFRCQ3_2nn4boss7TitleID", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::TitleId::operator_ne, "nn_boss", "__ne__Q3_2nn4boss7TitleIDCFRCQ3_2nn4boss7TitleID", LogType::Placeholder); + cafeExportRegisterFunc(nn::boss::TitleId::ctor1, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::TitleId::ctor2, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFUL", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::TitleId::ctor3, "nn_boss", "__ct__Q3_2nn4boss7TitleIDFRCQ3_2nn4boss7TitleID", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::TitleId::operator_ne, "nn_boss", "__ne__Q3_2nn4boss7TitleIDCFRCQ3_2nn4boss7TitleID", LogType::NN_BOSS); // DataName - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss8DataNameFv", nnBossDataNameExport_ct); - osLib_addFunction("nn_boss", "__opPCc__Q3_2nn4boss8DataNameCFv", nnBossDataNameExport_opPCc); + cafeExportRegisterFunc(nn::boss::DataName::ctor, "nn_boss", "__ct__Q3_2nn4boss8DataNameFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::DataName::operator_const_char, "nn_boss", "__opPCc__Q3_2nn4boss8DataNameCFv", LogType::NN_BOSS); // DirectoryName - cafeExportRegisterFunc(nn::boss::DirectoryName::ctor, "nn_boss", "__ct__Q3_2nn4boss13DirectoryNameFv", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::DirectoryName::operator_const_char, "nn_boss", "__opPCc__Q3_2nn4boss13DirectoryNameCFv", LogType::Placeholder); + cafeExportRegisterFunc(nn::boss::DirectoryName::ctor, "nn_boss", "__ct__Q3_2nn4boss13DirectoryNameFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::DirectoryName::operator_const_char, "nn_boss", "__opPCc__Q3_2nn4boss13DirectoryNameCFv", LogType::NN_BOSS); // Account - cafeExportRegisterFunc(nn::boss::Account::ctor, "nn_boss", "__ct__Q3_2nn4boss7AccountFUi", LogType::Placeholder); - - - // storage - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss7StorageFv", nnBossStorageExport_ct); - //osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss7StorageFPCcQ3_2nn4boss11StorageKind", nnBossStorageExport_initialize); - osLib_addFunction("nn_boss", "Exist__Q3_2nn4boss7StorageCFv", nnBossStorageExport_exist); - osLib_addFunction("nn_boss", "GetDataList__Q3_2nn4boss7StorageCFPQ3_2nn4boss8DataNameUiPUiT2", nnBossStorageExport_getDataList); - osLib_addFunction("nn_boss", "GetDataList__Q3_2nn4boss7StorageCFPQ3_2nn4boss8DataNameUiPUiT2", nnBossStorageExport_getDataList); - cafeExportRegisterFunc(nn::boss::Storage::Initialize, "nn_boss", "Initialize__Q3_2nn4boss7StorageFPCcUiQ3_2nn4boss11StorageKind", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::Storage::Initialize2, "nn_boss", "Initialize__Q3_2nn4boss7StorageFPCcQ3_2nn4boss11StorageKind", LogType::Placeholder); - - // AlmightyStorage - cafeExportRegisterFunc(nn::boss::AlmightyStorage::ctor, "nn_boss", "__ct__Q3_2nn4boss15AlmightyStorageFv", LogType::Placeholder ); - cafeExportRegisterFunc(nn::boss::AlmightyStorage::Initialize, "nn_boss", "Initialize__Q3_2nn4boss15AlmightyStorageFQ3_2nn4boss7TitleIDPCcUiQ3_2nn4boss11StorageKind", LogType::Placeholder ); + nn::boss::BossAccount::InitVTable(); + cafeExportRegisterFunc(nn::boss::BossAccount::ctor, "nn_boss", "__ct__Q3_2nn4boss7AccountFUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::BossAccount::dtor, "nn_boss", "__dt__Q3_2nn4boss7AccountFv", LogType::NN_BOSS); // AlmightyTask - cafeExportRegisterFunc(nn::boss::AlmightyTask::ctor, "nn_boss", "__ct__Q3_2nn4boss12AlmightyTaskFv", LogType::Placeholder); - cafeExportRegisterFunc(nn::boss::AlmightyTask::Initialize, "nn_boss", "Initialize__Q3_2nn4boss12AlmightyTaskFQ3_2nn4boss7TitleIDPCcUi", LogType::Placeholder); - // cafeExportRegisterFunc(nn::boss::AlmightyTask::dtor, "nn_boss", "__dt__Q3_2nn4boss12AlmightyTaskFv", LogType::Placeholder); + nn::boss::AlmightyTask::InitVTable(); + cafeExportRegisterFunc(nn::boss::AlmightyTask::ctor, "nn_boss", "__ct__Q3_2nn4boss12AlmightyTaskFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::AlmightyTask::Initialize, "nn_boss", "Initialize__Q3_2nn4boss12AlmightyTaskFQ3_2nn4boss7TitleIDPCcUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::AlmightyTask::dtor, "nn_boss", "__dt__Q3_2nn4boss12AlmightyTaskFv", LogType::NN_BOSS); + + // Storage + nn::boss::Storage::InitVTable(); + cafeExportRegisterFunc(nn::boss::Storage::ctor1, "nn_boss", "__ct__Q3_2nn4boss7StorageFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::dtor, "nn_boss", "__dt__Q3_2nn4boss7StorageFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::Finalize, "nn_boss", "Finalize__Q3_2nn4boss7StorageFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::Exist, "nn_boss", "Exist__Q3_2nn4boss7StorageCFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::GetDataList, "nn_boss", "GetDataList__Q3_2nn4boss7StorageCFPQ3_2nn4boss8DataNameUiPUiT2", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::Initialize, "nn_boss", "Initialize__Q3_2nn4boss7StorageFPCcUiQ3_2nn4boss11StorageKind", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::Storage::Initialize2, "nn_boss", "Initialize__Q3_2nn4boss7StorageFPCcQ3_2nn4boss11StorageKind", LogType::NN_BOSS); + + // AlmightyStorage + nn::boss::AlmightyStorage::InitVTable(); + cafeExportRegisterFunc(nn::boss::AlmightyStorage::ctor, "nn_boss", "__ct__Q3_2nn4boss15AlmightyStorageFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::AlmightyStorage::Initialize, "nn_boss", "Initialize__Q3_2nn4boss15AlmightyStorageFQ3_2nn4boss7TitleIDPCcUiQ3_2nn4boss11StorageKind", LogType::NN_BOSS); // NsData - osLib_addFunction("nn_boss", "__ct__Q3_2nn4boss6NsDataFv", nnBossNsDataExport_ct); - osLib_addFunction("nn_boss", "Initialize__Q3_2nn4boss6NsDataFRCQ3_2nn4boss7StoragePCc", nnBossNsDataExport_initialize); - osLib_addFunction("nn_boss", "DeleteRealFileWithHistory__Q3_2nn4boss6NsDataFv", nnBossNsDataExport_DeleteRealFileWithHistory); - osLib_addFunction("nn_boss", "Exist__Q3_2nn4boss6NsDataCFv", nnBossNsDataExport_Exist); - osLib_addFunction("nn_boss", "GetSize__Q3_2nn4boss6NsDataCFv", nnBossNsDataExport_getSize); - cafeExportRegisterFunc(nnBossNsData_GetCreatedTime, "nn_boss", "GetCreatedTime__Q3_2nn4boss6NsDataCFv", LogType::Placeholder); - osLib_addFunction("nn_boss", "Read__Q3_2nn4boss6NsDataFPvUi", nnBossNsDataExport_read); - osLib_addFunction("nn_boss", "Read__Q3_2nn4boss6NsDataFPLPvUi", nnBossNsDataExport_readWithSizeOut); - osLib_addFunction("nn_boss", "Seek__Q3_2nn4boss6NsDataFLQ3_2nn4boss12PositionBase", nnBossNsDataExport_seek); - + nn::boss::NsData::InitVTable(); + cafeExportRegisterFunc(nn::boss::NsData::ctor, "nn_boss", "__ct__Q3_2nn4boss6NsDataFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::dtor, "nn_boss", "__dt__Q3_2nn4boss6NsDataFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::Initialize, "nn_boss", "Initialize__Q3_2nn4boss6NsDataFRCQ3_2nn4boss7StoragePCc", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::DeleteRealFileWithHistory, "nn_boss", "DeleteRealFileWithHistory__Q3_2nn4boss6NsDataFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::Exist, "nn_boss", "Exist__Q3_2nn4boss6NsDataCFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::GetSize, "nn_boss", "GetSize__Q3_2nn4boss6NsDataCFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::GetCreatedTime, "nn_boss", "GetCreatedTime__Q3_2nn4boss6NsDataCFv", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::Read, "nn_boss", "Read__Q3_2nn4boss6NsDataFPvUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::ReadWithSizeOut, "nn_boss", "Read__Q3_2nn4boss6NsDataFPLPvUi", LogType::NN_BOSS); + cafeExportRegisterFunc(nn::boss::NsData::Seek, "nn_boss", "Seek__Q3_2nn4boss6NsDataFLQ3_2nn4boss12PositionBase", LogType::NN_BOSS); } diff --git a/src/Cemu/Logging/CemuLogging.cpp b/src/Cemu/Logging/CemuLogging.cpp index 6d596acf..058ab07a 100644 --- a/src/Cemu/Logging/CemuLogging.cpp +++ b/src/Cemu/Logging/CemuLogging.cpp @@ -44,6 +44,7 @@ const std::map<LogType, std::string> g_logging_window_mapping {LogType::CoreinitThread, "Coreinit Thread"}, {LogType::NN_NFP, "nn::nfp"}, {LogType::NN_FP, "nn::fp"}, + {LogType::NN_BOSS, "nn::boss"}, {LogType::GX2, "GX2"}, {LogType::SoundAPI, "Audio"}, {LogType::InputAPI, "Input"}, diff --git a/src/Cemu/Logging/CemuLogging.h b/src/Cemu/Logging/CemuLogging.h index bbffd164..fe74a6bc 100644 --- a/src/Cemu/Logging/CemuLogging.h +++ b/src/Cemu/Logging/CemuLogging.h @@ -35,6 +35,7 @@ enum class LogType : sint32 NN_OLV = 23, NN_NFP = 13, NN_FP = 24, + NN_BOSS = 25, TextureReadback = 29, diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 023918bd..4d2fb478 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -2232,6 +2232,7 @@ void MainWindow::RecreateMenu() debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::CoreinitThread), _("&Coreinit Thread API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::CoreinitThread)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::NN_NFP), _("&NN NFP"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::NN_NFP)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::NN_FP), _("&NN FP"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::NN_FP)); + debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::NN_BOSS), _("&NN BOSS"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::NN_BOSS)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::GX2), _("&GX2 API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::GX2)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::SoundAPI), _("&Audio API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::SoundAPI)); debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::InputAPI), _("&Input API"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::InputAPI));