mirror of
https://github.com/devkitPro/wut.git
synced 2026-03-21 17:34:47 -05:00
nn_idb: Implement icon database reading
This commit is contained in:
parent
8e4e1cb41a
commit
f0582e2e3e
1
Makefile
1
Makefile
|
|
@ -30,6 +30,7 @@ SOURCES := cafe \
|
|||
libraries/libirc/src \
|
||||
libraries/nn_erreula \
|
||||
libraries/nn_sl \
|
||||
libraries/nn_idb \
|
||||
libraries/nn_swkbd
|
||||
DATA := data
|
||||
INCLUDES := include \
|
||||
|
|
|
|||
8
include/nn/idb.h
Normal file
8
include/nn/idb.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
/**
|
||||
* \defgroup nn_idb nn_idb
|
||||
*/
|
||||
|
||||
#include <nn/idb/idb_cpp.h>
|
||||
#include <nn/idb/IDBReader.h>
|
||||
55
include/nn/idb/IDBReader.h
Normal file
55
include/nn/idb/IDBReader.h
Normal file
|
|
@ -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
|
||||
56
include/nn/idb/idb_cpp.h
Normal file
56
include/nn/idb/idb_cpp.h
Normal file
|
|
@ -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
|
||||
136
libraries/nn_idb/IDBReader.cpp
Normal file
136
libraries/nn_idb/IDBReader.cpp
Normal file
|
|
@ -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
|
||||
|
|
@ -106,6 +106,7 @@
|
|||
#include <nn/ffl/miidata.h>
|
||||
#include <nn/hpad/beta.h>
|
||||
#include <nn/hpad/hpad.h>
|
||||
#include <nn/idb.h>
|
||||
#include <nn/nets2/somemopt.h>
|
||||
#include <nn/nfp/nfp_cpp.h>
|
||||
#include <nn/nfp/amiibo_settings_cpp.h>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user