add dump options, allow for gamecard menu to be accessed without install enabled.
This commit is contained in:
@@ -115,6 +115,7 @@ public:
|
||||
static void DisplayMiscOptions(bool left_side = true);
|
||||
static void DisplayAdvancedOptions(bool left_side = true);
|
||||
static void DisplayInstallOptions(bool left_side = true);
|
||||
static void DisplayDumpOptions(bool left_side = true);
|
||||
|
||||
void Draw();
|
||||
void Update();
|
||||
@@ -252,6 +253,12 @@ public:
|
||||
option::OptionBool m_lower_master_key{INI_SECTION, "lower_master_key", false};
|
||||
option::OptionBool m_lower_system_version{INI_SECTION, "lower_system_version", false};
|
||||
|
||||
// dump options
|
||||
option::OptionBool m_dump_app_folder{"dump", "app_folder", true};
|
||||
option::OptionBool m_dump_append_folder_with_xci{"dump", "append_folder_with_xci", true};
|
||||
option::OptionBool m_dump_trim_xci{"dump", "trim_xci", false};
|
||||
option::OptionBool m_dump_usb_transfer_stream{"dump", "usb_transfer_stream", true};
|
||||
|
||||
// todo: move this into it's own menu
|
||||
option::OptionLong m_text_scroll_speed{"accessibility", "text_scroll_speed", 1}; // normal
|
||||
|
||||
|
||||
@@ -1590,6 +1590,10 @@ void App::DisplayAdvancedOptions(bool left_side) {
|
||||
options->Add(std::make_shared<ui::SidebarEntryCallback>("Install options"_i18n, [left_side](){
|
||||
App::DisplayInstallOptions(left_side);
|
||||
}));
|
||||
|
||||
options->Add(std::make_shared<ui::SidebarEntryCallback>("Dump options"_i18n, [left_side](){
|
||||
App::DisplayDumpOptions(left_side);
|
||||
}));
|
||||
}
|
||||
|
||||
void App::DisplayInstallOptions(bool left_side) {
|
||||
@@ -1681,6 +1685,27 @@ void App::DisplayInstallOptions(bool left_side) {
|
||||
}));
|
||||
}
|
||||
|
||||
void App::DisplayDumpOptions(bool left_side) {
|
||||
auto options = std::make_shared<ui::Sidebar>("Dump Options"_i18n, left_side ? ui::Sidebar::Side::LEFT : ui::Sidebar::Side::RIGHT);
|
||||
ON_SCOPE_EXIT(App::Push(options));
|
||||
|
||||
options->Add(std::make_shared<ui::SidebarEntryBool>("Created nested folder"_i18n, App::GetApp()->m_dump_app_folder.Get(), [](bool& enable){
|
||||
App::GetApp()->m_dump_app_folder.Set(enable);
|
||||
}));
|
||||
|
||||
options->Add(std::make_shared<ui::SidebarEntryBool>("Append folder with .xci"_i18n, App::GetApp()->m_dump_append_folder_with_xci.Get(), [](bool& enable){
|
||||
App::GetApp()->m_dump_append_folder_with_xci.Set(enable);
|
||||
}));
|
||||
|
||||
options->Add(std::make_shared<ui::SidebarEntryBool>("Trim XCI"_i18n, App::GetApp()->m_dump_trim_xci.Get(), [](bool& enable){
|
||||
App::GetApp()->m_dump_trim_xci.Set(enable);
|
||||
}));
|
||||
|
||||
options->Add(std::make_shared<ui::SidebarEntryBool>("Multi-threaded USB transfer"_i18n, App::GetApp()->m_dump_usb_transfer_stream.Get(), [](bool& enable){
|
||||
App::GetApp()->m_dump_usb_transfer_stream.Set(enable);
|
||||
}));
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
log_write("starting to exit\n");
|
||||
|
||||
|
||||
@@ -410,7 +410,11 @@ Result DumpNspToUsbS2S(ProgressBox* pbox, std::span<NspEntry> entries) {
|
||||
while (!pbox->ShouldExit()) {
|
||||
if (R_SUCCEEDED(usb->IsUsbConnected(timeout))) {
|
||||
pbox->NewTransfer("USB connected, sending file list");
|
||||
const u8 flags = usb::tinfoil::USBFlag_STREAM;
|
||||
u8 flags = usb::tinfoil::USBFlag_NONE;
|
||||
if (App::GetApp()->m_dump_usb_transfer_stream.Get()) {
|
||||
flags |= usb::tinfoil::USBFlag_STREAM;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(usb->WaitForConnection(timeout, flags, file_list))) {
|
||||
pbox->NewTransfer("Sent file list, waiting for command...");
|
||||
|
||||
@@ -740,7 +744,12 @@ auto BuildNspPath(const Entry& e, const NsApplicationContentMetaStatus& status)
|
||||
}
|
||||
|
||||
fs::FsPath path;
|
||||
std::snprintf(path, sizeof(path), "%s/%s %s[%016lX][v%u][%s].nsp", name_buf.s, name_buf.s, version, status.application_id, status.version, ncm::GetMetaTypeShortStr(status.meta_type));
|
||||
if (App::GetApp()->m_dump_app_folder.Get()) {
|
||||
std::snprintf(path, sizeof(path), "%s/%s %s[%016lX][v%u][%s].nsp", name_buf.s, name_buf.s, version, status.application_id, status.version, ncm::GetMetaTypeShortStr(status.meta_type));
|
||||
} else {
|
||||
std::snprintf(path, sizeof(path), "%s %s[%016lX][v%u][%s].nsp", name_buf.s, version, status.application_id, status.version, ncm::GetMetaTypeShortStr(status.meta_type));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -1117,6 +1126,10 @@ Menu::Menu() : grid::Menu{"Games"_i18n} {
|
||||
}, true));
|
||||
}, true));
|
||||
|
||||
options->Add(std::make_shared<SidebarEntryCallback>("Dump options"_i18n, [this](){
|
||||
App::DisplayDumpOptions(false);
|
||||
}));
|
||||
|
||||
// completely deletes the application record and all data.
|
||||
options->Add(std::make_shared<SidebarEntryCallback>("Delete"_i18n, [this](){
|
||||
const auto buf = "Are you sure you want to delete "_i18n + m_entries[m_index].GetName() + "?";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "ui/nvg_util.hpp"
|
||||
#include "ui/sidebar.hpp"
|
||||
#include "ui/popup_list.hpp"
|
||||
#include "ui/option_box.hpp"
|
||||
|
||||
#include "yati/yati.hpp"
|
||||
#include "yati/nx/nca.hpp"
|
||||
@@ -150,7 +151,15 @@ auto BuildFilePath(DumpFileType type, std::span<const ApplicationEntry> entries)
|
||||
// builds path suiteable for file dumps.
|
||||
auto BuildFullDumpPath(DumpFileType type, std::span<const ApplicationEntry> entries) -> fs::FsPath {
|
||||
const auto base_path = BuildXciBasePath(entries);
|
||||
return base_path + "/" + base_path + GetDumpTypeStr(type);
|
||||
if (App::GetApp()->m_dump_app_folder.Get()) {
|
||||
if (App::GetApp()->m_dump_append_folder_with_xci.Get()) {
|
||||
return base_path + ".xci/" + base_path + GetDumpTypeStr(type);
|
||||
} else {
|
||||
return base_path + "/" + base_path + GetDumpTypeStr(type);
|
||||
}
|
||||
} else {
|
||||
return base_path + GetDumpTypeStr(type);
|
||||
}
|
||||
}
|
||||
|
||||
// @Gc is the mount point, S is for secure partion, the remaining is the
|
||||
@@ -397,7 +406,11 @@ Result DumpNspToUsbS2S(ProgressBox* pbox, std::span<const fs::FsPath> paths, Xci
|
||||
while (!pbox->ShouldExit()) {
|
||||
if (R_SUCCEEDED(usb->IsUsbConnected(timeout))) {
|
||||
pbox->NewTransfer("USB connected, sending file list");
|
||||
const u8 flags = usb::tinfoil::USBFlag_STREAM;
|
||||
u8 flags = usb::tinfoil::USBFlag_NONE;
|
||||
if (App::GetApp()->m_dump_usb_transfer_stream.Get()) {
|
||||
flags |= usb::tinfoil::USBFlag_STREAM;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(usb->WaitForConnection(timeout, flags, file_list))) {
|
||||
pbox->NewTransfer("Sent file list, waiting for command...");
|
||||
|
||||
@@ -636,7 +649,16 @@ Menu::Menu() : MenuBase{"GameCard"_i18n} {
|
||||
SetPop();
|
||||
}}),
|
||||
std::make_pair(Button::X, Action{"Options"_i18n, [this](){
|
||||
App::DisplayInstallOptions(false);
|
||||
auto options = std::make_shared<Sidebar>("Game Options"_i18n, Sidebar::Side::RIGHT);
|
||||
ON_SCOPE_EXIT(App::Push(options));
|
||||
|
||||
options->Add(std::make_shared<SidebarEntryCallback>("Install options"_i18n, [this](){
|
||||
App::DisplayInstallOptions(false);
|
||||
}));
|
||||
|
||||
options->Add(std::make_shared<SidebarEntryCallback>("Dump options"_i18n, [this](){
|
||||
App::DisplayDumpOptions(false);
|
||||
}));
|
||||
}})
|
||||
);
|
||||
|
||||
@@ -875,16 +897,24 @@ Result Menu::GcMount() {
|
||||
}
|
||||
|
||||
if (m_option_index == 0) {
|
||||
App::Push(std::make_shared<ui::ProgressBox>(m_icon, "Installing "_i18n, m_entries[m_entry_index].lang_entry.name, [this](auto pbox) -> Result {
|
||||
auto source = std::make_shared<GcSource>(m_entries[m_entry_index], m_fs.get());
|
||||
return yati::InstallFromCollections(pbox, source, source->m_collections, source->m_config);
|
||||
}, [this](Result rc){
|
||||
App::PushErrorBox(rc, "Gc install failed"_i18n);
|
||||
if (!App::GetInstallEnable()) {
|
||||
App::Push(std::make_shared<ui::OptionBox>(
|
||||
"Install disabled...\n"
|
||||
"Please enable installing via the install options."_i18n,
|
||||
"OK"_i18n
|
||||
));
|
||||
} else {
|
||||
App::Push(std::make_shared<ui::ProgressBox>(m_icon, "Installing "_i18n, m_entries[m_entry_index].lang_entry.name, [this](auto pbox) -> Result {
|
||||
auto source = std::make_shared<GcSource>(m_entries[m_entry_index], m_fs.get());
|
||||
return yati::InstallFromCollections(pbox, source, source->m_collections, source->m_config);
|
||||
}, [this](Result rc){
|
||||
App::PushErrorBox(rc, "Gc install failed"_i18n);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
App::Notify("Gc install success!"_i18n);
|
||||
}
|
||||
}));
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
App::Notify("Gc install success!"_i18n);
|
||||
}
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
auto options = std::make_shared<Sidebar>("Select content to dump"_i18n, Sidebar::Side::RIGHT);
|
||||
ON_SCOPE_EXIT(App::Push(options));
|
||||
@@ -1206,8 +1236,7 @@ void Menu::DumpGames(u32 flags) {
|
||||
|
||||
std::vector<fs::FsPath> paths;
|
||||
if (flags & DumpFileFlag_XCI) {
|
||||
// todo: add config support for full and trimmed.
|
||||
if (1) {
|
||||
if (App::GetApp()->m_dump_trim_xci.Get()) {
|
||||
entry.xci_size = m_storage_trimmed_size;
|
||||
paths.emplace_back(BuildFullDumpPath(DumpFileType_TrimmedXCI, m_entries));
|
||||
} else {
|
||||
|
||||
@@ -43,7 +43,7 @@ const MiscMenuEntry MISC_MENU_ENTRIES[] = {
|
||||
{ .name = "GitHub", .title = "GitHub", .func = MiscMenuFuncGenerator<ui::menu::gh::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||
{ .name = "FTP", .title = "FTP Install", .func = MiscMenuFuncGenerator<ui::menu::ftp::Menu>, .flag = MiscMenuFlag_Install },
|
||||
{ .name = "USB", .title = "USB Install", .func = MiscMenuFuncGenerator<ui::menu::usb::Menu>, .flag = MiscMenuFlag_Install },
|
||||
{ .name = "GameCard", .title = "GameCard Install", .func = MiscMenuFuncGenerator<ui::menu::gc::Menu>, .flag = MiscMenuFlag_Shortcut|MiscMenuFlag_Install },
|
||||
{ .name = "GameCard", .title = "GameCard", .func = MiscMenuFuncGenerator<ui::menu::gc::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||
{ .name = "IRS", .title = "IRS (Infrared Joycon Camera)", .func = MiscMenuFuncGenerator<ui::menu::irs::Menu>, .flag = MiscMenuFlag_Shortcut },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user