From 601cae399f7e90d0c18650241e44b654f5aa6e0a Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Thu, 17 Jun 2021 03:55:42 -0400 Subject: [PATCH] UI changes. * GameCardTab: use fmt library to format strings. * AboutTab: finish view. --- Makefile | 2 +- include/about_tab.hpp | 24 +++++----- include/defines.h | 4 ++ include/gamecard_tab.hpp | 4 ++ libs/borealis | 2 +- romfs/i18n/en-US/about_tab.json | 21 +++++++-- source/about_tab.cpp | 77 ++++++++++++++++++--------------- source/error_frame.cpp | 2 +- source/gamecard_tab.cpp | 63 +++++++++++++-------------- 9 files changed, 113 insertions(+), 86 deletions(-) diff --git a/Makefile b/Makefile index 4c33748..f361805 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ CXXFLAGS := $(CFLAGS) -std=c++20 -O2 -Wno-volatile -Wno-unused-parameter ASFLAGS := -g $(ARCH) LDFLAGS := -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lxml2 -lz -lusbhsfs -lntfs-3g -llwext4 -lnx -ljson-c -lturbojpeg +LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lxml2 -lz -lusbhsfs -lntfs-3g -llwext4 -lnx #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/include/about_tab.hpp b/include/about_tab.hpp index a3f0edd..deee0f6 100644 --- a/include/about_tab.hpp +++ b/include/about_tab.hpp @@ -28,24 +28,12 @@ namespace nxdt::views { - /* Extended class to display a focusable (but unhighlightable) image. */ - class AboutTabLogo: public brls::Image - { - protected: - void layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash) override; - brls::View* getDefaultFocus(void); - //void onFocusGained(void); - - public: - AboutTabLogo(void); - }; - /* Extended class to display a focusable (but unhighlightable) label. */ class AboutTabLabel: public brls::Label { protected: - brls::View* getDefaultFocus(void); - //void onFocusGained(void); + brls::View* getDefaultFocus(void) override; + void onFocusGained(void) override; public: AboutTabLabel(brls::LabelStyle labelStyle, std::string text, bool center = false, bool multiline = true); @@ -53,8 +41,16 @@ namespace nxdt::views class AboutTab: public brls::List { + private: + brls::Image *logo = nullptr; + + protected: + void draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx) override; + void layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash) override; + public: AboutTab(void); + ~AboutTab(void); }; } diff --git a/include/defines.h b/include/defines.h index 03a8b38..c54a5be 100644 --- a/include/defines.h +++ b/include/defines.h @@ -74,5 +74,9 @@ #define BOREALIS_URL "https://github.com/natinusala/borealis" #define LIBUSBHSFS_URL "https://github.com/DarkMatterCore/libusbhsfs" +#define FATFS_URL "http://elm-chan.org/fsw/ff/00index_e.html" +#define LZ4_URL "https://github.com/lz4/lz4" + +#define DISCORD_SERVER_URL "https://discord.gg/SCbbcQx" #endif /* __DEFINES_H__ */ diff --git a/include/gamecard_tab.hpp b/include/gamecard_tab.hpp index 2660c62..a07b024 100644 --- a/include/gamecard_tab.hpp +++ b/include/gamecard_tab.hpp @@ -43,6 +43,8 @@ namespace nxdt::views /* Extended class to switch between ErrorFrame and List views whenever the gamecard status event is triggered. */ class GameCardTab: public brls::LayerView { + typedef bool (*GameCardSizeFunc)(u64 *size); + private: nxdt::tasks::GameCardTask *gc_status_task = nullptr; nxdt::tasks::GameCardStatusEvent::Subscription gc_status_task_sub; @@ -73,6 +75,8 @@ namespace nxdt::views void addLayerWrapper(brls::View* view); void changeLayerWrapper(brls::View* view); + + std::string GetFormattedSizeString(GameCardSizeFunc func); public: GameCardTab(nxdt::tasks::GameCardTask *gc_status_task); diff --git a/libs/borealis b/libs/borealis index 45a33d8..2351161 160000 --- a/libs/borealis +++ b/libs/borealis @@ -1 +1 @@ -Subproject commit 45a33d8a2bdb81b53378a8c6dbff1b3d6cb83ebd +Subproject commit 2351161d911d968e1374679c41cf652e7cb0dd32 diff --git a/romfs/i18n/en-US/about_tab.json b/romfs/i18n/en-US/about_tab.json index f6e4e44..42230e2 100644 --- a/romfs/i18n/en-US/about_tab.json +++ b/romfs/i18n/en-US/about_tab.json @@ -1,5 +1,20 @@ -{ +{ "description": "Nintendo Switch Dump Tool", - "copyright": "Licensed under GPLv3+\n\u00A9 2020 - 2021 {0}", - "links": "\uE016 Source code is available at: {0}.\n\uE016 {1} is powered by Borealis, a hardware-accelerated UI library: {2}.\n\uE016 USB Mass Storage device support is powered by libusbhsfs: {3}." + + "copyright": "Licensed under GPLv3+\n\u00A9 2020 - 2021 {0}\n{1}", + + "dependencies": { + "header": "Dependencies", + "value": "\uE016 {0} is powered by Borealis, a hardware-accelerated UI library: {1}.\n\uE016 USB Mass Storage device support is powered by libusbhsfs: {2}.\n\uE016 FatFs is used to mount FAT volumes from the eMMC storage: {3}.\n\uE016 LZ4 is used to decompress NSO binaries: {4}." + }, + + "acknowledgments": { + "header": "Acknowledgments", + "value": "\uE016 Switchbrew and libnx contributors.\n\uE016 SciresM, for hactool and Atmosphère-NX.\n\uE016 shchmue, for Lockpick and its runtime key-collection algorithm, as well as helping in reverse engineering tasks.\n\uE016 Adubbz, for Tinfoil and its ES service bindings.\n\uE016 RattletraPM, for the awesome icon.\n\uE016 Whovian9369, for being a key piece throughout the whole development by providing with lots of testing and cool ideas.\n\uE016 0Liam and Shadów, for their tremendous help in understanding Nintendo Switch file and data formats.\n\uE016 The folks from NSWDB.COM and No-Intro.org, for being kind enough to put up public APIs to perform online checksum lookups.\n\uE016 The folks at the nxdumptool Discord server.\n\uE016 The Comfy Boyes, for always being awesome and supportive. You know who you are.\n\uE016 My girlfriend, for always being by my side and motivating me to keep working on all my projects. I love you. \u2665\n\uE016 And, at last but not least, you! Thank you for using my work!" + }, + + "links": { + "header": "Additional links and resources", + "value": "\uE016 Discord server: {0}." + } } diff --git a/source/about_tab.cpp b/source/about_tab.cpp index 2265802..4728738 100644 --- a/source/about_tab.cpp +++ b/source/about_tab.cpp @@ -29,29 +29,6 @@ using namespace i18n::literals; /* For _i18n. */ namespace nxdt::views { - AboutTabLogo::AboutTabLogo(void) : brls::Image(BOREALIS_ASSET("icon/" APP_TITLE ".jpg")) - { - this->setScaleType(brls::ImageScaleType::NO_RESIZE); - } - - void AboutTabLogo::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash) - { - this->setBoundaries(this->x + this->width / 2 - LOGO_SIZE / 2, this->y, LOGO_SIZE, LOGO_SIZE); - brls::Image::layout(vg, style, stash); - } - - brls::View* AboutTabLogo::getDefaultFocus(void) - { - return this; - } - /* - void AboutTabLogo::onFocusGained(void) - { - this->focused = true; - this->focusEvent.fire(this); - if (this->hasParent()) this->getParent()->onChildFocusGained(this); - } - */ AboutTabLabel::AboutTabLabel(brls::LabelStyle labelStyle, std::string text, bool center, bool multiline) : brls::Label(labelStyle, text, multiline) { if (center) this->setHorizontalAlign(NVG_ALIGN_CENTER); @@ -61,40 +38,72 @@ namespace nxdt::views { return this; } - /* + void AboutTabLabel::onFocusGained(void) { this->focused = true; this->focusEvent.fire(this); if (this->hasParent()) this->getParent()->onChildFocusGained(this); } - */ + AboutTab::AboutTab(void) : brls::List() { this->setSpacing(this->getSpacing() / 2); this->setMarginBottom(20); /* Logo. */ - this->addView(new AboutTabLogo()); + this->logo = new brls::Image(BOREALIS_ASSET("icon/" APP_TITLE ".jpg")); + this->logo->setWidth(LOGO_SIZE); + this->logo->setHeight(LOGO_SIZE); + this->logo->setScaleType(brls::ImageScaleType::NO_RESIZE); + this->logo->setOpacity(0.3F); /* Description. */ - brls::Label* description = new brls::Label(brls::LabelStyle::REGULAR, "about_tab/description"_i18n, true); - description->setHorizontalAlign(NVG_ALIGN_CENTER); + AboutTabLabel* description = new AboutTabLabel(brls::LabelStyle::CRASH, "about_tab/description"_i18n, true); this->addView(description); /* Copyright. */ - brls::Label* copyright = new brls::Label(brls::LabelStyle::DESCRIPTION, i18n::getStr("about_tab/copyright"_i18n, APP_AUTHOR), true); + brls::Label* copyright = new brls::Label(brls::LabelStyle::DESCRIPTION, i18n::getStr("about_tab/copyright"_i18n, APP_AUTHOR, GITHUB_REPOSITORY_URL), true); copyright->setHorizontalAlign(NVG_ALIGN_CENTER); this->addView(copyright); - /* Links and resources. */ - this->addView(new brls::Header("Links and resources")); + /* Dependencies. */ + this->addView(new brls::Header("about_tab/dependencies/header"_i18n)); + brls::Label* dependencies = new brls::Label(brls::LabelStyle::SMALL, i18n::getStr("about_tab/dependencies/value"_i18n, APP_TITLE, BOREALIS_URL, LIBUSBHSFS_URL, FATFS_URL, LZ4_URL), true); + this->addView(dependencies); - AboutTabLabel* links = new AboutTabLabel(brls::LabelStyle::SMALL, i18n::getStr("about_tab/links"_i18n, GITHUB_REPOSITORY_URL, APP_TITLE, BOREALIS_URL, LIBUSBHSFS_URL)); + /* Acknowledgments. */ + this->addView(new brls::Header("about_tab/acknowledgments/header"_i18n)); + AboutTabLabel* acknowledgments = new AboutTabLabel(brls::LabelStyle::SMALL, "about_tab/acknowledgments/value"_i18n); + this->addView(acknowledgments); + + /* Additional links and resources. */ + this->addView(new brls::Header("about_tab/links/header"_i18n)); + AboutTabLabel* links = new AboutTabLabel(brls::LabelStyle::SMALL, i18n::getStr("about_tab/links/value"_i18n, DISCORD_SERVER_URL)); this->addView(links); + } + + AboutTab::~AboutTab(void) + { + delete this->logo; + } + + void AboutTab::draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx) + { + this->logo->frame(ctx); + brls::ScrollView::draw(vg, x, y, width, height, style, ctx); + } + + void AboutTab::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash) + { + this->logo->setBoundaries( + this->x + (this->width - this->logo->getWidth()) / 2, + this->y + (this->height - this->logo->getHeight()) / 2, + this->logo->getWidth(), + this->logo->getHeight()); + this->logo->invalidate(true); - - + brls::ScrollView::layout(vg, style, stash); } } diff --git a/source/error_frame.cpp b/source/error_frame.cpp index 18365d9..11b89eb 100644 --- a/source/error_frame.cpp +++ b/source/error_frame.cpp @@ -83,7 +83,7 @@ namespace nxdt::views this->label->invalidate(true); this->label->setBoundaries( - this->x + this->width / 2 - this->label->getWidth() / 2, + this->x + (this->width - this->label->getWidth()) / 2, this->y + (this->height - style->AppletFrame.footerHeight) / 2, this->label->getWidth(), this->label->getHeight()); diff --git a/source/gamecard_tab.cpp b/source/gamecard_tab.cpp index 2f5bbbb..2fa55de 100644 --- a/source/gamecard_tab.cpp +++ b/source/gamecard_tab.cpp @@ -27,11 +27,6 @@ using namespace i18n::literals; /* For _i18n. */ namespace nxdt::views { - static const char *GameCardCompatibilityTypeStrings[GameCardCompatibilityType_Count] = { - [GameCardCompatibilityType_Normal] = "Normal", - [GameCardCompatibilityType_Terra] = "Terra" - }; - static const char *GameCardFwVersionStrings[GameCardFwVersion_Count] = { [GameCardFwVersion_ForDev] = "1.0.0+", [GameCardFwVersion_Since100NUP] = "1.0.0+", @@ -41,6 +36,11 @@ namespace nxdt::views [GameCardFwVersion_Since1200NUP] = "12.0.0+" }; + static const char *GameCardCompatibilityTypeStrings[GameCardCompatibilityType_Count] = { + [GameCardCompatibilityType_Normal] = "Normal", + [GameCardCompatibilityType_Terra] = "Terra" + }; + GameCardTable::GameCardTable(void) : brls::Table() { } brls::View* GameCardTable::getDefaultFocus(void) @@ -125,39 +125,27 @@ namespace nxdt::views break; case GameCardStatus_InsertedAndInfoLoaded: { - u64 size = 0; GameCardInfo card_info = {0}; - char strbuf[0x40] = {0}; - - gamecardGetRomCapacity(&size); - utilsGenerateFormattedSizeString(size, strbuf, sizeof(strbuf)); - this->capacity->setValue(std::string(strbuf)); - - gamecardGetTotalSize(&size); - utilsGenerateFormattedSizeString(size, strbuf, sizeof(strbuf)); - this->total_size->setValue(std::string(strbuf)); - - gamecardGetTrimmedSize(&size); - utilsGenerateFormattedSizeString(size, strbuf, sizeof(strbuf)); - this->trimmed_size->setValue(std::string(strbuf)); - gamecardGetDecryptedCardInfoArea(&card_info); - snprintf(strbuf, sizeof(strbuf), "%u.%u.%u-%u.%u (v%u)", card_info.upp_version.major, card_info.upp_version.minor, card_info.upp_version.micro, \ - card_info.upp_version.major_relstep, card_info.upp_version.minor_relstep, card_info.upp_version.value); - this->update_version->setValue(std::string(strbuf)); + this->capacity->setValue(this->GetFormattedSizeString(&gamecardGetRomCapacity)); + this->total_size->setValue(this->GetFormattedSizeString(&gamecardGetTotalSize)); + this->trimmed_size->setValue(this->GetFormattedSizeString(&gamecardGetTrimmedSize)); - snprintf(strbuf, sizeof(strbuf), "%lu (%s)", card_info.fw_version, \ - card_info.fw_version >= GameCardFwVersion_Count ? "generic/unknown"_i18n.c_str() : GameCardFwVersionStrings[card_info.fw_version]); - this->lafw_version->setValue(std::string(strbuf)); + const VersionType1 *upp_version = &(card_info.upp_version); + this->update_version->setValue(fmt::format("{}.{}.{}-{}.{} (v{})", upp_version->major, upp_version->minor, upp_version->micro, upp_version->major_relstep, \ + upp_version->minor_relstep, upp_version->value)); - snprintf(strbuf, sizeof(strbuf), "%u.%u.%u-%u (v%u)", card_info.fw_mode.major, card_info.fw_mode.minor, card_info.fw_mode.micro, card_info.fw_mode.relstep, card_info.fw_mode.value); - this->sdk_version->setValue(std::string(strbuf)); + u64 fw_version = card_info.fw_version; + this->lafw_version->setValue(fmt::format("{} ({})", fw_version, fw_version >= GameCardFwVersion_Count ? "generic/unknown"_i18n : GameCardFwVersionStrings[fw_version])); - snprintf(strbuf, sizeof(strbuf), "%s (%u)", \ - card_info.compatibility_type >= GameCardCompatibilityType_Count ? "generic/unknown"_i18n.c_str() : GameCardCompatibilityTypeStrings[card_info.compatibility_type], \ - card_info.compatibility_type); - this->compatibility_type->setValue(std::string(strbuf)); + const VersionType2 *fw_mode = &(card_info.fw_mode); + this->sdk_version->setValue(fmt::format("{}.{}.{}-{} (v{})", fw_mode->major, fw_mode->minor, fw_mode->micro, fw_mode->relstep, fw_mode->value)); + + u8 compatibility_type = card_info.compatibility_type; + this->compatibility_type->setValue(fmt::format("{} ({})", \ + compatibility_type >= GameCardCompatibilityType_Count ? "generic/unknown"_i18n : GameCardCompatibilityTypeStrings[compatibility_type], \ + compatibility_type)); this->changeLayerWrapper(this->list); @@ -214,4 +202,15 @@ namespace nxdt::views this->invalidate(true); this->view_index = index; } + + std::string GameCardTab::GetFormattedSizeString(GameCardSizeFunc func) + { + u64 size = 0; + char strbuf[0x40] = {0}; + + func(&size); + utilsGenerateFormattedSizeString(size, strbuf, sizeof(strbuf)); + + return std::string(strbuf); + } }