diff --git a/include/dump_options_frame.hpp b/include/dump_options_frame.hpp index a3ce10c..0c0edf7 100644 --- a/include/dump_options_frame.hpp +++ b/include/dump_options_frame.hpp @@ -26,14 +26,7 @@ #include - - - -using namespace brls::i18n::literals; - - - - +#include "root_view.hpp" namespace nxdt::views { @@ -41,333 +34,44 @@ namespace nxdt::views { private: RootView *root_view = nullptr; - nxdt::tasks::UmsEvent::Subscription ums_task_sub; - - std::string raw_filename = ""; - std::string extension = ""; + std::string raw_filename{}, extension{}; brls::List *list = nullptr; - brls::InputListItem *filename_item = nullptr; - brls::SelectListItem *output_storage_item = nullptr; - brls::ToggleListItem *prepend_key_area_item = nullptr; - brls::ToggleListItem *keep_certificate_item = nullptr; - brls::ToggleListItem *trim_dump_item = nullptr; - brls::ToggleListItem *calculate_checksum_item = nullptr; - brls::SelectListItem *checksum_lookup_method_item = nullptr; + brls::InputListItem *filename = nullptr; + brls::SelectListItem *output_storage = nullptr; + brls::GenericEvent *button_click_event = nullptr; - std::string SanitizeFileName(void) - { - char *raw_filename_dup = nullptr; + nxdt::tasks::UmsEvent::Subscription ums_task_sub; - if (raw_filename.empty() || !(raw_filename_dup = strdup(this->raw_filename.c_str()))) return "dummy"; + bool finalized = false; - u8 selected = static_cast(this->output_storage_item ? this->output_storage_item->getSelectedValue() : configGetInteger("output_storage")); - utilsReplaceIllegalCharacters(raw_filename_dup, selected == ConfigOutputStorage_SdCard); + void Initialize(std::string& title, brls::Image *icon); - std::string output = std::string(raw_filename_dup); - free(raw_filename_dup); + std::string SanitizeUserFileName(void); - return output; - } - - void UpdateStorages(const nxdt::tasks::UmsDeviceVector& ums_devices) - { - if (!this->output_storage_item) return; - - std::vector storages{}; - - size_t elem_count = (ConfigOutputStorage_Count + ums_devices.size()); - u32 selected = this->output_storage_item->getSelectedValue(); - - /* Fill storages vector. */ - for(size_t i = 0; i < elem_count; i++) - { - if (i == 1) - { - storages.push_back("dump_options/output_storage/value_01"_i18n); - continue; - } - - u64 total_sz = 0, free_sz = 0; - char total_sz_str[64] = {0}, free_sz_str[64] = {0}; - - const nxdt::tasks::UmsDeviceVectorEntry *ums_device_entry = (i >= ConfigOutputStorage_Count ? &(ums_devices.at(i - ConfigOutputStorage_Count)) : nullptr); - const UsbHsFsDevice *cur_ums_device = (ums_device_entry ? ums_device_entry->first : nullptr); - - sprintf(total_sz_str, "%s/", cur_ums_device ? cur_ums_device->name : DEVOPTAB_SDMC_DEVICE); - utilsGetFileSystemStatsByPath(total_sz_str, &total_sz, &free_sz); - utilsGenerateFormattedSizeString(total_sz, total_sz_str, sizeof(total_sz_str)); - utilsGenerateFormattedSizeString(free_sz, free_sz_str, sizeof(free_sz_str)); - - if (cur_ums_device) - { - storages.push_back(brls::i18n::getStr("dump_options/output_storage/value_02", ums_device_entry->second, free_sz_str, total_sz_str)); - } else { - storages.push_back(brls::i18n::getStr("dump_options/output_storage/value_00", free_sz_str, total_sz_str)); - } - } - - /* Update SelectListItem values. */ - /* If the dropdown menu currently is being displayed, it'll be reloaded. */ - this->output_storage_item->updateValues(storages); - - if (selected > ConfigOutputStorage_UsbHost) - { - /* Set the SD card as the current output storage. */ - this->output_storage_item->setSelectedValue(ConfigOutputStorage_SdCard); - - /* Manually trigger selection event. */ - /* This will take care of both updating the JSON configuration and saniziting the filename provided by the user. */ - this->output_storage_item->getValueSelectedEvent()->fire(ConfigOutputStorage_SdCard); - } else { - /* Set the current output storage once more. This will make sure the selected device string gets updated. */ - this->output_storage_item->setSelectedValue(selected); - } - } + void UpdateOutputStorages(const nxdt::tasks::UmsDeviceVector& ums_devices); protected: - bool onCancel(void) override - { - /* Pop view. */ - brls::Application::popView(brls::ViewAnimation::SLIDE_RIGHT); + DumpOptionsFrame(RootView *root_view, std::string& title, std::string& raw_filename, std::string extension); + DumpOptionsFrame(RootView *root_view, std::string& title, brls::Image *icon, std::string& raw_filename, std::string extension); + ~DumpOptionsFrame(); - return true; + bool onCancel(void) override final; + + void addView(brls::View *view, bool fill = false); + + std::string GetFileName(void); + + std::string GetOutputStoragePrefix(void); + + ALWAYS_INLINE brls::GenericEvent::Subscription RegisterButtonListener(brls::GenericEvent::Callback cb) + { + return this->button_click_event->subscribe(cb); } - public: - DumpOptionsFrame(RootView *root_view, std::string title, brls::Image *icon, std::string raw_filename, std::string extension) : brls::ThumbnailFrame(), root_view(root_view), raw_filename(raw_filename), extension(extension) + ALWAYS_INLINE void UnregisterButtonListener(brls::GenericEvent::Subscription subscription) { - /* Set UI properties. */ - this->setTitle(title); - this->setIcon(icon); - - this->list = new brls::List(); - this->list->setSpacing(this->list->getSpacing() / 2); - this->list->setMarginBottom(20); - - - - - - - - - this->filename_item = new brls::InputListItem("dump_options/filename/label"_i18n, this->SanitizeFileName(), "", "dump_options/filename/description"_i18n, FS_MAX_FILENAME_LENGTH); - - this->filename_item->getClickEvent()->subscribe([this](brls::View *view) { - this->raw_filename = this->filename_item->getValue(); - this->filename_item->setValue(this->SanitizeFileName()); - }); - - this->list->addView(this->filename_item); - - - - - - - - - this->output_storage_item = new brls::SelectListItem("dump_options/output_storage/label"_i18n, { "dummy0", "dummy1" }, configGetInteger("output_storage"), - brls::i18n::getStr("dump_options/output_storage/description", GITHUB_REPOSITORY_URL)); - - /* Subscribe to SelectListItem's value selected event. */ - this->output_storage_item->getValueSelectedEvent()->subscribe([this](int selected) { - /* Make sure the current value isn't out of bounds. */ - if (selected < ConfigOutputStorage_SdCard || selected >= static_cast(this->root_view->GetUmsDevices().size() + ConfigOutputStorage_Count)) return; - - /* Update configuration. */ - if (selected == ConfigOutputStorage_SdCard || selected == ConfigOutputStorage_UsbHost) configSetInteger("output_storage", selected); - - /* Sanitize output filename for the selected storage. */ - this->filename_item->setValue(this->SanitizeFileName()); - }); - - /* Manually update output storages vector. */ - this->UpdateStorages(this->root_view->GetUmsDevices()); - - this->list->addView(this->output_storage_item); - - - - - - - /* Subscribe to the UMS device event. */ - this->ums_task_sub = this->root_view->RegisterUmsTaskListener([this](const nxdt::tasks::UmsDeviceVector& ums_devices) { - /* Update output storages vector. */ - this->UpdateStorages(ums_devices); - }); - - - - - - - - - - this->prepend_key_area_item = new brls::ToggleListItem("dump_options/prepend_key_area/label"_i18n, configGetBoolean("gamecard/prepend_key_area"), - "dump_options/prepend_key_area/description"_i18n, "generic/value_enabled"_i18n, - "generic/value_disabled"_i18n); - - this->prepend_key_area_item->getClickEvent()->subscribe([](brls::View* view) { - /* Get current value. */ - brls::ToggleListItem *item = static_cast(view); - bool value = item->getToggleState(); - - /* Update configuration. */ - configSetBoolean("gamecard/prepend_key_area", value); - - LOG_MSG_DEBUG("Prepend Key Area setting changed by user."); - }); - - this->list->addView(this->prepend_key_area_item); - - - - - - - - this->keep_certificate_item = new brls::ToggleListItem("dump_options/keep_certificate/label"_i18n, configGetBoolean("gamecard/keep_certificate"), - "dump_options/keep_certificate/description"_i18n, "generic/value_enabled"_i18n, - "generic/value_disabled"_i18n); - - this->keep_certificate_item->getClickEvent()->subscribe([](brls::View* view) { - /* Get current value. */ - brls::ToggleListItem *item = static_cast(view); - bool value = item->getToggleState(); - - /* Update configuration. */ - configSetBoolean("gamecard/keep_certificate", value); - - LOG_MSG_DEBUG("Keep certificate setting changed by user."); - }); - - this->list->addView(this->keep_certificate_item); - - - - - - - - - - this->trim_dump_item = new brls::ToggleListItem("dump_options/trim_dump/label"_i18n, configGetBoolean("gamecard/trim_dump"), - "dump_options/trim_dump/description"_i18n, "generic/value_enabled"_i18n, - "generic/value_disabled"_i18n); - - this->trim_dump_item->getClickEvent()->subscribe([](brls::View* view) { - /* Get current value. */ - brls::ToggleListItem *item = static_cast(view); - bool value = item->getToggleState(); - - /* Update configuration. */ - configSetBoolean("gamecard/trim_dump", value); - - LOG_MSG_DEBUG("Trim dump setting changed by user."); - }); - - this->list->addView(this->trim_dump_item); - - - - - - - - - - this->calculate_checksum_item = new brls::ToggleListItem("dump_options/calculate_checksum/label"_i18n, configGetBoolean("gamecard/calculate_checksum"), - "dump_options/calculate_checksum/description"_i18n, "generic/value_enabled"_i18n, - "generic/value_disabled"_i18n); - - this->calculate_checksum_item->getClickEvent()->subscribe([](brls::View* view) { - /* Get current value. */ - brls::ToggleListItem *item = static_cast(view); - bool value = item->getToggleState(); - - /* Update configuration. */ - configSetBoolean("gamecard/calculate_checksum", value); - - LOG_MSG_DEBUG("Calculate checksum setting changed by user."); - }); - - this->list->addView(this->calculate_checksum_item); - - - - - - - - - this->checksum_lookup_method_item = new brls::SelectListItem("dump_options/checksum_lookup_method/label"_i18n, { - "dump_options/checksum_lookup_method/value_00"_i18n, - "NSWDB", - "No-Intro" - }, configGetInteger("gamecard/checksum_lookup_method"), - brls::i18n::getStr("dump_options/checksum_lookup_method/description", - "dump_options/calculate_checksum/label"_i18n, "NSWDB", NSWDB_XML_NAME, "No-Intro")); - - /* Subscribe to SelectListItem's value selected event. */ - this->checksum_lookup_method_item->getValueSelectedEvent()->subscribe([this](int selected) { - /* Make sure the current value isn't out of bounds. */ - if (selected < ConfigChecksumLookupMethod_None || selected >= ConfigChecksumLookupMethod_Count) return; - - /* Update configuration. */ - configSetInteger("gamecard/checksum_lookup_method", selected); - }); - - this->list->addView(this->checksum_lookup_method_item); - - - - - - - - brls::Button *button = this->getSidebar()->getButton(); - button->setLabel("dump_options/start_dump"_i18n); - button->getClickEvent()->subscribe([this](brls::View *view) { - /* Retrieve configuration values set by the user. */ - //bool prepend_key_area = this->prepend_key_area_item->getToggleState(); - //bool keep_certificate = this->keep_certificate_item->getToggleState(); - bool trim_dump = this->trim_dump_item->getToggleState(); - //bool calculate_checksum = this->calculate_checksum_item->getToggleState(); - - /* Get gamecard size. */ - u64 gc_size = 0; - if ((!trim_dump && !gamecardGetTotalSize(&gc_size)) || (trim_dump && !gamecardGetTrimmedSize(&gc_size)) || !gc_size) - { - brls::Application::notify("fail"); - } - - - - - - - /* Display update frame. */ - //brls::Application::pushView(new OptionsTabUpdateApplicationFrame(), brls::ViewAnimation::SLIDE_LEFT, false); - brls::Application::notify(fmt::format("0x{:X}", gc_size)); - }); - - - - - - - - this->setContentView(this->list); - } - - ~DumpOptionsFrame() - { - /* Unregister task listener. */ - this->root_view->UnregisterUmsTaskListener(this->ums_task_sub); + this->button_click_event->unsubscribe(subscription); } }; } diff --git a/include/gamecard_image_dump_options_frame.hpp b/include/gamecard_image_dump_options_frame.hpp new file mode 100644 index 0000000..a9b50f6 --- /dev/null +++ b/include/gamecard_image_dump_options_frame.hpp @@ -0,0 +1,45 @@ +/* + * gamecard_image_dump_options_frame.hpp + * + * Copyright (c) 2020-2024, DarkMatterCore . + * + * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool). + * + * nxdumptool is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nxdumptool is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#ifndef __GAMECARD_IMAGE_DUMP_OPTIONS_FRAME_HPP__ +#define __GAMECARD_IMAGE_DUMP_OPTIONS_FRAME_HPP__ + +#include "dump_options_frame.hpp" + +namespace nxdt::views +{ + class GameCardImageDumpOptionsFrame: public DumpOptionsFrame + { + private: + brls::ToggleListItem *prepend_key_area = nullptr; + brls::ToggleListItem *keep_certificate = nullptr; + brls::ToggleListItem *trim_dump = nullptr; + brls::ToggleListItem *calculate_checksum = nullptr; + brls::SelectListItem *checksum_lookup_method = nullptr; + + public: + GameCardImageDumpOptionsFrame(RootView *root_view, std::string title, std::string raw_filename); + }; +} + +#endif /* __GAMECARD_IMAGE_DUMP_OPTIONS_FRAME_HPP__ */ diff --git a/romfs/i18n/en-US/options_tab.json b/romfs/i18n/en-US/options_tab.json index 517b285..fd80e2a 100644 --- a/romfs/i18n/en-US/options_tab.json +++ b/romfs/i18n/en-US/options_tab.json @@ -20,12 +20,12 @@ "update_nswdb_xml": { "label": "Update NSWDB XML", - "description": "Retrieves the latest NSWDB XML, which can be optionally used to validate checksums from gamecard dumps. Requires Internet connectivity." + "description": "Retrieves the latest NSWDB XML, which can be optionally used to validate checksums from gamecard dumps. Requires an Internet connection." }, "update_app": { "label": "Update application", - "description": "Checks if an update is available in nxdumptool's GitHub repository. Requires Internet connectivity.", + "description": "Checks if an update is available in nxdumptool's GitHub repository. Requires an Internet connection.", "frame": { "please_wait": "Please wait…", "release_details": "Commit hash: {0:.7}\nRelease date: {1} UTC+0", diff --git a/source/dump_options_frame.cpp b/source/dump_options_frame.cpp new file mode 100644 index 0000000..b573c9c --- /dev/null +++ b/source/dump_options_frame.cpp @@ -0,0 +1,224 @@ +/* + * dump_options_frame.cpp + * + * Copyright (c) 2020-2024, DarkMatterCore . + * + * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool). + * + * nxdumptool is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nxdumptool is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +namespace i18n = brls::i18n; /* For getStr(). */ +using namespace i18n::literals; /* For _i18n. */ + +namespace nxdt::views +{ + DumpOptionsFrame::DumpOptionsFrame(RootView *root_view, std::string& title, std::string& raw_filename, std::string extension) : brls::ThumbnailFrame(), root_view(root_view), raw_filename(raw_filename), extension(extension) + { + /* Generate icon using the default image. */ + brls::Image *icon = new brls::Image(); + icon->setImage(BOREALIS_ASSET("icon/" APP_TITLE ".jpg")); + icon->setScaleType(brls::ImageScaleType::SCALE); + + /* Initialize the rest of the elements. */ + this->Initialize(title, icon); + } + + DumpOptionsFrame::DumpOptionsFrame(RootView *root_view, std::string& title, brls::Image *icon, std::string& raw_filename, std::string extension) : brls::ThumbnailFrame(), root_view(root_view), raw_filename(raw_filename), extension(extension) + { + /* Initialize the rest of the elements. */ + this->Initialize(title, icon); + } + + DumpOptionsFrame::~DumpOptionsFrame() + { + /* Unregister all button click event listeners. */ + this->button_click_event->unsubscribeAll(); + + /* Unregister task listener. */ + this->root_view->UnregisterUmsTaskListener(this->ums_task_sub); + } + + void DumpOptionsFrame::Initialize(std::string& title, brls::Image *icon) + { + /* Set UI properties. */ + this->setTitle(title); + this->setIcon(icon); + + /* Generate List view. */ + this->list = new brls::List(); + this->list->setSpacing(this->list->getSpacing() / 2); + this->list->setMarginBottom(20); + + /* Filename. */ + this->filename = new brls::InputListItem("dump_options/filename/label"_i18n, this->SanitizeUserFileName(), "", "dump_options/filename/description"_i18n, FS_MAX_FILENAME_LENGTH); + + this->filename->getClickEvent()->subscribe([this](brls::View *view) { + /* Sanitize the string entered by the user. */ + this->raw_filename = this->filename->getValue(); + this->filename->setValue(this->SanitizeUserFileName()); + }); + + this->list->addView(this->filename); + + /* Output storage. */ + this->output_storage = new brls::SelectListItem("dump_options/output_storage/label"_i18n, { "dummy0", "dummy1" }, configGetInteger("output_storage"), brls::i18n::getStr("dump_options/output_storage/description", GITHUB_REPOSITORY_URL)); + + this->output_storage->getValueSelectedEvent()->subscribe([this](int selected) { + /* Make sure the current value isn't out of bounds. */ + if (selected < ConfigOutputStorage_SdCard || selected >= static_cast(this->root_view->GetUmsDevices().size() + ConfigOutputStorage_Count)) return; + + /* Update configuration. */ + if (selected == ConfigOutputStorage_SdCard || selected == ConfigOutputStorage_UsbHost) configSetInteger("output_storage", selected); + + /* Sanitize output filename for the selected storage. */ + this->filename->setValue(this->SanitizeUserFileName()); + }); + + /* Manually update output storages vector. */ + this->UpdateOutputStorages(this->root_view->GetUmsDevices()); + + this->list->addView(this->output_storage); + + /* Subscribe to the UMS device event. */ + this->ums_task_sub = this->root_view->RegisterUmsTaskListener([this](const nxdt::tasks::UmsDeviceVector& ums_devices) { + /* Update output storages vector. */ + this->UpdateOutputStorages(ums_devices); + }); + + /* Start dump button. */ + brls::Button *button = this->getSidebar()->getButton(); + button->setLabel("dump_options/start_dump"_i18n); + + /* Retrieve button event pointer. */ + this->button_click_event = button->getClickEvent(); + + /* Set content view. */ + this->setContentView(this->list); + } + + std::string DumpOptionsFrame::SanitizeUserFileName(void) + { + char *raw_filename_dup = nullptr; + + if (this->raw_filename.empty() || !(raw_filename_dup = strdup(this->raw_filename.c_str()))) return "dummy"; + + u8 selected = static_cast(this->output_storage ? this->output_storage->getSelectedValue() : configGetInteger("output_storage")); + utilsReplaceIllegalCharacters(raw_filename_dup, selected == ConfigOutputStorage_SdCard); + + std::string output = std::string(raw_filename_dup); + free(raw_filename_dup); + + return output; + } + + void DumpOptionsFrame::UpdateOutputStorages(const nxdt::tasks::UmsDeviceVector& ums_devices) + { + if (!this->output_storage) return; + + std::vector storages{}; + + size_t elem_count = (ConfigOutputStorage_Count + ums_devices.size()); + u32 selected = this->output_storage->getSelectedValue(); + + /* Fill storages vector. */ + for(size_t i = 0; i < elem_count; i++) + { + if (i == 1) + { + storages.push_back("dump_options/output_storage/value_01"_i18n); + continue; + } + + u64 total_sz = 0, free_sz = 0; + char total_sz_str[64] = {0}, free_sz_str[64] = {0}; + + const nxdt::tasks::UmsDeviceVectorEntry *ums_device_entry = (i >= ConfigOutputStorage_Count ? &(ums_devices.at(i - ConfigOutputStorage_Count)) : nullptr); + const UsbHsFsDevice *cur_ums_device = (ums_device_entry ? ums_device_entry->first : nullptr); + + sprintf(total_sz_str, "%s/", cur_ums_device ? cur_ums_device->name : DEVOPTAB_SDMC_DEVICE); + utilsGetFileSystemStatsByPath(total_sz_str, &total_sz, &free_sz); + utilsGenerateFormattedSizeString(total_sz, total_sz_str, sizeof(total_sz_str)); + utilsGenerateFormattedSizeString(free_sz, free_sz_str, sizeof(free_sz_str)); + + if (cur_ums_device) + { + storages.push_back(brls::i18n::getStr("dump_options/output_storage/value_02", ums_device_entry->second, free_sz_str, total_sz_str)); + } else { + storages.push_back(brls::i18n::getStr("dump_options/output_storage/value_00", free_sz_str, total_sz_str)); + } + } + + /* Update SelectListItem values. */ + /* If the dropdown menu currently is being displayed, it'll be reloaded. */ + this->output_storage->updateValues(storages); + + if (selected > ConfigOutputStorage_UsbHost) + { + /* Set the SD card as the current output storage. */ + this->output_storage->setSelectedValue(ConfigOutputStorage_SdCard); + + /* Manually trigger selection event. */ + /* This will take care of both updating the JSON configuration and saniziting the filename provided by the user. */ + this->output_storage->getValueSelectedEvent()->fire(ConfigOutputStorage_SdCard); + } else { + /* Set the current output storage once more. This will make sure the selected device string gets updated. */ + this->output_storage->setSelectedValue(selected); + } + } + + bool DumpOptionsFrame::onCancel(void) + { + /* Pop view. */ + brls::Application::popView(brls::ViewAnimation::SLIDE_RIGHT); + return true; + } + + void DumpOptionsFrame::addView(brls::View *view, bool fill) + { + this->list->addView(view, fill); + } + + std::string DumpOptionsFrame::GetFileName(void) + { + return this->filename->getValue(); + } + + std::string DumpOptionsFrame::GetOutputStoragePrefix(void) + { + std::string prefix{}; + + u8 selected = static_cast(this->output_storage ? this->output_storage->getSelectedValue() : configGetInteger("output_storage")); + + switch(selected) + { + case ConfigOutputStorage_SdCard: + prefix = DEVOPTAB_SDMC_DEVICE "/"; + break; + case ConfigOutputStorage_UsbHost: + prefix = "/"; + break; + default: + { + const nxdt::tasks::UmsDeviceVector& ums_devices = this->root_view->GetUmsDevices(); + prefix = std::string(ums_devices.at(selected - ConfigOutputStorage_Count).first->name); + break; + } + } + + return prefix; + } +} diff --git a/source/gamecard_image_dump_options_frame.cpp b/source/gamecard_image_dump_options_frame.cpp new file mode 100644 index 0000000..d13f548 --- /dev/null +++ b/source/gamecard_image_dump_options_frame.cpp @@ -0,0 +1,137 @@ +/* + * gamecard_image_dump_options_frame.cpp + * + * Copyright (c) 2020-2024, DarkMatterCore . + * + * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool). + * + * nxdumptool is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * nxdumptool is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +namespace i18n = brls::i18n; /* For getStr(). */ +using namespace i18n::literals; /* For _i18n. */ + +namespace nxdt::views +{ + GameCardImageDumpOptionsFrame::GameCardImageDumpOptionsFrame(RootView *root_view, std::string title, std::string raw_filename) : DumpOptionsFrame(root_view, title, raw_filename, ".xci") + { + /* Prepend KeyArea data. */ + this->prepend_key_area = new brls::ToggleListItem("dump_options/prepend_key_area/label"_i18n, configGetBoolean("gamecard/prepend_key_area"), "dump_options/prepend_key_area/description"_i18n, + "generic/value_enabled"_i18n, "generic/value_disabled"_i18n); + + this->prepend_key_area->getClickEvent()->subscribe([](brls::View* view) { + /* Get current value. */ + brls::ToggleListItem *item = static_cast(view); + bool value = item->getToggleState(); + + /* Update configuration. */ + configSetBoolean("gamecard/prepend_key_area", value); + + LOG_MSG_DEBUG("Prepend Key Area setting changed by user."); + }); + + this->addView(this->prepend_key_area); + + /* Keep certificate. */ + this->keep_certificate = new brls::ToggleListItem("dump_options/keep_certificate/label"_i18n, configGetBoolean("gamecard/keep_certificate"), "dump_options/keep_certificate/description"_i18n, + "generic/value_enabled"_i18n, "generic/value_disabled"_i18n); + + this->keep_certificate->getClickEvent()->subscribe([](brls::View* view) { + /* Get current value. */ + brls::ToggleListItem *item = static_cast(view); + bool value = item->getToggleState(); + + /* Update configuration. */ + configSetBoolean("gamecard/keep_certificate", value); + + LOG_MSG_DEBUG("Keep certificate setting changed by user."); + }); + + this->addView(this->keep_certificate); + + /* Trim dump. */ + this->trim_dump = new brls::ToggleListItem("dump_options/trim_dump/label"_i18n, configGetBoolean("gamecard/trim_dump"), "dump_options/trim_dump/description"_i18n, "generic/value_enabled"_i18n, + "generic/value_disabled"_i18n); + + this->trim_dump->getClickEvent()->subscribe([](brls::View* view) { + /* Get current value. */ + brls::ToggleListItem *item = static_cast(view); + bool value = item->getToggleState(); + + /* Update configuration. */ + configSetBoolean("gamecard/trim_dump", value); + + LOG_MSG_DEBUG("Trim dump setting changed by user."); + }); + + this->addView(this->trim_dump); + + this->calculate_checksum = new brls::ToggleListItem("dump_options/calculate_checksum/label"_i18n, configGetBoolean("gamecard/calculate_checksum"), "dump_options/calculate_checksum/description"_i18n, + "generic/value_enabled"_i18n, "generic/value_disabled"_i18n); + + this->calculate_checksum->getClickEvent()->subscribe([](brls::View* view) { + /* Get current value. */ + brls::ToggleListItem *item = static_cast(view); + bool value = item->getToggleState(); + + /* Update configuration. */ + configSetBoolean("gamecard/calculate_checksum", value); + + LOG_MSG_DEBUG("Calculate checksum setting changed by user."); + }); + + this->addView(this->calculate_checksum); + + /* Checksum lookup method. */ + this->checksum_lookup_method = new brls::SelectListItem("dump_options/checksum_lookup_method/label"_i18n, { + "dump_options/checksum_lookup_method/value_00"_i18n, + "NSWDB", + "No-Intro" + }, configGetInteger("gamecard/checksum_lookup_method"), brls::i18n::getStr("dump_options/checksum_lookup_method/description", + "dump_options/calculate_checksum/label"_i18n, "NSWDB", NSWDB_XML_NAME, "No-Intro")); + + this->checksum_lookup_method->getValueSelectedEvent()->subscribe([this](int selected) { + /* Make sure the current value isn't out of bounds. */ + if (selected < ConfigChecksumLookupMethod_None || selected >= ConfigChecksumLookupMethod_Count) return; + + /* Update configuration. */ + configSetInteger("gamecard/checksum_lookup_method", selected); + }); + + this->addView(this->checksum_lookup_method); + + /* Register dump button callback. */ + this->RegisterButtonListener([this](brls::View *view) { + /* Retrieve configuration values set by the user. */ + //bool prepend_key_area = this->prepend_key_area_item->getToggleState(); + //bool keep_certificate = this->keep_certificate_item->getToggleState(); + bool trim_dump_val = this->trim_dump->getToggleState(); + //bool calculate_checksum = this->calculate_checksum_item->getToggleState(); + + /* Get gamecard size. */ + u64 gc_size = 0; + if ((!trim_dump_val && !gamecardGetTotalSize(&gc_size)) || (trim_dump_val && !gamecardGetTrimmedSize(&gc_size)) || !gc_size) + { + brls::Application::notify("fail"); + return; + } + + /* Display update frame. */ + //brls::Application::pushView(new OptionsTabUpdateApplicationFrame(), brls::ViewAnimation::SLIDE_LEFT, false); + brls::Application::notify(fmt::format("0x{:X}", gc_size)); + }); + } +} diff --git a/source/gamecard_tab.cpp b/source/gamecard_tab.cpp index e5b5766..afffbdd 100644 --- a/source/gamecard_tab.cpp +++ b/source/gamecard_tab.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace i18n = brls::i18n; /* For getStr(). */ using namespace i18n::literals; /* For _i18n. */ @@ -256,12 +256,8 @@ namespace nxdt::views brls::ListItem *dump_card_image = new brls::ListItem("gamecard_tab/list/dump_card_image/label"_i18n, "gamecard_tab/list/dump_card_image/description"_i18n); dump_card_image->getClickEvent()->subscribe([this](brls::View *view) { - brls::Image *icon = new brls::Image(); - icon->setImage(BOREALIS_ASSET("icon/" APP_TITLE ".jpg")); - icon->setScaleType(brls::ImageScaleType::SCALE); - - brls::Application::pushView(new DumpOptionsFrame(this->root_view, "gamecard_tab/list/dump_card_image/label"_i18n, icon, - configGetInteger("naming_convention") == TitleNamingConvention_Full ? raw_filename_full : raw_filename_id_only, ".xci"), brls::ViewAnimation::SLIDE_LEFT); + std::string& raw_filename = (configGetInteger("naming_convention") == TitleNamingConvention_Full ? raw_filename_full : raw_filename_id_only); + brls::Application::pushView(new GameCardImageDumpOptionsFrame(this->root_view, "gamecard_tab/list/dump_card_image/label"_i18n, raw_filename), brls::ViewAnimation::SLIDE_LEFT); }); this->list->addView(dump_card_image);