Merge branch 'master' into touch
This commit is contained in:
6
.github/workflows/build_presets.yml
vendored
6
.github/workflows/build_presets.yml
vendored
@@ -1,10 +1,6 @@
|
|||||||
name: build
|
name: build
|
||||||
|
|
||||||
on:
|
on: [push, pull_request]
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -503,8 +503,8 @@ void App::SetReplaceHbmenuEnable(bool enable) {
|
|||||||
NacpStruct actual_hbmenu_nacp;
|
NacpStruct actual_hbmenu_nacp;
|
||||||
if (R_FAILED(nro_get_nacp("/switch/hbmenu.nro", actual_hbmenu_nacp))) {
|
if (R_FAILED(nro_get_nacp("/switch/hbmenu.nro", actual_hbmenu_nacp))) {
|
||||||
App::Push(std::make_shared<ui::OptionBox>(
|
App::Push(std::make_shared<ui::OptionBox>(
|
||||||
"Failed to find /switch/hbmenu.nro\n\
|
"Failed to find /switch/hbmenu.nro\n"
|
||||||
Use the Appstore to re-install hbmenu"_i18n,
|
"Use the Appstore to re-install hbmenu"_i18n,
|
||||||
"OK"_i18n
|
"OK"_i18n
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "app.hpp"
|
#include "app.hpp"
|
||||||
#include "ui/progress_box.hpp"
|
#include "ui/progress_box.hpp"
|
||||||
#include "i18n.hpp"
|
#include "i18n.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
namespace sphaira {
|
namespace sphaira {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -191,10 +192,30 @@ struct NpdmMeta {
|
|||||||
u32 acid_size;
|
u32 acid_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NpdmAcid {
|
||||||
|
u8 rsa_sig[0x100];
|
||||||
|
u8 rsa_pub[0x100];
|
||||||
|
u32 magic; // "ACID"
|
||||||
|
u32 size;
|
||||||
|
u8 version;
|
||||||
|
u8 _0x209[0x1];
|
||||||
|
u8 _0x20A[0x2];
|
||||||
|
u32 flags;
|
||||||
|
u64 program_id_min;
|
||||||
|
u64 program_id_max;
|
||||||
|
u32 fac_offset;
|
||||||
|
u32 fac_size;
|
||||||
|
u32 sac_offset;
|
||||||
|
u32 sac_size;
|
||||||
|
u32 kac_offset;
|
||||||
|
u32 kac_size;
|
||||||
|
u8 _0x238[0x8];
|
||||||
|
};
|
||||||
|
|
||||||
struct NpdmAci0 {
|
struct NpdmAci0 {
|
||||||
u32 magic; // "ACI0"
|
u32 magic; // "ACI0"
|
||||||
u8 _0x4[0xC];
|
u8 _0x4[0xC];
|
||||||
u32 program_id;
|
u64 program_id;
|
||||||
u8 _0x18[0x8];
|
u8 _0x18[0x8];
|
||||||
u32 fac_offset;
|
u32 fac_offset;
|
||||||
u32 fac_size;
|
u32 fac_size;
|
||||||
@@ -592,25 +613,41 @@ auto romfs_build(const FileEntries& entries, u64 *out_size) -> std::vector<u8> {
|
|||||||
return buf.buf;
|
return buf.buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto npdm_patch_kc(std::vector<u8>& npdm, u32 off, u32 size, u32 bitmask, u32 value) -> bool {
|
||||||
|
const u32 pattern = BIT(bitmask) - 1;
|
||||||
|
const u32 mask = BIT(bitmask) | pattern;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < size; i += 4) {
|
||||||
|
u32 cup;
|
||||||
|
std::memcpy(&cup, npdm.data() + off + i, sizeof(cup));
|
||||||
|
if ((cup & mask) == pattern) {
|
||||||
|
cup = value | pattern;
|
||||||
|
std::memcpy(npdm.data() + off + i, &cup, sizeof(cup));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// todo: manually build npdm
|
// todo: manually build npdm
|
||||||
void patch_npdm(std::vector<u8>& npdm, const NpdmPatch& patch) {
|
void patch_npdm(std::vector<u8>& npdm, const NpdmPatch& patch) {
|
||||||
NpdmMeta meta{};
|
NpdmMeta meta{};
|
||||||
NpdmAci0 aci0{};
|
NpdmAci0 aci0{};
|
||||||
|
NpdmAcid acid{};
|
||||||
std::memcpy(&meta, npdm.data(), sizeof(meta));
|
std::memcpy(&meta, npdm.data(), sizeof(meta));
|
||||||
std::memcpy(&aci0, npdm.data() + meta.aci0_offset, sizeof(aci0));
|
std::memcpy(&aci0, npdm.data() + meta.aci0_offset, sizeof(aci0));
|
||||||
|
std::memcpy(&acid, npdm.data() + meta.acid_offset, sizeof(acid));
|
||||||
|
|
||||||
// apply patch
|
// apply patch
|
||||||
std::memcpy(npdm.data() + 0x20, &patch.title_name, sizeof(patch.title_name));
|
std::memcpy(meta.title_name, &patch.title_name, sizeof(meta.title_name));
|
||||||
std::memcpy(npdm.data() + 0x30, &patch.product_code, sizeof(patch.product_code));
|
std::memcpy(meta.product_code, &patch.product_code, sizeof(patch.product_code));
|
||||||
std::memcpy(npdm.data() + meta.aci0_offset + 0x10, &patch.tid, sizeof(patch.tid));
|
aci0.program_id = patch.tid;
|
||||||
std::memcpy(npdm.data() + meta.acid_offset + 0x210, &patch.tid, sizeof(patch.tid));
|
acid.program_id_min = patch.tid;
|
||||||
std::memcpy(npdm.data() + meta.acid_offset + 0x218, &patch.tid, sizeof(patch.tid));
|
acid.program_id_max = patch.tid;
|
||||||
|
|
||||||
// patch debug flags based on ams version
|
// patch debug flags based on ams version
|
||||||
// SEE: https://github.com/ITotalJustice/sphaira/issues/67
|
// SEE: https://github.com/ITotalJustice/sphaira/issues/67
|
||||||
// disabled as it doesn't seem to launch with ForceDebug set.
|
|
||||||
// todo: look into ams and figure out why.
|
|
||||||
#if 0
|
|
||||||
u64 ver{};
|
u64 ver{};
|
||||||
splInitialize();
|
splInitialize();
|
||||||
ON_SCOPE_EXIT(splExit());
|
ON_SCOPE_EXIT(splExit());
|
||||||
@@ -618,20 +655,14 @@ void patch_npdm(std::vector<u8>& npdm, const NpdmPatch& patch) {
|
|||||||
splGetConfig(SplConfigItem_ExosphereVersion, &ver);
|
splGetConfig(SplConfigItem_ExosphereVersion, &ver);
|
||||||
ver >>= 40;
|
ver >>= 40;
|
||||||
|
|
||||||
const auto kac_offset = meta.aci0_offset + sizeof(aci0) + aci0.kac_offset;
|
if (ver >= MAKEHOSVERSION(1,7,1)) {
|
||||||
|
npdm_patch_kc(npdm, meta.aci0_offset + aci0.kac_offset, aci0.kac_size, 16, BIT(19));
|
||||||
for (u32 i = 0; i < aci0.kac_size; i += 4) {
|
npdm_patch_kc(npdm, meta.acid_offset + acid.kac_offset, acid.kac_size, 16, BIT(19));
|
||||||
u32 cup;
|
|
||||||
std::memcpy(&cup, npdm.data() + kac_offset + i, sizeof(cup));
|
|
||||||
if ((cup & 0x1FFFF) == 0xFFFF) {
|
|
||||||
if (ver >= MAKEHOSVERSION(1,7,1) && hosversionAtLeast(1, 9, 0)) {
|
|
||||||
cup = BIT(19) | 0xFFFF; // ForceDebug
|
|
||||||
}
|
|
||||||
std::memcpy(npdm.data() + kac_offset + i, &cup, sizeof(cup));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
std::memcpy(npdm.data(), &meta, sizeof(meta));
|
||||||
|
std::memcpy(npdm.data() + meta.aci0_offset, &aci0, sizeof(aci0));
|
||||||
|
std::memcpy(npdm.data() + meta.acid_offset, &acid, sizeof(acid));
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_nacp(NacpStruct& nacp, const NcapPatch& patch) {
|
void patch_nacp(NacpStruct& nacp, const NcapPatch& patch) {
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ void Menu::SetIndex(std::size_t index) {
|
|||||||
// log_write("name: %s hbini.ts: %lu file.ts: %lu smaller: %s\n", e.GetName(), e.hbini.timestamp, e.timestamp.modified, e.hbini.timestamp < e.timestamp.modified ? "true" : "false");
|
// log_write("name: %s hbini.ts: %lu file.ts: %lu smaller: %s\n", e.GetName(), e.hbini.timestamp, e.timestamp.modified, e.hbini.timestamp < e.timestamp.modified ? "true" : "false");
|
||||||
|
|
||||||
SetTitleSubHeading(m_entries[m_index].path);
|
SetTitleSubHeading(m_entries[m_index].path);
|
||||||
this->SetSubHeading(std::to_string(m_index + 1) + " / " + std::to_string(m_entries.size()) + " " + std::to_string(m_start));
|
this->SetSubHeading(std::to_string(m_index + 1) + " / " + std::to_string(m_entries.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::InstallHomebrew() {
|
void Menu::InstallHomebrew() {
|
||||||
|
|||||||
Reference in New Issue
Block a user