diff --git a/include/nn/sl/KillerNotification.h b/include/nn/sl/KillerNotification.h index 3840f3ac3..02da2f28e 100644 --- a/include/nn/sl/KillerNotification.h +++ b/include/nn/sl/KillerNotification.h @@ -41,7 +41,6 @@ namespace nn::sl { ANYBODY = 1 } KillerNotificationAccountMailActivation; - typedef enum KillerNotificationConjunction { AND = 0, OR = 1 diff --git a/include/nn/sl/LaunchInfoDatabase.h b/include/nn/sl/LaunchInfoDatabase.h index c6834c2c8..c100ee4c1 100644 --- a/include/nn/sl/LaunchInfoDatabase.h +++ b/include/nn/sl/LaunchInfoDatabase.h @@ -10,9 +10,22 @@ namespace nn::sl { namespace details { typedef struct WUT_PACKED LaunchInfoDatabaseInternal { - WUT_UNKNOWN_BYTES(0x1C); + uint64_t *currentIdPtr; + uint32_t *entryCountPtr; + uint32_t *maxEntriesPtr; + void *pDatabase; + LaunchInfoDatabaseEntry *entriesPtr; + LaunchInfoDatabaseEntry *systemTablePtr; + uint32_t systemTableNum; } LaunchInfoDatabaseInternal; WUT_CHECK_SIZE(LaunchInfoDatabaseInternal, 0x1C); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x00, currentIdPtr); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x04, entryCountPtr); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x08, maxEntriesPtr); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x0C, pDatabase); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x10, entriesPtr); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x14, systemTablePtr); + WUT_CHECK_OFFSET(LaunchInfoDatabaseInternal, 0x18, systemTableNum); extern "C" LaunchInfoDatabaseInternal *__ct__Q3_2nn2sl18LaunchInfoDatabaseFv(LaunchInfoDatabaseInternal *); extern "C" nn::Result Store__Q3_2nn2sl18LaunchInfoDatabaseCFRQ3_2nn2sl7IStream(LaunchInfoDatabaseInternal *, nn::sl::details::IStreamInternal *); @@ -20,6 +33,14 @@ namespace nn::sl { extern "C" nn::Result LoadInitial__Q3_2nn2sl18LaunchInfoDatabaseFUiQ3_2nn2sl6Region(LaunchInfoDatabaseInternal *, int, nn::sl::Region); extern "C" nn::Result GetLaunchInfoById__Q3_2nn2sl18LaunchInfoDatabaseCFPQ3_2nn2sl10LaunchInfoUL(LaunchInfoDatabaseInternal *, nn::sl::LaunchInfo *, uint64_t titleId); extern "C" void Finalize__Q3_2nn2sl18LaunchInfoDatabaseFv(LaunchInfoDatabaseInternal *); + extern "C" uint32_t GetEntryCount__Q3_2nn2sl18LaunchInfoDatabaseCFv(LaunchInfoDatabaseInternal *); + extern "C" void Clear__Q3_2nn2sl18LaunchInfoDatabaseFv(LaunchInfoDatabaseInternal *); + extern "C" uint64_t GetCurrentId__Q3_2nn2sl18LaunchInfoDatabaseCFv(LaunchInfoDatabaseInternal *); + extern "C" uint64_t Register__Q3_2nn2sl18LaunchInfoDatabaseFRCQ3_2nn2sl10LaunchInfo(LaunchInfoDatabaseInternal *, const nn::sl::LaunchInfo &); + extern "C" nn::Result Unregister__Q3_2nn2sl18LaunchInfoDatabaseFUL(LaunchInfoDatabaseInternal *, uint64_t); + extern "C" nn::Result __CPR84__LoadInitial__Q3_2nn2sl18LaunchInfoDatabaseFUiPCQ4_2nn2slJ22J5EntryT1(LaunchInfoDatabaseInternal *, uint32_t max_entries, nn::sl::LaunchInfoDatabaseEntry *defaultEntries, uint32_t defaultEntryNum); + extern "C" uint32_t __CPR86__ListLaunchInfos__Q3_2nn2sl18LaunchInfoDatabaseCFPQ4_2nn2slJ26J5EntryUi(LaunchInfoDatabaseInternal *, nn::sl::LaunchInfoDatabaseEntry *entriesOut, uint32_t num); + extern "C" uint32_t __CPR93__Load__Q3_2nn2sl18LaunchInfoDatabaseFRQ3_2nn2sl7IStreamPCQ4_2nn2slJ15J5EntryUi(LaunchInfoDatabaseInternal *, details::IStreamInternal *stream, nn::sl::LaunchInfoDatabaseEntry *defaultEntries, uint32_t defaultEntryNum); } // namespace details class LaunchInfoDatabase { @@ -32,6 +53,10 @@ namespace nn::sl { Finalize__Q3_2nn2sl18LaunchInfoDatabaseFv(&mInstance); } + void Finalize() { + Finalize__Q3_2nn2sl18LaunchInfoDatabaseFv(&mInstance); + } + nn::Result Load(nn::sl::details::IStreamBase &fileStream, nn::sl::Region region) { return Load__Q3_2nn2sl18LaunchInfoDatabaseFRQ3_2nn2sl7IStreamQ3_2nn2sl6Region(&mInstance, fileStream.GetInternal(), region); } @@ -40,14 +65,46 @@ namespace nn::sl { return Store__Q3_2nn2sl18LaunchInfoDatabaseCFRQ3_2nn2sl7IStream(&mInstance, fileStream.GetInternal()); } - nn::Result LoadInitial(int entryNum, nn::sl::Region region) { - return LoadInitial__Q3_2nn2sl18LaunchInfoDatabaseFUiQ3_2nn2sl6Region(&mInstance, entryNum, region); + nn::Result LoadInitial(int maxEntries, nn::sl::Region region) { + return LoadInitial__Q3_2nn2sl18LaunchInfoDatabaseFUiQ3_2nn2sl6Region(&mInstance, maxEntries, region); } nn::Result GetLaunchInfoById(nn::sl::LaunchInfo *launchInfo, uint64_t titleId) const { return GetLaunchInfoById__Q3_2nn2sl18LaunchInfoDatabaseCFPQ3_2nn2sl10LaunchInfoUL((details::LaunchInfoDatabaseInternal *) &mInstance, launchInfo, titleId); } + [[nodiscard]] uint32_t GetEntryCount() const { + return details::GetEntryCount__Q3_2nn2sl18LaunchInfoDatabaseCFv((details::LaunchInfoDatabaseInternal *) &mInstance); + } + + [[nodiscard]] uint64_t GetCurrentId() const { + return details::GetCurrentId__Q3_2nn2sl18LaunchInfoDatabaseCFv((details::LaunchInfoDatabaseInternal *) &mInstance); + } + + [[nodiscard]] uint64_t Register(const nn::sl::LaunchInfo &launchInfo) { + return details::Register__Q3_2nn2sl18LaunchInfoDatabaseFRCQ3_2nn2sl10LaunchInfo((details::LaunchInfoDatabaseInternal *) &mInstance, launchInfo); + } + + [[nodiscard]] uint64_t Unregister(const nn::sl::LaunchInfo &launchInfo, uint64_t id) { + return details::Unregister__Q3_2nn2sl18LaunchInfoDatabaseFUL((details::LaunchInfoDatabaseInternal *) &mInstance, id); + } + + void Clear() { + return details::Clear__Q3_2nn2sl18LaunchInfoDatabaseFv(&mInstance); + } + + static nn::Result LoadInitial(LaunchInfoDatabase &launchDatabase, uint32_t maxEntries, nn::sl::LaunchInfoDatabaseEntry *defaultEntries, uint32_t defaultEntryNum) { + return details::__CPR84__LoadInitial__Q3_2nn2sl18LaunchInfoDatabaseFUiPCQ4_2nn2slJ22J5EntryT1(&launchDatabase.mInstance, maxEntries, defaultEntries, defaultEntryNum); + } + + static uint32_t ListLaunchInfos(const LaunchInfoDatabase &launchDatabase, nn::sl::LaunchInfoDatabaseEntry *entriesOut, uint32_t num) { + return details::__CPR86__ListLaunchInfos__Q3_2nn2sl18LaunchInfoDatabaseCFPQ4_2nn2slJ26J5EntryUi((details::LaunchInfoDatabaseInternal *) &launchDatabase.mInstance, entriesOut, num); + } + + static uint32_t Load(LaunchInfoDatabase &launchDatabase, nn::sl::details::IStreamBase &fileStream, nn::sl::LaunchInfoDatabaseEntry *defaultEntries, uint32_t defaultEntryNum) { + return details::__CPR93__Load__Q3_2nn2sl18LaunchInfoDatabaseFRQ3_2nn2sl7IStreamPCQ4_2nn2slJ15J5EntryUi(&launchDatabase.mInstance, fileStream.GetInternal(), defaultEntries, defaultEntryNum); + } + private: details::LaunchInfoDatabaseInternal mInstance = {}; }; diff --git a/include/nn/sl/sl_cpp.h b/include/nn/sl/sl_cpp.h index a5757904e..1f30f988a 100644 --- a/include/nn/sl/sl_cpp.h +++ b/include/nn/sl/sl_cpp.h @@ -27,6 +27,33 @@ namespace nn::sl { WUT_CHECK_OFFSET(LaunchInfo, 0x0C, mediaType); WUT_CHECK_SIZE(LaunchInfo, 0x810); + typedef struct WUT_PACKED LaunchInfoDatabaseEntry { + uint64_t uuid; + LaunchInfo launchInfo; + } LaunchInfoDatabaseEntry; + WUT_CHECK_SIZE(LaunchInfoDatabaseEntry, 0x818); + WUT_CHECK_OFFSET(LaunchInfoDatabaseEntry, 0x0, uuid); + WUT_CHECK_OFFSET(LaunchInfoDatabaseEntry, 0x8, launchInfo); + + // This struct has a variable length, the hash is always expected at the end + typedef struct WUT_PACKED LaunchInfoDatabaseHeader { + uint32_t version; // 1 + uint32_t magic; // "LIDB" + uint32_t maxEntries; + uint32_t entryCount; + uint64_t currentId; // start at 0x1000000000000000 + LaunchInfoDatabaseEntry entries[0]; // Dynamic, actually this array should be entries[maxEntries] + char sha1Hash[20]; + } LaunchInfoDatabaseHeader; + WUT_CHECK_SIZE(LaunchInfoDatabaseHeader, 0x2C); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x0, version); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x4, magic); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x8, maxEntries); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0xC, entryCount); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x10, currentId); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x18, entries); + WUT_CHECK_OFFSET(LaunchInfoDatabaseHeader, 0x18, sha1Hash); + struct WUT_PACKED IconInfo { uint8_t data[65580]; // tga char name[0x80]; @@ -69,7 +96,7 @@ namespace nn::sl { uint8_t isOnDisc[10]; uint64_t killerNotificationsTitleId; uint32_t serialId; - WUT_UNKNOWN_BYTES(192); + WUT_PADDING_BYTES(192); struct { DRCImagePalette palette; uint8_t pixelIndex[206][412]; // index of color in palette