Skip to content

Commit

Permalink
Cache homebrew NACP too
Browse files Browse the repository at this point in the history
  • Loading branch information
XorTroll committed Jun 28, 2023
1 parent 4970c00 commit 9f8ca25
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 59 deletions.
3 changes: 2 additions & 1 deletion libs/uCommon/include/ul/cfg/cfg_Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ namespace ul::cfg {
return JoinPath(TitleCachePath, util::FormatProgramId(app_id) + ".jpg");
}

std::string GetHomebrewCacheIconPath(const std::string &path);
std::string GetHomebrewCacheIconPath(const std::string &nro_path);
std::string GetHomebrewCacheNacpPath(const std::string &nro_path);

}
85 changes: 44 additions & 41 deletions libs/uCommon/source/ul/cfg/cfg_Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,31 @@ namespace ul::cfg {

NacpStruct g_DefaultHomebrewNacp = {};

std::string GetHomebrewCachePath(const std::string &nro_path, const std::string &ext) {
char path_copy[FS_MAX_PATH] = {};
strcpy(path_copy, nro_path.c_str());
u8 hash[SHA256_HASH_SIZE] = {};
sha256CalculateHash(hash, path_copy, FS_MAX_PATH);

std::stringstream strm;
strm << HomebrewCachePath << "/";
// Use the first half of the hash, like N does with NCAs
for(u32 i = 0; i < sizeof(hash) / 2; i++) {
strm << std::setw(2) << std::setfill('0') << std::hex << std::nouppercase << static_cast<u32>(hash[i]);
}
strm << "." << ext;
return strm.str();
}

void CacheHomebrewEntry(const std::string &nro_path) {
const auto cache_nro_icon_path = GetHomebrewCacheIconPath(nro_path);
if(fs::ExistsFile(cache_nro_icon_path)) {
// Since the cache icon filename is the SHA256 of the NRO, we know it's already cached
// (if the NRO were to have a different ico the SHA256 would also be different)
const auto cache_nro_nacp_path = GetHomebrewCacheNacpPath(nro_path);
if(fs::ExistsFile(cache_nro_icon_path) && fs::ExistsFile(cache_nro_nacp_path)) {
// Since the cache icon/nacp filename is the SHA256 of the NRO, we know it's already cached
// (if the NRO were to have a different icon/nacp the SHA256 would also be different)
return;
}

// TODONEW: cache nacp too?

auto f = fopen(nro_path.c_str(), "rb");
if(f) {
if(fseek(f, sizeof(NroStart), SEEK_SET) == 0) {
Expand All @@ -29,7 +44,7 @@ namespace ul::cfg {
NroAssetHeader asset_header = {};
if(fread(&asset_header, sizeof(asset_header), 1, f) == 1) {
if(asset_header.magic == NROASSETHEADER_MAGIC) {
if((asset_header.icon.offset > 0) && (asset_header.icon.size > 0)) {
if(!fs::ExistsFile(cache_nro_icon_path) && (asset_header.icon.offset > 0) && (asset_header.icon.size > 0)) {
auto icon_buf = new u8[asset_header.icon.size]();
if(fseek(f, header.size + asset_header.icon.offset, SEEK_SET) == 0) {
if(fread(icon_buf, asset_header.icon.size, 1, f) == 1) {
Expand All @@ -38,6 +53,15 @@ namespace ul::cfg {
}
delete[] icon_buf;
}
if(!fs::ExistsFile(cache_nro_nacp_path) && (asset_header.nacp.offset > 0) && (asset_header.nacp.size > 0)) {
auto nacp_buf = new u8[asset_header.nacp.size]();
if(fseek(f, header.size + asset_header.nacp.offset, SEEK_SET) == 0) {
if(fread(nacp_buf, asset_header.nacp.size, 1, f) == 1) {
fs::WriteFile(cache_nro_nacp_path, nacp_buf, asset_header.nacp.size, true);
}
}
delete[] nacp_buf;
}
}
}
}
Expand Down Expand Up @@ -96,32 +120,19 @@ namespace ul::cfg {

void EnsureLoadDefaultHomebrewNacp() {
if(g_DefaultHomebrewNacp.display_version[0] == 0) {
fs::ReadFile(DefaultHomebrewNacpPath, &g_DefaultHomebrewNacp, sizeof(g_DefaultHomebrewNacp));
UL_ASSERT_TRUE(fs::ReadFile(DefaultHomebrewNacpPath, &g_DefaultHomebrewNacp, sizeof(g_DefaultHomebrewNacp)));
}
}

void LoadHomebrewControlData(const std::string &nro_path, TitleControlData &out_control) {
auto loaded = false;
auto f = fopen(nro_path.c_str(), "rb");
if(f) {
fseek(f, sizeof(NroStart), SEEK_SET);
NroHeader hdr = {};
if(fread(&hdr, 1, sizeof(NroHeader), f) == sizeof(NroHeader)) {
fseek(f, hdr.size, SEEK_SET);
NroAssetHeader ahdr = {};
if(fread(&ahdr, 1, sizeof(NroAssetHeader), f) == sizeof(NroAssetHeader)) {
if(ahdr.magic == NROASSETHEADER_MAGIC) {
if(ahdr.nacp.size > 0) {
NacpStruct nacp = {};
fseek(f, hdr.size + ahdr.nacp.offset, SEEK_SET);
fread(&nacp, 1, ahdr.nacp.size, f);
ProcessControlDataStrings(out_control, &nacp);
loaded = true;
}
}
}
}
fclose(f);

const auto cache_nacp_path = GetHomebrewCacheNacpPath(nro_path);
if(fs::ExistsFile(cache_nacp_path)) {
NacpStruct nacp = {};
UL_ASSERT_TRUE(fs::ReadFile(cache_nacp_path, &nacp, sizeof(nacp)));
ProcessControlDataStrings(out_control, &nacp);
loaded = true;
}
if(!loaded) {
// Default NACP strings
Expand All @@ -132,7 +143,7 @@ namespace ul::cfg {

void LoadApplicationControlData(const u64 app_id, TitleControlData &out_control) {
auto tmp_control_data = new NsApplicationControlData();
nsGetApplicationControlData(NsApplicationControlSource_Storage, app_id, tmp_control_data, sizeof(NsApplicationControlData), nullptr);
UL_RC_ASSERT(nsGetApplicationControlData(NsApplicationControlSource_Storage, app_id, tmp_control_data, sizeof(NsApplicationControlData), nullptr));
ProcessControlDataStrings(out_control, &tmp_control_data->nacp);
}

Expand Down Expand Up @@ -669,19 +680,11 @@ namespace ul::cfg {
}

std::string GetHomebrewCacheIconPath(const std::string &nro_path) {
char path_copy[FS_MAX_PATH] = {};
strcpy(path_copy, nro_path.c_str());
u8 hash[0x20] = {0};
sha256CalculateHash(hash, path_copy, FS_MAX_PATH);

std::stringstream strm;
strm << HomebrewCachePath << "/";
// Use the first half of the hash, like N does with NCAs.
for(u32 i = 0; i < sizeof(hash) / 2; i++) {
strm << std::setw(2) << std::setfill('0') << std::hex << std::nouppercase << static_cast<u32>(hash[i]);
}
strm << ".jpg";
return strm.str();
return GetHomebrewCachePath(nro_path, "jpg");
}

std::string GetHomebrewCacheNacpPath(const std::string &nro_path) {
return GetHomebrewCachePath(nro_path, "nacp");
}

}
17 changes: 0 additions & 17 deletions projects/uMenu/source/ul/menu/ui/ui_MainMenuLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ extern char g_FwVersion[0x18];

#define MENU_HBMENU_NRO "sdmc:/hbmenu.nro"

#define DEBUG_LOG(fmt, ...) ({ \
auto f = fopen("sdmc:/ulaunch/umenu-tmp.log", "ab+"); \
if(f) { \
fprintf(f, fmt "\n", ##__VA_ARGS__); \
fclose(f); \
} \
})

namespace ul::menu::ui {

namespace {
Expand Down Expand Up @@ -690,18 +682,15 @@ namespace ul::menu::ui {
if(this->items_menu->IsSuspendedItemSelected() && (this->suspended_screen_alpha <= this->min_alpha)) {
this->suspended_screen_alpha = this->min_alpha;
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
DEBUG_LOG("now focused from startshow");
this->mode = SuspendedImageMode::Focused;
}
else if(!this->items_menu->IsSuspendedItemSelected() && (this->suspended_screen_alpha == 0)) {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
DEBUG_LOG("now not focused from startshow");
this->mode = SuspendedImageMode::NotFocused;
}
else {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
this->suspended_screen_alpha -= SuspendedScreenAlphaIncrement;
DEBUG_LOG("startshow alpha: %d -> %d", this->suspended_screen_alpha + SuspendedScreenAlphaIncrement, this->suspended_screen_alpha);
if(this->suspended_screen_alpha < 0) {
this->suspended_screen_alpha = 0;
}
Expand All @@ -720,7 +709,6 @@ namespace ul::menu::ui {
else {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
this->suspended_screen_alpha += SuspendedScreenAlphaIncrement;
DEBUG_LOG("hide alpha: %d -> %d", this->suspended_screen_alpha - SuspendedScreenAlphaIncrement, this->suspended_screen_alpha);
if(this->suspended_screen_alpha > 0xFF) {
this->suspended_screen_alpha = 0xFF;
}
Expand All @@ -733,13 +721,11 @@ namespace ul::menu::ui {
case SuspendedImageMode::ShowingGainedFocus: {
if(this->suspended_screen_alpha == this->min_alpha) {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
DEBUG_LOG("now focused from ShowingGainedFocus");
this->mode = SuspendedImageMode::Focused;
}
else {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
this->suspended_screen_alpha += SuspendedScreenAlphaIncrement;
DEBUG_LOG("reshow alpha: %d -> %d", this->suspended_screen_alpha - SuspendedScreenAlphaIncrement, this->suspended_screen_alpha);
if(this->suspended_screen_alpha > this->min_alpha) {
this->suspended_screen_alpha = this->min_alpha;
}
Expand All @@ -749,13 +735,11 @@ namespace ul::menu::ui {
case SuspendedImageMode::HidingLostFocus: {
if(this->suspended_screen_alpha == 0) {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
DEBUG_LOG("now not focus from hidelostfocus");
this->mode = SuspendedImageMode::NotFocused;
}
else {
this->suspended_screen_img->SetAlpha(this->suspended_screen_alpha);
this->suspended_screen_alpha -= SuspendedScreenAlphaIncrement;
DEBUG_LOG("hidelostfocus alpha: %d -> %d", this->suspended_screen_alpha - SuspendedScreenAlphaIncrement, this->suspended_screen_alpha);
if(this->suspended_screen_alpha < 0) {
this->suspended_screen_alpha = 0;
}
Expand Down Expand Up @@ -798,7 +782,6 @@ namespace ul::menu::ui {
if(action) {
action();
}
this->items_menu->Rewind(); // TODONEW: this was a temp fix, we shouldnt have to rewind here
this->DoMoveFolder(name);

g_MenuApplication->FadeIn();
Expand Down

0 comments on commit 9f8ca25

Please sign in to comment.