-
-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nn_idb: Implement icon database reading
- Loading branch information
Showing
6 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#pragma once | ||
|
||
/** | ||
* \defgroup nn_idb nn_idb | ||
*/ | ||
|
||
#include <nn/idb/idb_cpp.h> | ||
#include <nn/idb/IDBReader.h> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
|
||
#include <cstdio> | ||
#include <nn/idb/idb_cpp.h> | ||
#include <nn/result.h> | ||
#include <string> | ||
|
||
namespace nn::idb { | ||
class IDBReader { | ||
public: | ||
IDBReader() = default; | ||
|
||
~IDBReader(); | ||
|
||
nn::Result LoadIconDataFromIdb(uint64_t titleId, nn::idb::IconDataRaw &iconData) const; | ||
|
||
bool SearchFromDataBase(nn::idb::IconDataKey &key, uint32_t &outIndex) const; | ||
|
||
bool LoadIconDataFromDatabase(uint32_t index, nn::idb::IconDataRaw &iconData) const; | ||
|
||
bool LoadIconData(uint64_t titleId, uint32_t u1, nn::idb::IconDataRaw &iconData) const; | ||
|
||
/** | ||
* Initializes the IDBReader from a custom path | ||
* @param path Path to "BaristaIconDataBase.dat" | ||
* @return true on success, false on error | ||
*/ | ||
bool Initialize(const std::string &path); | ||
|
||
/** | ||
* Initializes the IDBReader to read icons from the Wii U Menu icon cache | ||
* (fs:/vol/storage_mlc01/usr/save/%08X/%08X/user/common/BaristaIconDataBase.dat) | ||
* @return true on success, false on error | ||
*/ | ||
bool Initialize(); | ||
|
||
void Finalize(); | ||
|
||
private: | ||
bool InitializeFile(); | ||
|
||
void FinalizeFile(); | ||
|
||
int LoadFromFile(void *buffer, uint32_t size, uint32_t offset) const; | ||
|
||
std::string mPath = {}; | ||
FileHeader *mFileHeader = {}; | ||
FILE *mFile = {}; | ||
bool mInitDone = false; | ||
}; | ||
} // namespace nn::idb | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
|
||
#include <wut.h> | ||
#include <cstdint> | ||
|
||
namespace nn::idb { | ||
struct WUT_PACKED FileHeaderEntry { | ||
uint64_t titleId; | ||
uint32_t u1; | ||
WUT_UNKNOWN_BYTES(0xC); | ||
}; | ||
WUT_CHECK_SIZE(FileHeaderEntry, 0x18); | ||
WUT_CHECK_OFFSET(FileHeaderEntry, 0x00, titleId); | ||
WUT_CHECK_OFFSET(FileHeaderEntry, 0x08, u1); | ||
|
||
struct WUT_PACKED FileHeader { | ||
uint32_t version; | ||
FileHeaderEntry entries[300]; | ||
}; | ||
WUT_CHECK_SIZE(FileHeader, 0x1c24); | ||
WUT_CHECK_OFFSET(FileHeader, 0x00, version); | ||
WUT_CHECK_OFFSET(FileHeader, 0x04, entries); | ||
|
||
struct WUT_PACKED IconDataKey { | ||
uint64_t titleId; | ||
uint32_t u1; // maybe some kind of filter (or version)? | ||
}; | ||
WUT_CHECK_SIZE(IconDataKey, 0xC); | ||
WUT_CHECK_OFFSET(IconDataKey, 0x00, titleId); | ||
WUT_CHECK_OFFSET(IconDataKey, 0x08, u1); | ||
|
||
struct WUT_PACKED Utf16NameBuffer { | ||
char16_t utf16Str[0x100]; | ||
}; | ||
WUT_CHECK_SIZE(Utf16NameBuffer, 0x200); | ||
WUT_CHECK_OFFSET(Utf16NameBuffer, 0x00, utf16Str); | ||
|
||
struct WUT_PACKED IconDataRaw { | ||
uint64_t titleID; | ||
WUT_UNKNOWN_BYTES(0xC); | ||
char u6[0x10]; | ||
WUT_UNKNOWN_BYTES(0xC); | ||
Utf16NameBuffer names[0xF]; | ||
WUT_UNKNOWN_BYTES(0x200); | ||
uint8_t icon[0x1002c]; | ||
WUT_UNKNOWN_BYTES(0x4); | ||
}; | ||
WUT_CHECK_SIZE(IconDataRaw, 0x12060); | ||
WUT_CHECK_OFFSET(IconDataRaw, 0x00, titleID); | ||
WUT_CHECK_OFFSET(IconDataRaw, 0x30, names); | ||
WUT_CHECK_OFFSET(IconDataRaw, 0x2030, icon); | ||
} // namespace nn::idb | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#include <malloc.h> | ||
#include <nn/idb/IDBReader.h> | ||
#include <nn/idb/idb_cpp.h> | ||
#include <sysapp/title.h> | ||
|
||
namespace nn::idb { | ||
IDBReader::~IDBReader() { | ||
Finalize(); | ||
} | ||
|
||
nn::Result IDBReader::LoadIconDataFromIdb(uint64_t titleId, IconDataRaw &iconData) const { | ||
if (!LoadIconData(titleId, 0xFFFFFFFF, iconData)) { | ||
return {Result::LEVEL_FATAL, Result::RESULT_MODULE_NN_SL, 1}; | ||
} | ||
return {{0}}; | ||
} | ||
|
||
bool IDBReader::SearchFromDataBase(IconDataKey &key, uint32_t &outIndex) const { | ||
if (!mInitDone) { | ||
return false; | ||
} | ||
int index = 0; | ||
for (const auto &entry : mFileHeader->entries) { | ||
if (entry.titleId == key.titleId && (entry.u1 == key.u1 || key.u1 == 0xFFFFFFFF)) { | ||
outIndex = index; | ||
return true; | ||
} | ||
index++; | ||
} | ||
return false; | ||
} | ||
|
||
bool IDBReader::LoadIconDataFromDatabase(uint32_t index, IconDataRaw &iconData) const { | ||
if (!mInitDone) { | ||
return false; | ||
} | ||
auto res = LoadFromFile(&iconData, sizeof(IconDataRaw), index * sizeof(IconDataRaw) + sizeof(FileHeader)); | ||
return res == sizeof(IconDataRaw); | ||
} | ||
|
||
bool IDBReader::LoadIconData(uint64_t titleId, uint32_t u1, IconDataRaw &iconData) const { | ||
if (!mInitDone) { | ||
return false; | ||
} | ||
IconDataKey dataKey = { | ||
.titleId = titleId, | ||
.u1 = u1}; | ||
uint32_t index; | ||
|
||
|
||
if (SearchFromDataBase(dataKey, index)) { | ||
return LoadIconDataFromDatabase(index, iconData); | ||
} | ||
return false; | ||
} | ||
|
||
bool IDBReader::Initialize(const std::string &path) { | ||
this->mPath = path; | ||
if (!mFileHeader) { | ||
mFileHeader = (FileHeader *) memalign(0x40, sizeof(*mFileHeader)); | ||
if (!mFileHeader) { | ||
return false; | ||
} | ||
} | ||
|
||
if (!InitializeFile()) { | ||
Finalize(); | ||
return false; | ||
} | ||
|
||
if (LoadFromFile(mFileHeader, sizeof(*mFileHeader), 0) != sizeof(*mFileHeader)) { | ||
Finalize(); | ||
return false; | ||
} | ||
if (mFileHeader->version != 0) { | ||
Finalize(); | ||
return false; | ||
} | ||
|
||
mInitDone = true; | ||
return true; | ||
} | ||
|
||
bool IDBReader::Initialize() { | ||
uint64_t menuTid = _SYSGetSystemApplicationTitleId(SYSTEM_APP_ID_WII_U_MENU); | ||
auto *menuTidPtr = (uint32_t *) menuTid; | ||
char path[90]; | ||
snprintf(path, sizeof(path), "fs:/vol/storage_mlc01/usr/save/%08X/%08X/user/common/BaristaIconDataBase.dat", menuTidPtr[0], menuTidPtr[1]); | ||
|
||
return Initialize(path); | ||
} | ||
|
||
void IDBReader::Finalize() { | ||
if (mFileHeader) { | ||
free(mFileHeader); | ||
mFileHeader = nullptr; | ||
} | ||
FinalizeFile(); | ||
mInitDone = false; | ||
} | ||
|
||
bool IDBReader::InitializeFile() { | ||
if (!mFile) { | ||
mFile = fopen(mPath.c_str(), "r"); | ||
if (!mFile) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
void IDBReader::FinalizeFile() { | ||
if (mFile) { | ||
fclose(mFile); | ||
mFile = nullptr; | ||
} | ||
} | ||
|
||
int IDBReader::LoadFromFile(void *buffer, uint32_t size, uint32_t offset) const { | ||
if (!mFile) { | ||
return 0; | ||
} | ||
size_t bytesRead; | ||
|
||
if (fseek(mFile, offset, SEEK_SET) != 0) { | ||
return false; | ||
} | ||
|
||
bytesRead = ::fread(buffer, 1, (size_t) size, mFile); | ||
|
||
if (bytesRead != size) { | ||
bytesRead = 0; | ||
} | ||
return bytesRead; | ||
} | ||
} // namespace nn::idb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters